static int hkdf_expand_label(uint8_t *out, const EVP_MD *digest, const uint8_t *secret, size_t secret_len, const uint8_t *label, size_t label_len, const uint8_t *hash, size_t hash_len, size_t len) { static const char kTLS13LabelVersion[] = "TLS 1.3, "; CBB cbb, child; uint8_t *hkdf_label; size_t hkdf_label_len; if (!CBB_init(&cbb, 2 + 1 + strlen(kTLS13LabelVersion) + label_len + 1 + hash_len) || !CBB_add_u16(&cbb, len) || !CBB_add_u8_length_prefixed(&cbb, &child) || !CBB_add_bytes(&child, (const uint8_t *)kTLS13LabelVersion, strlen(kTLS13LabelVersion)) || !CBB_add_bytes(&child, label, label_len) || !CBB_add_u8_length_prefixed(&cbb, &child) || !CBB_add_bytes(&child, hash, hash_len) || !CBB_finish(&cbb, &hkdf_label, &hkdf_label_len)) { CBB_cleanup(&cbb); return 0; } int ret = HKDF_expand(out, len, digest, secret, secret_len, hkdf_label, hkdf_label_len); OPENSSL_free(hkdf_label); return ret; }
int main(void) { uint8_t buf[82], prk[EVP_MAX_MD_SIZE]; size_t i, prk_len; CRYPTO_library_init(); for (i = 0; i < OPENSSL_ARRAY_SIZE(kTests); i++) { const hkdf_test_vector_t *test = &kTests[i]; if (!HKDF_extract(prk, &prk_len, test->md_func(), test->ikm, test->ikm_len, test->salt, test->salt_len)) { fprintf(stderr, "Call to HKDF_extract failed\n"); ERR_print_errors_fp(stderr); return 1; } if (prk_len != test->prk_len || memcmp(prk, test->prk, test->prk_len) != 0) { fprintf(stderr, "%zu: Resulting PRK does not match test vector\n", i); return 1; } if (!HKDF_expand(buf, test->out_len, test->md_func(), prk, prk_len, test->info, test->info_len)) { fprintf(stderr, "Call to HKDF_expand failed\n"); ERR_print_errors_fp(stderr); return 1; } if (memcmp(buf, test->out, test->out_len) != 0) { fprintf(stderr, "%zu: Resulting key material does not match test vector\n", i); return 1; } if (!HKDF(buf, test->out_len, test->md_func(), test->ikm, test->ikm_len, test->salt, test->salt_len, test->info, test->info_len)) { fprintf(stderr, "Call to HKDF failed\n"); ERR_print_errors_fp(stderr); return 1; } if (memcmp(buf, test->out, test->out_len) != 0) { fprintf(stderr, "%zu: Resulting key material does not match test vector\n", i); return 1; } } printf("PASS\n"); ERR_free_strings(); return 0; }