Skip to content

Commit 5acdcf6

Browse files
hpke uses wrong kdf/kem digest
1 parent 7ad9c25 commit 5acdcf6

5 files changed

Lines changed: 128 additions & 29 deletions

File tree

src/ssl_ech.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ int wolfSSL_CTX_GenerateEchConfig(WOLFSSL_CTX* ctx, const char* publicName,
3434
word16 kemId, word16 kdfId, word16 aeadId)
3535
{
3636
int ret = 0;
37-
word16 encLen = DHKEM_X25519_ENC_LEN;
3837
WOLFSSL_EchConfig* newConfig;
38+
word16 encLen = sizeof(newConfig->receiverPubkey);
3939
#ifdef WOLFSSL_SMALL_STACK
4040
Hpke* hpke = NULL;
4141
WC_RNG* rng;

tests/api.c

Lines changed: 65 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14438,6 +14438,9 @@ static byte echCbTestConfigs[512];
1443814438
static word32 echCbTestConfigsLen;
1443914439
static const char* echCbTestPublicName = "ech-public-name.com";
1444014440
static const char* echCbTestPrivateName = "ech-private-name.com";
14441+
static word16 echCbTestKemID = 0;
14442+
static word16 echCbTestKdfID = 0;
14443+
static word16 echCbTestAeadID = 0;
1444114444

1444214445
/* the arg is whether the client has ech enabled or not */
1444314446
static int test_ech_server_sni_callback(WOLFSSL* ssl, int* ad, void* arg)
@@ -14469,7 +14472,8 @@ static int test_ech_server_ctx_ready(WOLFSSL_CTX* ctx)
1446914472
{
1447014473
int ret;
1447114474

14472-
ret = wolfSSL_CTX_GenerateEchConfig(ctx, echCbTestPublicName, 0, 0, 0);
14475+
ret = wolfSSL_CTX_GenerateEchConfig(ctx, echCbTestPublicName,
14476+
echCbTestKemID, echCbTestKdfID, echCbTestAeadID);
1447314477
if (ret != WOLFSSL_SUCCESS)
1447414478
return TEST_FAIL;
1447514479

@@ -14512,6 +14516,65 @@ static int test_ech_client_ssl_ready(WOLFSSL* ssl)
1451214516
return TEST_SUCCESS;
1451314517
}
1451414518

14519+
static int test_wolfSSL_Tls13_ECH_all_algos_ex(void)
14520+
{
14521+
EXPECT_DECLS;
14522+
struct test_ssl_memio_ctx test_ctx;
14523+
14524+
XMEMSET(&test_ctx, 0, sizeof(test_ctx));
14525+
14526+
test_ctx.s_cb.method = wolfTLSv1_3_server_method;
14527+
test_ctx.c_cb.method = wolfTLSv1_3_client_method;
14528+
14529+
test_ctx.s_cb.ctx_ready = test_ech_server_ctx_ready;
14530+
test_ctx.s_cb.ssl_ready = test_ech_server_ssl_ready;
14531+
test_ctx.c_cb.ssl_ready = test_ech_client_ssl_ready;
14532+
14533+
ExpectIntEQ(test_ssl_memio_setup(&test_ctx), TEST_SUCCESS);
14534+
14535+
ExpectIntEQ(test_ssl_memio_do_handshake(&test_ctx, 10, NULL), TEST_SUCCESS);
14536+
ExpectIntEQ(test_ctx.c_ssl->options.echAccepted, 1);
14537+
14538+
test_ssl_memio_cleanup(&test_ctx);
14539+
14540+
return EXPECT_RESULT();
14541+
}
14542+
14543+
static int test_wolfSSL_Tls13_ECH_all_algos(void)
14544+
{
14545+
EXPECT_DECLS;
14546+
int i;
14547+
int j;
14548+
int k;
14549+
static const word16 kems[] = {
14550+
DHKEM_P256_HKDF_SHA256,
14551+
DHKEM_P384_HKDF_SHA384,
14552+
DHKEM_P521_HKDF_SHA512,
14553+
DHKEM_X25519_HKDF_SHA256,
14554+
};
14555+
static const word16 kdfs[] = { HKDF_SHA256, HKDF_SHA384, HKDF_SHA512 };
14556+
static const word16 aeads[] = { HPKE_AES_128_GCM, HPKE_AES_256_GCM };
14557+
14558+
/* test each KEM with default KDF and AEAD */
14559+
for (i = 0; i < (int)(sizeof(kems) / sizeof(*kems)); i++) {
14560+
echCbTestKemID = kems[i];
14561+
for (j = 0; j < (int)(sizeof(kdfs) / sizeof(*kdfs)); j++) {
14562+
echCbTestKdfID = kdfs[j];
14563+
for (k = 0; k < (int)(sizeof(aeads) / sizeof(*aeads)); k++) {
14564+
echCbTestAeadID = aeads[k];
14565+
ExpectIntEQ(test_wolfSSL_Tls13_ECH_all_algos_ex(),
14566+
WOLFSSL_SUCCESS);
14567+
}
14568+
}
14569+
}
14570+
14571+
echCbTestKemID = 0;
14572+
echCbTestKdfID = 0;
14573+
echCbTestAeadID = 0;
14574+
14575+
return EXPECT_RESULT();
14576+
}
14577+
1451514578
/* Test ECH when no private SNI is set */
1451614579
static int test_wolfSSL_Tls13_ECH_no_private_name(void)
1451714580
{
@@ -34426,6 +34489,7 @@ TEST_CASE testCases[] = {
3442634489
TEST_DECL(test_wolfSSL_SubTls13_ECH),
3442734490
#endif
3442834491
#if defined(HAVE_SSL_MEMIO_TESTS_DEPENDENCIES)
34492+
TEST_DECL(test_wolfSSL_Tls13_ECH_all_algos),
3442934493
TEST_DECL(test_wolfSSL_Tls13_ECH_no_private_name),
3443034494
TEST_DECL(test_wolfSSL_Tls13_ECH_bad_configs),
3443134495
TEST_DECL(test_wolfSSL_Tls13_ECH_new_config),

wolfcrypt/src/hpke.c

Lines changed: 31 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -170,7 +170,7 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
170170
case DHKEM_P256_HKDF_SHA256:
171171
hpke->curve_id = ECC_SECP256R1;
172172
hpke->Nsecret = WC_SHA256_DIGEST_SIZE;
173-
hpke->Nh = WC_SHA256_DIGEST_SIZE;
173+
hpke->kem_digest = WC_SHA256;
174174
hpke->Ndh = (word32)wc_ecc_get_curve_size_from_id(hpke->curve_id);
175175
hpke->Npk = 1 + hpke->Ndh * 2;
176176
break;
@@ -180,7 +180,7 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
180180
case DHKEM_P384_HKDF_SHA384:
181181
hpke->curve_id = ECC_SECP384R1;
182182
hpke->Nsecret = WC_SHA384_DIGEST_SIZE;
183-
hpke->Nh = WC_SHA384_DIGEST_SIZE;
183+
hpke->kem_digest = WC_SHA384;
184184
hpke->Ndh = (word32)wc_ecc_get_curve_size_from_id(hpke->curve_id);
185185
hpke->Npk = 1 + hpke->Ndh * 2;
186186
break;
@@ -190,7 +190,7 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
190190
case DHKEM_P521_HKDF_SHA512:
191191
hpke->curve_id = ECC_SECP521R1;
192192
hpke->Nsecret = WC_SHA512_DIGEST_SIZE;
193-
hpke->Nh = WC_SHA512_DIGEST_SIZE;
193+
hpke->kem_digest = WC_SHA512;
194194
hpke->Ndh = (word32)wc_ecc_get_curve_size_from_id(hpke->curve_id);
195195
hpke->Npk = 1 + hpke->Ndh * 2;
196196
break;
@@ -201,7 +201,7 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
201201
(defined(WOLFSSL_SHA224) || !defined(NO_SHA256))
202202
case DHKEM_X25519_HKDF_SHA256:
203203
hpke->Nsecret = WC_SHA256_DIGEST_SIZE;
204-
hpke->Nh = WC_SHA256_DIGEST_SIZE;
204+
hpke->kem_digest = WC_SHA256;
205205
hpke->Ndh = CURVE25519_KEYSIZE;
206206
hpke->Npk = CURVE25519_PUB_KEY_SIZE;
207207
break;
@@ -211,7 +211,7 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
211211
(defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))
212212
case DHKEM_X448_HKDF_SHA512:
213213
hpke->Nsecret = WC_SHA512_DIGEST_SIZE;
214-
hpke->Nh = WC_SHA512_DIGEST_SIZE;
214+
hpke->kem_digest = WC_SHA512;
215215
/* size of x448 shared secret */
216216
hpke->Ndh = 64;
217217
hpke->Npk = CURVE448_PUB_KEY_SIZE;
@@ -228,14 +228,17 @@ int wc_HpkeInit(Hpke* hpke, int kem, int kdf, int aead, void* heap)
228228
if (ret == 0) {
229229
switch (kdf) {
230230
case HKDF_SHA256:
231+
hpke->Nh = WC_SHA256_DIGEST_SIZE;
231232
hpke->kdf_digest = WC_SHA256;
232233
break;
233234

234235
case HKDF_SHA384:
236+
hpke->Nh = WC_SHA384_DIGEST_SIZE;
235237
hpke->kdf_digest = WC_SHA384;
236238
break;
237239

238240
case HKDF_SHA512:
241+
hpke->Nh = WC_SHA512_DIGEST_SIZE;
239242
hpke->kdf_digest = WC_SHA512;
240243
break;
241244

@@ -459,7 +462,7 @@ void wc_HpkeFreeKey(Hpke* hpke, word16 kem, void* keypair, void* heap)
459462
}
460463

461464
static int wc_HpkeLabeledExtract(Hpke* hpke, byte* suite_id,
462-
word32 suite_id_len, byte* salt, word32 salt_len, byte* label,
465+
word32 suite_id_len, int digest, byte* salt, word32 salt_len, byte* label,
463466
word32 label_len, byte* ikm, word32 ikm_len, byte* out)
464467
{
465468
int ret;
@@ -516,7 +519,7 @@ static int wc_HpkeLabeledExtract(Hpke* hpke, byte* suite_id,
516519

517520
/* call extract */
518521
PRIVATE_KEY_UNLOCK();
519-
ret = wc_HKDF_Extract(hpke->kdf_digest, salt, salt_len, labeled_ikm,
522+
ret = wc_HKDF_Extract(digest, salt, salt_len, labeled_ikm,
520523
(word32)(size_t)(labeled_ikm_p - labeled_ikm), out);
521524
PRIVATE_KEY_LOCK();
522525

@@ -528,8 +531,8 @@ static int wc_HpkeLabeledExtract(Hpke* hpke, byte* suite_id,
528531
/* do hkdf expand with the format specified in the hpke rfc, return 0 or
529532
* error */
530533
static int wc_HpkeLabeledExpand(Hpke* hpke, byte* suite_id, word32 suite_id_len,
531-
byte* prk, word32 prk_len, byte* label, word32 label_len, byte* info,
532-
word32 infoSz, word32 L, byte* out)
534+
int digest, byte* prk, word32 prk_len, byte* label, word32 label_len,
535+
byte* info, word32 infoSz, word32 L, byte* out)
533536
{
534537
int ret;
535538
byte* labeled_info_p;
@@ -592,10 +595,8 @@ static int wc_HpkeLabeledExpand(Hpke* hpke, byte* suite_id, word32 suite_id_len,
592595

593596
/* call expand */
594597
PRIVATE_KEY_UNLOCK();
595-
ret = wc_HKDF_Expand(hpke->kdf_digest,
596-
prk, prk_len,
597-
labeled_info, (word32)(size_t)(labeled_info_p - labeled_info),
598-
out, L);
598+
ret = wc_HKDF_Expand(digest, prk, prk_len, labeled_info,
599+
(word32)(size_t)(labeled_info_p - labeled_info), out, L);
599600
PRIVATE_KEY_LOCK();
600601
}
601602

@@ -643,15 +644,16 @@ static int wc_HpkeExtractAndExpand( Hpke* hpke, byte* dh, word32 dh_len,
643644

644645
/* extract */
645646
ret = wc_HpkeLabeledExtract(hpke, hpke->kem_suite_id,
646-
sizeof( hpke->kem_suite_id ), NULL, 0, (byte*)EAE_PRK_LABEL_STR,
647-
EAE_PRK_LABEL_STR_LEN, dh, dh_len, eae_prk);
647+
sizeof( hpke->kem_suite_id ), hpke->kem_digest, NULL, 0,
648+
(byte*)EAE_PRK_LABEL_STR, EAE_PRK_LABEL_STR_LEN, dh, dh_len, eae_prk);
648649

649650
/* expand */
650651
if ( ret == 0 ) {
651652
ret = wc_HpkeLabeledExpand(hpke, hpke->kem_suite_id,
652-
sizeof( hpke->kem_suite_id ), eae_prk, hpke->Nh,
653-
(byte*)SHARED_SECRET_LABEL_STR, SHARED_SECRET_LABEL_STR_LEN,
654-
kemContext, kem_context_length, hpke->Nsecret, sharedSecret);
653+
sizeof( hpke->kem_suite_id ), hpke->kem_digest, eae_prk,
654+
hpke->Nsecret, (byte*)SHARED_SECRET_LABEL_STR,
655+
SHARED_SECRET_LABEL_STR_LEN, kemContext, kem_context_length,
656+
hpke->Nsecret, sharedSecret);
655657
}
656658

657659
ForceZero(eae_prk, WC_MAX_DIGEST_SIZE);
@@ -701,35 +703,37 @@ static int wc_HpkeKeyScheduleBase(Hpke* hpke, HpkeBaseContext* context,
701703

702704
/* extract psk_id, which for base is null */
703705
ret = wc_HpkeLabeledExtract(hpke, hpke->hpke_suite_id,
704-
sizeof( hpke->hpke_suite_id ), NULL, 0, (byte*)PSK_ID_HASH_LABEL_STR,
705-
PSK_ID_HASH_LABEL_STR_LEN, NULL, 0, key_schedule_context + 1);
706+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, NULL, 0,
707+
(byte*)PSK_ID_HASH_LABEL_STR, PSK_ID_HASH_LABEL_STR_LEN, NULL, 0,
708+
key_schedule_context + 1);
706709

707710
/* extract info */
708711
if (ret == 0) {
709712
ret = wc_HpkeLabeledExtract(hpke, hpke->hpke_suite_id,
710-
sizeof( hpke->hpke_suite_id ), NULL, 0, (byte*)INFO_HASH_LABEL_STR,
711-
INFO_HASH_LABEL_STR_LEN, info, infoSz,
713+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, NULL, 0,
714+
(byte*)INFO_HASH_LABEL_STR, INFO_HASH_LABEL_STR_LEN, info, infoSz,
712715
key_schedule_context + 1 + hpke->Nh);
713716
}
714717

715718
/* extract secret */
716719
if (ret == 0) {
717720
ret = wc_HpkeLabeledExtract(hpke, hpke->hpke_suite_id,
718-
sizeof( hpke->hpke_suite_id ), sharedSecret, hpke->Nsecret,
719-
(byte*)SECRET_LABEL_STR, SECRET_LABEL_STR_LEN, NULL, 0, secret);
721+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, sharedSecret,
722+
hpke->Nsecret, (byte*)SECRET_LABEL_STR, SECRET_LABEL_STR_LEN,
723+
NULL, 0, secret);
720724
}
721725

722726
/* expand key */
723727
if (ret == 0)
724728
ret = wc_HpkeLabeledExpand(hpke, hpke->hpke_suite_id,
725-
sizeof( hpke->hpke_suite_id ), secret, hpke->Nh,
729+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, secret, hpke->Nh,
726730
(byte*)KEY_LABEL_STR, KEY_LABEL_STR_LEN, key_schedule_context,
727731
1 + 2 * hpke->Nh, hpke->Nk, context->key);
728732

729733
/* expand nonce */
730734
if (ret == 0) {
731735
ret = wc_HpkeLabeledExpand(hpke, hpke->hpke_suite_id,
732-
sizeof( hpke->hpke_suite_id ), secret, hpke->Nh,
736+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, secret, hpke->Nh,
733737
(byte*)BASE_NONCE_LABEL_STR, BASE_NONCE_LABEL_STR_LEN,
734738
key_schedule_context, 1 + 2 * hpke->Nh, hpke->Nn,
735739
context->base_nonce);
@@ -738,7 +742,7 @@ static int wc_HpkeKeyScheduleBase(Hpke* hpke, HpkeBaseContext* context,
738742
/* expand exporter_secret */
739743
if (ret == 0) {
740744
ret = wc_HpkeLabeledExpand(hpke, hpke->hpke_suite_id,
741-
sizeof( hpke->hpke_suite_id ), secret, hpke->Nh,
745+
sizeof( hpke->hpke_suite_id ), hpke->kdf_digest, secret, hpke->Nh,
742746
(byte*)EXP_LABEL_STR, EXP_LABEL_STR_LEN, key_schedule_context,
743747
1 + 2 * hpke->Nh, hpke->Nh, context->exporter_secret);
744748
}

wolfcrypt/test/test.c

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32102,9 +32102,24 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
3210232102
ret = hpke_test_multi(hpke);
3210332103
if (ret != 0)
3210432104
return ret;
32105+
#endif
3210532106

32107+
#if (defined(WOLFSSL_SHA224) || !defined(NO_SHA256)) && \
32108+
(defined(WOLFSSL_SHA384) || defined(WOLFSSL_SHA512))
32109+
/* p256 with sha512 kdf */
32110+
ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA512,
32111+
HPKE_AES_128_GCM, NULL);
32112+
if (ret != 0)
32113+
return WC_TEST_RET_ENC_EC(ret);
32114+
ret = hpke_test_single(hpke);
32115+
if (ret != 0)
32116+
return ret;
32117+
ret = hpke_test_multi(hpke);
32118+
if (ret != 0)
32119+
return ret;
3210632120
#endif
3210732121

32122+
3210832123
#if defined(WOLFSSL_SHA384) && \
3210932124
(defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES))
3211032125
/* p384 */
@@ -32134,6 +32149,21 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void)
3213432149
if (ret != 0)
3213532150
return ret;
3213632151
#endif
32152+
32153+
#if defined(WOLFSSL_SHA384) && defined(WOLFSSL_SHA512) && \
32154+
(defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES))
32155+
/* p521 with sha384 kdf */
32156+
ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA384,
32157+
HPKE_AES_128_GCM, NULL);
32158+
if (ret != 0)
32159+
return WC_TEST_RET_ENC_EC(ret);
32160+
ret = hpke_test_single(hpke);
32161+
if (ret != 0)
32162+
return ret;
32163+
ret = hpke_test_multi(hpke);
32164+
if (ret != 0)
32165+
return ret;
32166+
#endif
3213732167
#endif
3213832168

3213932169
#if defined(HAVE_CURVE25519)

wolfssl/wolfcrypt/hpke.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ typedef struct {
9999
word32 Npk;
100100
word32 Nsecret;
101101
int kdf_digest;
102+
int kem_digest;
102103
int curve_id;
103104
byte kem_suite_id[KEM_SUITE_ID_LEN];
104105
byte hpke_suite_id[HPKE_SUITE_ID_LEN];

0 commit comments

Comments
 (0)