void dtls_hmac_init(dtls_hmac_context_t *ctx, const unsigned char *key, size_t klen) { int i; assert(ctx); memset(ctx, 0, sizeof(dtls_hmac_context_t)); if (klen > DTLS_HMAC_BLOCKSIZE) { dtls_hash_init(&ctx->data); dtls_hash_update(&ctx->data, key, klen); dtls_hash_finalize(ctx->pad, &ctx->data); } else memcpy(ctx->pad, key, klen); /* create ipad: */ for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) ctx->pad[i] ^= 0x36; dtls_hash_init(&ctx->data); dtls_hmac_update(ctx, ctx->pad, DTLS_HMAC_BLOCKSIZE); /* create opad by xor-ing pad[i] with 0x36 ^ 0x5C: */ for (i=0; i < DTLS_HMAC_BLOCKSIZE; ++i) ctx->pad[i] ^= 0x6A; }
int main(int argc, char **argv) { static unsigned char buf[DTLS_HMAC_DIGEST_SIZE]; size_t len, i; dtls_hmac_context_t *ctx; if (argc < 3) { fprintf(stderr, "usage: %s key text", argv[0]); return -1; } dtls_hmac_storage_init(); ctx = dtls_hmac_new(argv[1], strlen(argv[1])); assert(ctx); dtls_hmac_update(ctx, argv[2], strlen(argv[2])); len = dtls_hmac_finalize(ctx, buf); for(i = 0; i < len; i++) printf("%02x", buf[i]); printf("\n"); dtls_hmac_free(ctx); return 0; }
void dtls_mac(dtls_hmac_context_t *hmac_ctx, const unsigned char *record, const unsigned char *packet, size_t length, unsigned char *buf) { uint16 L; dtls_int_to_uint16(L, length); assert(hmac_ctx); dtls_hmac_update(hmac_ctx, record +3, sizeof(uint16) + sizeof(uint48)); dtls_hmac_update(hmac_ctx, record, sizeof(uint8) + sizeof(uint16)); dtls_hmac_update(hmac_ctx, L, sizeof(uint16)); dtls_hmac_update(hmac_ctx, packet, length); dtls_hmac_finalize(hmac_ctx, buf); }
size_t dtls_p_hash(dtls_hashfunc_t h, const unsigned char *key, size_t keylen, const unsigned char *label, size_t labellen, const unsigned char *random1, size_t random1len, const unsigned char *random2, size_t random2len, unsigned char *buf, size_t buflen) { dtls_hmac_context_t *hmac_a, *hmac_p; unsigned char A[DTLS_HMAC_DIGEST_SIZE]; unsigned char tmp[DTLS_HMAC_DIGEST_SIZE]; size_t dlen; /* digest length */ size_t len = 0; /* result length */ hmac_a = dtls_hmac_new(key, keylen); if (!hmac_a) return 0; /* calculate A(1) from A(0) == seed */ HMAC_UPDATE_SEED(hmac_a, label, labellen); HMAC_UPDATE_SEED(hmac_a, random1, random1len); HMAC_UPDATE_SEED(hmac_a, random2, random2len); dlen = dtls_hmac_finalize(hmac_a, A); hmac_p = dtls_hmac_new(key, keylen); if (!hmac_p) goto error; while (len + dlen < buflen) { /* FIXME: rewrite loop to avoid superflous call to dtls_hmac_init() */ dtls_hmac_init(hmac_p, key, keylen); dtls_hmac_update(hmac_p, A, dlen); HMAC_UPDATE_SEED(hmac_p, label, labellen); HMAC_UPDATE_SEED(hmac_p, random1, random1len); HMAC_UPDATE_SEED(hmac_p, random2, random2len); len += dtls_hmac_finalize(hmac_p, tmp); memcpy(buf, tmp, dlen); buf += dlen; /* calculate A(i+1) */ dtls_hmac_init(hmac_a, key, keylen); dtls_hmac_update(hmac_a, A, dlen); dtls_hmac_finalize(hmac_a, A); } dtls_hmac_init(hmac_p, key, keylen); dtls_hmac_update(hmac_p, A, dlen); HMAC_UPDATE_SEED(hmac_p, label, labellen); HMAC_UPDATE_SEED(hmac_p, random1, random1len); HMAC_UPDATE_SEED(hmac_p, random2, random2len); dtls_hmac_finalize(hmac_p, tmp); memcpy(buf, tmp, buflen - len); error: dtls_hmac_free(hmac_a); dtls_hmac_free(hmac_p); return buflen; }