dtls_hmac_context_t * dtls_hmac_new(const unsigned char *key, size_t klen) { dtls_hmac_context_t *ctx; ctx = dtls_hmac_context_new(); if (ctx) dtls_hmac_init(ctx, key, klen); return ctx; }
int pcap_verify(dtls_security_parameters_t *sec, int is_client, const unsigned char *record, size_t record_length, const unsigned char *cleartext, size_t cleartext_length) { unsigned char mac[DTLS_HMAC_MAX]; dtls_hmac_context_t hmac_ctx; int ok; if (cleartext_length < dtls_kb_digest_size(sec)) return 0; dtls_hmac_init(&hmac_ctx, is_client ? dtls_kb_client_mac_secret(sec) : dtls_kb_server_mac_secret(sec), dtls_kb_mac_secret_size(sec)); cleartext_length -= dtls_kb_digest_size(sec); /* calculate MAC even if padding is wrong */ dtls_mac(&hmac_ctx, record, /* the pre-filled record header */ cleartext, cleartext_length, mac); ok = memcmp(mac, cleartext + cleartext_length, dtls_kb_digest_size(sec)) == 0; #ifndef NDEBUG printf("MAC (%s): ", ok ? "valid" : "invalid"); dump(mac, dtls_kb_digest_size(sec)); printf("\n"); #endif return ok; }
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; }