hmac.c (1793B)
1 #include "hmac.h" 2 3 #include <assert.h> 4 #include <string.h> 5 6 void 7 hmac_gen_iv_block(struct hmac_ctx *ctx, 8 struct hmac_hash const *hash, void *restrict hash_ctx, 9 void const *restrict key, size_t key_len) 10 { 11 memset(ctx, 0, sizeof *ctx); 12 13 ctx->hash = hash; 14 ctx->hash_ctx = hash_ctx; 15 16 if (key_len <= HMAC_BLOCK_SIZE) { // can use the key directly 17 assert(key_len <= HMAC_BLOCK_SIZE); 18 memcpy(ctx->iv, key, key_len); 19 } else { // must hash the key first to generate the iv block 20 assert(hash->digest_size <= HMAC_BLOCK_SIZE); 21 hash->init(hash_ctx); 22 hash->push(hash_ctx, key, key_len); 23 hash->dgst(hash_ctx, ctx->iv); 24 } 25 26 for (size_t i = 0; i < HMAC_BLOCK_SIZE; i++) { 27 ctx->ipad[i] = ctx->iv[i] ^ HMAC_IPAD_BYTE; 28 ctx->opad[i] = ctx->iv[i] ^ HMAC_OPAD_BYTE; 29 } 30 } 31 32 void 33 hmac_init(struct hmac_ctx *ctx) 34 { 35 // prepare ipad material 36 ctx->hash->init(ctx->hash_ctx); 37 ctx->hash->push(ctx->hash_ctx, ctx->ipad, sizeof ctx->ipad); 38 } 39 40 void 41 hmac_push(struct hmac_ctx *ctx, void const *buf, size_t buf_len) 42 { 43 // accumulate ipad material 44 ctx->hash->push(ctx->hash_ctx, buf, buf_len); 45 } 46 47 void 48 hmac_dgst(struct hmac_ctx *ctx, void *digest) 49 { 50 // close ipad material 51 ctx->hash->dgst(ctx->hash_ctx, digest); 52 53 // final digest against opad 54 ctx->hash->init(ctx->hash_ctx); 55 ctx->hash->push(ctx->hash_ctx, ctx->opad, sizeof ctx->opad); 56 ctx->hash->push(ctx->hash_ctx, digest, ctx->hash->digest_size); 57 ctx->hash->dgst(ctx->hash_ctx, digest); 58 } 59 60 void 61 hmac(struct hmac_hash const *hash, void *restrict hash_ctx, 62 void const *restrict key, size_t key_len, 63 void const *restrict buf, size_t buf_len, 64 void *restrict digest) 65 { 66 struct hmac_ctx ctx; 67 68 hmac_gen_iv_block(&ctx, hash, hash_ctx, key, key_len); 69 70 hmac_init(&ctx); 71 hmac_push(&ctx, buf, buf_len); 72 hmac_dgst(&ctx, digest); 73 }