Commit 11a3def3 authored by Nils Goroll's avatar Nils Goroll
parent 0a053a68
......@@ -55,11 +55,13 @@
#define INIT_FINI(ctx) (((ctx)->method & (VCL_MET_INIT | VCL_MET_FINI)) != 0)
#define BLOB_BLOBDIGEST_DIGEST_TYPE 0x9235d52f
struct digest_task {
unsigned magic;
#define VMOD_BLOBDIGEST_DIGEST_TASK_MAGIC 0x646937a8
hash_ctx ctx;
struct vmod_priv *result;
VCL_BLOB result;
};
struct vmod_blobdigest_digest {
......@@ -67,7 +69,8 @@ struct vmod_blobdigest_digest {
#define VMOD_BLOBDIGEST_DIGEST_MAGIC 0xaccb2e25
hash_ctx ctx;
char *vcl_name;
struct vmod_priv *result;
VCL_BLOB result;
void *digest; // == result->blob
enum algorithm hash;
enum scope scope;
};
......@@ -248,35 +251,61 @@ digest(const enum algorithm hash, hash_ctx *restrict const hctx,
VCL_BLOB restrict const b, uint8_t *restrict digest)
{
init(hash, hctx);
update(hash, hctx, b->priv, b->len);
update(hash, hctx, b->blob, b->len);
final(hash, hctx, digest);
}
static struct vmod_priv *
ws_alloc_digest(VRT_CTX, const size_t digestsz,
static VCL_BLOB
ws_alloc_digest(VRT_CTX, const size_t digestsz, void **digestp,
const char * const restrict context,
const char * const restrict caller)
{
struct vmod_priv *b;
struct vrt_blob *b;
uintptr_t snap;
CHECK_OBJ_NOTNULL(ctx->ws, WS_MAGIC);
AN(digestp);
snap = WS_Snapshot(ctx->ws);
if ((b = WS_Alloc(ctx->ws, sizeof(struct vmod_priv))) == NULL) {
if ((b = WS_Alloc(ctx->ws, sizeof *b)) == NULL) {
VERRNOMEM(ctx, "allocating blob in %s.%s()", context, caller);
return NULL;
}
if ((b->priv = WS_Alloc(ctx->ws, digestsz)) == NULL) {
if ((b->blob = *digestp = WS_Alloc(ctx->ws, digestsz)) == NULL) {
WS_Reset(ctx->ws, snap);
VERRNOMEM(ctx, "allocating hash result in %s.%s()", context,
caller);
return NULL;
}
b->type = BLOB_BLOBDIGEST_DIGEST_TYPE;
b->len = digestsz;
b->free = NULL;
return b;
}
static VCL_BLOB
heap_alloc_digest(VRT_CTX, const size_t digestsz, void **digestp,
const char * const restrict context,
const char * const restrict caller)
{
unsigned char *spc;
struct vrt_blob *b;
AN(digestp);
spc = malloc(PRNDUP(digestsz) + sizeof *b);
if (spc == NULL) {
VERRNOMEM(ctx, "malloc in %s.%s()", context, caller);
return (NULL);
}
b = (void *)(spc + PRNDUP(digestsz));
b->blob = *digestp = spc;
b->type = BLOB_BLOBDIGEST_DIGEST_TYPE;
b->len = digestsz;
return (b);
}
/* Objects */
static inline void
......@@ -369,8 +398,8 @@ vmod_digest__init(VRT_CTX, struct vmod_blobdigest_digest **digestp,
AN(digest->vcl_name);
AZ(digest->result);
init(hash, &digest->ctx);
if (initb != NULL && initb->len > 0 && initb->priv != NULL)
update(hash, &digest->ctx, initb->priv, initb->len);
if (initb != NULL && initb->len > 0 && initb->blob != NULL)
update(hash, &digest->ctx, initb->blob, initb->len);
}
VCL_VOID
......@@ -384,11 +413,9 @@ vmod_digest__fini(struct vmod_blobdigest_digest **digestp)
*digestp = NULL;
CHECK_OBJ_NOTNULL(digest, VMOD_BLOBDIGEST_DIGEST_MAGIC);
if (digest->result != NULL) {
AN(digest->result->priv);
free(digest->result->priv);
free(digest->result);
}
/* single allocation for digest + blob */
if (digest->digest != NULL)
free(digest->digest);
if (digest->vcl_name != NULL)
free(digest->vcl_name);
FREE_OBJ(digest);
......@@ -417,8 +444,8 @@ vmod_digest_update(VRT_CTX, struct vmod_blobdigest_digest *h, VCL_BLOB b)
}
if (INIT_FINI(ctx)) {
if (b->len > 0 && b->priv != NULL)
update(h->hash, &h->ctx, b->priv, b->len);
if (b->len > 0 && b->blob != NULL)
update(h->hash, &h->ctx, b->blob, b->len);
return 1;
}
......@@ -426,16 +453,18 @@ vmod_digest_update(VRT_CTX, struct vmod_blobdigest_digest *h, VCL_BLOB b)
VERR(ctx, "already finalized in %s.update()", h->vcl_name);
return 0;
}
if (b->len > 0 && b->priv != NULL)
update(h->hash, &task->ctx, b->priv, b->len);
if (b->len > 0 && b->blob != NULL)
update(h->hash, &task->ctx, b->blob, b->len);
return 1;
}
VCL_BLOB
vmod_digest_final(VRT_CTX, struct vmod_blobdigest_digest *h)
{
struct vmod_priv *b;
VCL_BLOB b;
void *r = NULL;
struct digest_task *task;
hash_ctx *hctx;
enum algorithm hash;
size_t digestsz;
......@@ -443,36 +472,32 @@ vmod_digest_final(VRT_CTX, struct vmod_blobdigest_digest *h)
CHECK_OBJ_NOTNULL(h, VMOD_BLOBDIGEST_DIGEST_MAGIC);
if (h->result != NULL)
return h->result;
return (h->result);
hash = h->hash;
digestsz = hashspec[hash].digestsz;
if (INIT_FINI(ctx)) {
b = malloc(sizeof(struct vmod_priv));
AN(b);
b->priv = malloc(digestsz);
AN(b->priv);
b->len = digestsz;
b->free = free;
final(hash, &h->ctx, b->priv);
b = heap_alloc_digest(ctx, digestsz, &r, h->vcl_name, "final");
h->result = b;
return b;
hctx = &h->ctx;
} else {
task = get_scope(ctx, h, "final");
if (task == NULL)
return (NULL);
if (task->result != NULL)
return (task->result);
b = ws_alloc_digest(ctx, digestsz, &r, h->vcl_name, "final");
task->result = b;
hctx = &task->ctx;
}
task = get_scope(ctx, h, "final");
if (task == NULL)
return NULL;
if (task->result != NULL)
return task->result;
b = ws_alloc_digest(ctx, digestsz, h->vcl_name, "final");
if (b == NULL)
return NULL;
final(hash, &task->ctx, b->priv);
task->result = b;
return b;
return (NULL);
AN(r);
final(hash, hctx, r);
return (b);
}
static void
......@@ -485,7 +510,7 @@ hmac_init(enum algorithm hash, VCL_BLOB restrict key,
memset(k, 0, blocksz);
if (key->len <= blocksz)
memcpy(k, key->priv, key->len);
memcpy(k, key->blob, key->len);
else {
hash_ctx hctx[1];
......@@ -509,23 +534,26 @@ hmac_final(VRT_CTX, enum algorithm hash, VCL_BLOB restrict msg,
const char * const restrict context,
const char * const restrict caller)
{
struct vmod_priv *b;
void *digest = NULL;
VCL_BLOB b;
size_t digestsz = hashspec[hash].digestsz;
b = ws_alloc_digest(ctx, digestsz, context, caller);
b = ws_alloc_digest(ctx, digestsz, &digest, context, caller);
if (b == NULL)
return NULL;
AN(digest);
uint8_t inner_digest[digestsz];
/* Hash the message with the inner key */
update(hash, inner_ctx, msg->priv, msg->len);
update(hash, inner_ctx, msg->blob, msg->len);
final(hash, inner_ctx, inner_digest);
/* Hash the result with the outer key */
update(hash, outer_ctx, inner_digest, digestsz);
final(hash, outer_ctx, b->priv);
return b;
final(hash, outer_ctx, digest);
return (b);
}
VCL_VOID
......@@ -537,7 +565,7 @@ vmod_hmac__init(VRT_CTX, struct vmod_blobdigest_hmac **hmacp,
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
AN(vcl_name);
if (key == NULL || key->priv == NULL) {
if (key == NULL || key->blob == NULL) {
VERR(ctx, "key is NULL in %s constructor", vcl_name);
return;
}
......@@ -559,7 +587,7 @@ vmod_hmac_hmac(VRT_CTX, struct vmod_blobdigest_hmac *h, VCL_BLOB msg)
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
CHECK_OBJ_NOTNULL(h, VMOD_BLOBDIGEST_HMAC_MAGIC);
if (msg == NULL || msg->priv == NULL) {
if (msg == NULL || msg->blob == NULL) {
VERR(ctx, "msg is NULL in %s.hmac()", h->vcl_name);
return NULL;
}
......@@ -613,18 +641,24 @@ VCL_BLOB
vmod_hash(VRT_CTX, VCL_ENUM hashs, VCL_BLOB msg)
{
enum algorithm hash = parse_algorithm(hashs);
struct vmod_priv *b;
void *r = NULL;
VCL_BLOB b;
hash_ctx hctx[1];
CHECK_OBJ_NOTNULL(ctx, VRT_CTX_MAGIC);
if (msg == NULL)
return NULL;
b = ws_alloc_digest(ctx, hashspec[hash].digestsz, "blobdigest", "hash");
b = ws_alloc_digest(ctx, hashspec[hash].digestsz, &r,
"blobdigest", "hash");
if (b == NULL)
return NULL;
digest(hash, hctx, msg, b->priv);
return b;
AN(r);
digest(hash, hctx, msg, r);
return (b);
}
VCL_BLOB
......@@ -633,11 +667,11 @@ vmod_hmacf(VRT_CTX, VCL_ENUM hashs, VCL_BLOB key, VCL_BLOB msg)
enum algorithm hash = parse_algorithm(hashs);
hash_ctx inner_ctx, outer_ctx;
if (key == NULL || key->priv == NULL) {
if (key == NULL || key->blob == NULL) {
ERR(ctx, "key is NULL in blobdigest.hmacf()");
return NULL;
}
if (msg == NULL || msg->priv == NULL) {
if (msg == NULL || msg->blob == NULL) {
ERR(ctx, "msg is NULL in blobdigest.hmacf()");
return NULL;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment