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