diff --git a/src/ssl_ech.c b/src/ssl_ech.c index eb9b9a6a5a..1f864bc15b 100644 --- a/src/ssl_ech.c +++ b/src/ssl_ech.c @@ -547,8 +547,9 @@ int SetEchConfigsEx(WOLFSSL_EchConfig** outputConfigs, void* heap, ato16(echConfig, &hpkePubkeyLen); echConfig += 2; - /* hpke public_key */ - if (hpkePubkeyLen > HPKE_Npk_MAX || hpkePubkeyLen == 0) { + /* hpke public_key + * KEM support will be checked along with the ciphersuites */ + if (hpkePubkeyLen != wc_HpkeKemGetEncLen(workingConfig->kemId)) { ret = BUFFER_E; break; } diff --git a/src/tls.c b/src/tls.c index 09e6c92174..4096dc6bfc 100644 --- a/src/tls.c +++ b/src/tls.c @@ -13696,7 +13696,7 @@ static int TLSX_ECH_Write(WOLFSSL_ECH* ech, byte msgType, byte* writeBuf, writeBuf_p += ech->encLen; } /* innerClientHelloLen */ - c16toa(ech->innerClientHelloLen, writeBuf_p); + c16toa((word16)ech->innerClientHelloLen, writeBuf_p); writeBuf_p += 2; /* set payload offset for when we finalize */ ech->outerClientPayload = writeBuf_p; @@ -14155,7 +14155,7 @@ static int TLSX_ECH_ExpandOuterExtensions(WOLFSSL* ssl, WOLFSSL_ECH* ech, if (ret == 0) { XFREE(ech->innerClientHello, heap, DYNAMIC_TYPE_TMP_BUFFER); ech->innerClientHello = newInnerCh; - ech->innerClientHelloLen = (word16)newInnerChLen; + ech->innerClientHelloLen = newInnerChLen; newInnerCh = NULL; } @@ -14269,6 +14269,7 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, word32 offset = 0; word16 len; word16 tmpVal16; + word16 lenCh; WOLFSSL_MSG("TLSX_ECH_Parse"); if (ssl->options.disableECH) { @@ -14385,7 +14386,8 @@ static int TLSX_ECH_Parse(WOLFSSL* ssl, const byte* readBuf, word16 size, readBuf_p += len; offset += len; /* read payload (encrypted CH) len */ - ato16(readBuf_p, &ech->innerClientHelloLen); + ato16(readBuf_p, &lenCh); + ech->innerClientHelloLen = lenCh; readBuf_p += 2; offset += 2; /* Check payload is no bigger than remaining bytes. */ diff --git a/src/tls13.c b/src/tls13.c index e46a518f71..aa38a4fe5d 100644 --- a/src/tls13.c +++ b/src/tls13.c @@ -3801,6 +3801,7 @@ int EchConfigGetSupportedCipherSuite(WOLFSSL_EchConfig* config) int i = 0; if (!wc_HpkeKemIsSupported(config->kemId)) { + WOLFSSL_MSG("ECH config: KEM not supported"); return WOLFSSL_FATAL_ERROR; } @@ -3811,6 +3812,7 @@ int EchConfigGetSupportedCipherSuite(WOLFSSL_EchConfig* config) } } + WOLFSSL_MSG("ECH config: KDF or AEAD not supported"); return WOLFSSL_FATAL_ERROR; } @@ -3933,10 +3935,14 @@ static int EchCalcAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz, if (isHrr) { /* the transcript hash of ClientHelloInner1 */ - hashSz = GetMsgHash(ssl, clientHelloInnerHash); - if (hashSz > 0) { + ret = GetMsgHash(ssl, clientHelloInnerHash); + if (ret > 0) { + hashSz = ret; ret = 0; } + else if (ret == 0) { + ret = HASH_TYPE_E; + } /* restart ECH transcript hash, similar to RestartHandshakeHash but * don't add a cookie */ @@ -3976,6 +3982,9 @@ static int EchCalcAcceptance(WOLFSSL* ssl, byte* label, word16 labelSz, if (ret > 0) { ret = 0; } + else if (ret == 0) { + ret = HASH_TYPE_E; + } } /* pick the right type and size based on mac_algorithm */ @@ -4752,15 +4761,18 @@ int SendTls13ClientHello(WOLFSSL* ssl) /* get size for inner */ ret = TLSX_GetRequestSize(ssl, client_hello, &args->length); + + /* set the type to outer */ + args->ech->type = ECH_TYPE_OUTER; if (ret != 0) return ret; - /* set the type to outer */ - args->ech->type = 0; /* set innerClientHelloLen to ClientHelloInner + padding + tag */ args->ech->paddingLen = 31 - ((args->length - 1) % 32); - args->ech->innerClientHelloLen = (word16)(args->length + - args->ech->paddingLen + args->ech->hpke->Nt); + args->ech->innerClientHelloLen = args->length + + args->ech->paddingLen + args->ech->hpke->Nt; + if (args->ech->innerClientHelloLen > 0xFFFF) + return BUFFER_E; /* set the length back to before we computed ClientHelloInner size */ args->length = (word32)args->preXLength; } @@ -4902,8 +4914,10 @@ int SendTls13ClientHello(WOLFSSL* ssl) args->ech->innerClientHello = (byte*)XMALLOC(args->ech->innerClientHelloLen - args->ech->hpke->Nt, ssl->heap, DYNAMIC_TYPE_TMP_BUFFER); - if (args->ech->innerClientHello == NULL) + if (args->ech->innerClientHello == NULL) { + args->ech->type = ECH_TYPE_OUTER; return MEMORY_E; + } /* set the padding bytes to 0 */ XMEMSET(args->ech->innerClientHello + args->ech->innerClientHelloLen - args->ech->hpke->Nt - args->ech->paddingLen, 0, @@ -4926,8 +4940,10 @@ int SendTls13ClientHello(WOLFSSL* ssl) /* change the outer client random */ ret = wc_RNG_GenerateBlock(ssl->rng, args->output + args->clientRandomOffset, RAN_LEN); - if (ret != 0) + if (ret != 0) { + args->ech->type = ECH_TYPE_OUTER; return ret; + } /* copy the new client random */ XMEMCPY(ssl->arrays->clientRandom, args->output + args->clientRandomOffset, RAN_LEN); @@ -4936,10 +4952,10 @@ int SendTls13ClientHello(WOLFSSL* ssl) ret = TLSX_WriteRequest(ssl, args->ech->innerClientHello + args->idx - (RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ), client_hello, &args->length); + /* set the type to outer */ + args->ech->type = ECH_TYPE_OUTER; if (ret != 0) return ret; - /* set the type to outer */ - args->ech->type = 0; } #endif @@ -5694,6 +5710,9 @@ int DoTls13ServerHello(WOLFSSL* ssl, const byte* input, word32* inOutIdx, /* check for acceptConfirmation */ if (ssl->echConfigs != NULL && !ssl->options.disableECH) { args->echX = TLSX_Find(ssl->extensions, TLSX_ECH); + if (args->echX == NULL || args->echX->data == NULL) + return WOLFSSL_FATAL_ERROR; + /* account for hrr extension instead of server random */ if (args->extMsgType == hello_retry_request) { args->acceptOffset = @@ -8648,6 +8667,8 @@ int CreateSigData(WOLFSSL* ssl, byte* sigData, word16* sigDataSz, ret = GetMsgHash(ssl, &sigData[idx]); if (ret < 0) return ret; + if (ret == 0) + return HASH_TYPE_E; *sigDataSz = (word16)(idx + ret); ret = 0; diff --git a/wolfcrypt/src/hpke.c b/wolfcrypt/src/hpke.c index 8f16f66f70..0c1037325d 100644 --- a/wolfcrypt/src/hpke.c +++ b/wolfcrypt/src/hpke.c @@ -917,7 +917,7 @@ int wc_HpkeInitSealContext(Hpke* hpke, HpkeBaseContext* context, void* ephemeralKey, void* receiverKey, byte* info, word32 infoSz) { if (hpke == NULL || context == NULL || ephemeralKey == NULL || - receiverKey == NULL || (info == NULL && infoSz > 0)) { + receiverKey == NULL || (info == NULL && infoSz != 0)) { return BAD_FUNC_ARG; } @@ -935,7 +935,7 @@ int wc_HpkeContextSealBase(Hpke* hpke, HpkeBaseContext* context, int ret; byte nonce[HPKE_Nn_MAX]; WC_DECLARE_VAR(aes, Aes, 1, 0); - if (hpke == NULL || context == NULL || (aad == NULL && aadSz > 0) || + if (hpke == NULL || context == NULL || (aad == NULL && aadSz != 0) || plaintext == NULL || out == NULL) { return BAD_FUNC_ARG; } @@ -1160,7 +1160,7 @@ int wc_HpkeInitOpenContext(Hpke* hpke, HpkeBaseContext* context, word32 infoSz) { if (hpke == NULL || context == NULL || receiverKey == NULL || pubKey == NULL - || (info == NULL && infoSz > 0)) { + || (info == NULL && infoSz != 0)) { return BAD_FUNC_ARG; } @@ -1175,7 +1175,8 @@ int wc_HpkeContextOpenBase(Hpke* hpke, HpkeBaseContext* context, byte* aad, int ret; byte nonce[HPKE_Nn_MAX]; WC_DECLARE_VAR(aes, Aes, 1, 0); - if (hpke == NULL || context == NULL || ciphertext == NULL || out == NULL) { + if (hpke == NULL || context == NULL || (aad == NULL && aadSz != 0) || + ciphertext == NULL || out == NULL) { return BAD_FUNC_ARG; } diff --git a/wolfcrypt/test/test.c b/wolfcrypt/test/test.c index ff297d7142..0a275b2849 100644 --- a/wolfcrypt/test/test.c +++ b/wolfcrypt/test/test.c @@ -32177,18 +32177,24 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t x963kdf_test(void) defined(HAVE_CURVE448)) && \ defined(HAVE_AESGCM) -static wc_test_ret_t hpke_test_single(Hpke* hpke) +/* test null/bad arguments for wc_HpkeInit, a one-shot seal/open round-trip + * with wc_HpkeSealBase/wc_HpkeOpenBase, and auth failure cases (wrong info, + * wrong AAD, tampered ciphertext, wrong receiver key) */ +static wc_test_ret_t hpke_test_single(Hpke* hpke, int kem, int kdf, int aead) { wc_test_ret_t ret = 0; int rngRet = 0; WC_RNG rng[1]; const char* start_text = "this is a test"; const char* info_text = "info"; + const char* alt_info_text = "different info"; const char* aad_text = "aad"; + const char* alt_aad_text = "different aad"; byte ciphertext[MAX_HPKE_LABEL_SZ]; byte plaintext[MAX_HPKE_LABEL_SZ]; void* receiverKey = NULL; void* ephemeralKey = NULL; + void* wrongKey = NULL; #ifdef WOLFSSL_SMALL_STACK byte *pubKey = NULL; /* public key */ word16 pubKeySz = (word16)HPKE_Npk_MAX; @@ -32197,204 +32203,796 @@ static wc_test_ret_t hpke_test_single(Hpke* hpke) word16 pubKeySz = (word16)sizeof(pubKey); #endif + /* NULL hpke */ + ret = wc_HpkeInit(NULL, kem, kdf, aead, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); + /* bad kem */ + ret = wc_HpkeInit(hpke, 0, kdf, aead, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); + /* bad kdf */ + ret = wc_HpkeInit(hpke, kem, 0, aead, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); + /* bad aead */ + ret = wc_HpkeInit(hpke, kem, kdf, 0, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + return WC_TEST_RET_ENC_EC(ret); + /* valid init */ + ret = wc_HpkeInit(hpke, kem, kdf, aead, NULL); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + rngRet = ret = wc_InitRng(rng); + if (ret != 0) + return WC_TEST_RET_ENC_EC(ret); + +#ifdef WOLFSSL_SMALL_STACK + if (ret == 0) { + pubKey = (byte *)XMALLOC(pubKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (pubKey == NULL) + ret = WC_TEST_RET_ENC_EC(MEMORY_E); + } +#endif + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeGenerateKeyPair(NULL, &receiverKey, rng); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeGenerateKeyPair(hpke, NULL, rng); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + + /* generate the keys */ + if (ret == 0) { + ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + if (ret == 0) { + ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeSealBase(NULL, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, NULL, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, NULL, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, + (byte*)NULL, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)NULL, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)NULL, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + + /* seal */ + if (ret == 0) { + ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), + ciphertext); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeSerializePublicKey(NULL, ephemeralKey, pubKey, &pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSerializePublicKey(hpke, NULL, pubKey, &pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, NULL, &pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + + /* export ephemeral key */ + if (ret == 0) { + ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeOpenBase(NULL, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, NULL, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, NULL, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, 0, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)NULL, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)NULL, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + NULL, (word32)XSTRLEN(start_text), + plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + + /* wrong info */ + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)alt_info_text, (word32)XSTRLEN(alt_info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), plaintext); + if (ret == 0) + ret = WC_TEST_RET_ENC_NC; + else + ret = 0; + } + /* wrong AAD */ + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)alt_aad_text, (word32)XSTRLEN(alt_aad_text), + ciphertext, (word32)XSTRLEN(start_text), plaintext); + if (ret == 0) + ret = WC_TEST_RET_ENC_NC; + else + ret = 0; + } + /* tampered ciphertext */ + if (ret == 0) { + ciphertext[0] ^= 0xFF; + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), plaintext); + ciphertext[0] ^= 0xFF; + if (ret == 0) + ret = WC_TEST_RET_ENC_NC; + else + ret = 0; + } + /* wrong receiver key */ + if (ret == 0) + ret = wc_HpkeGenerateKeyPair(hpke, &wrongKey, rng); + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, wrongKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), plaintext); + if (ret == 0) + ret = WC_TEST_RET_ENC_NC; + else + ret = 0; + } + if (wrongKey != NULL) { + wc_HpkeFreeKey(hpke, hpke->kem, wrongKey, hpke->heap); + wrongKey = NULL; + } + + /* open with exported ephemeral key */ + if (ret == 0) { + ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, + (byte*)info_text, (word32)XSTRLEN(info_text), + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertext, (word32)XSTRLEN(start_text), + plaintext); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + if (ret == 0) { + ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_NC; + } + + if (ephemeralKey != NULL) + wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap); + if (receiverKey != NULL) + wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, hpke->heap); + + WC_FREE_VAR_EX(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + + if (rngRet == 0) + wc_FreeRng(rng); + + return ret; +} +/* test null/bad arguments for the context-based HPKE API + * (wc_HpkeInitSealContext, wc_HpkeContextSealBase, wc_HpkeInitOpenContext, + * wc_HpkeContextOpenBase) and wc_HpkeDeserializePublicKey, a two-message + * seal/open round-trip, out-of-order open rejection, and seq overflow */ +static wc_test_ret_t hpke_test_multi(Hpke* hpke) +{ + wc_test_ret_t ret = 0; + int rngRet = 0; + WC_RNG rng[1]; + const char* start_text = "this is a test"; + const char* info_text = "info"; + const char* aad_text = "aad"; + byte ciphertexts[2][MAX_HPKE_LABEL_SZ]; + byte plaintext[MAX_HPKE_LABEL_SZ]; + void* receiverKey = NULL; + void* ephemeralKey = NULL; + void* deserializedKey = NULL; +#ifdef WOLFSSL_SMALL_STACK + HpkeBaseContext* context = NULL; + byte* pubKey = NULL; + word16 pubKeySz = (word16)HPKE_Npk_MAX; +#else + HpkeBaseContext context[1]; + byte pubKey[HPKE_Npk_MAX]; + word16 pubKeySz = (word16)sizeof(pubKey); +#endif + + rngRet = ret = wc_InitRng(rng); if (ret != 0) return WC_TEST_RET_ENC_EC(ret); #ifdef WOLFSSL_SMALL_STACK + pubKey = (byte*)XMALLOC(pubKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); + if (pubKey == NULL) + ret = MEMORY_E; + if (ret == 0) + context = (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext), HEAP_HINT, + DYNAMIC_TYPE_TMP_BUFFER); + if (context == NULL) + ret = MEMORY_E; +#endif + + /* generate the keys */ + if (ret == 0) + ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); + if (ret == 0) + ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng); + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeInitSealContext(NULL, context, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, NULL, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, context, NULL, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, NULL, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* NULL info with non-zero infoSz */ + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey, + NULL, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* infoSz too large to fit in labeled_ikm scratch buffer */ + if (ret == 0) { + /* prefer ciphertexts[0] to info_text for this test since static + * analysis may throw an error */ + ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey, + ciphertexts[0], MAX_HPKE_LABEL_SZ); + if (ret != WC_NO_ERR_TRACE(BUFFER_E)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + + /* initialize a valid seal context for ContextSealBase tests */ + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + + /* Negative test case with NULL argument */ + if (ret == 0) { + ret = wc_HpkeContextSealBase(NULL, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[0]); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeContextSealBase(hpke, NULL, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[0]); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* NULL aad with non-zero aadSz */ + if (ret == 0) { + ret = wc_HpkeContextSealBase(hpke, context, + NULL, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[0]); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } if (ret == 0) { - pubKey = (byte *)XMALLOC(pubKeySz, HEAP_HINT, - DYNAMIC_TYPE_TMP_BUFFER); - if (pubKey == NULL) - ret = WC_TEST_RET_ENC_EC(MEMORY_E); + ret = wc_HpkeContextSealBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + NULL, (word32)XSTRLEN(start_text), ciphertexts[0]); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } -#endif - - /* generate the keys */ if (ret == 0) { - ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); - if (ret != 0) + ret = wc_HpkeContextSealBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } + /* seal message 0 */ if (ret == 0) { - ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng); + ret = wc_HpkeContextSealBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[0]); if (ret != 0) ret = WC_TEST_RET_ENC_EC(ret); } - - /* seal */ + /* seal message 1 */ if (ret == 0) { - ret = wc_HpkeSealBase(hpke, ephemeralKey, receiverKey, - (byte*)info_text, (word32)XSTRLEN(info_text), + ret = wc_HpkeContextSealBase(hpke, context, (byte*)aad_text, (word32)XSTRLEN(aad_text), - (byte*)start_text, (word32)XSTRLEN(start_text), - ciphertext); + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[1]); if (ret != 0) ret = WC_TEST_RET_ENC_EC(ret); } - /* export ephemeral key */ + /* Negative test case with NULL argument */ if (ret == 0) { ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz); if (ret != 0) ret = WC_TEST_RET_ENC_EC(ret); } - - /* open with exported ephemeral key */ if (ret == 0) { - ret = wc_HpkeOpenBase(hpke, receiverKey, pubKey, pubKeySz, - (byte*)info_text, (word32)XSTRLEN(info_text), - (byte*)aad_text, (word32)XSTRLEN(aad_text), - ciphertext, (word32)XSTRLEN(start_text), - plaintext); + ret = wc_HpkeDeserializePublicKey(NULL, &deserializedKey, pubKey, + pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeDeserializePublicKey(hpke, NULL, pubKey, pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeDeserializePublicKey(hpke, &deserializedKey, NULL, + pubKeySz); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* inSz = 0 is less than Npk → BUFFER_E */ + if (ret == 0) { + ret = wc_HpkeDeserializePublicKey(hpke, &deserializedKey, pubKey, 0); + if (ret != WC_NO_ERR_TRACE(BUFFER_E)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* deserialize result must re-serialize identically */ + if (ret == 0) { + ret = wc_HpkeDeserializePublicKey(hpke, &deserializedKey, pubKey, + pubKeySz); if (ret != 0) ret = WC_TEST_RET_ENC_EC(ret); } - if (ret == 0) { - ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text)); + word16 reSz = (word16)sizeof(plaintext); + ret = wc_HpkeSerializePublicKey(hpke, deserializedKey, + plaintext, &reSz); if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + else if (reSz != pubKeySz || XMEMCMP(plaintext, pubKey, pubKeySz) != 0) ret = WC_TEST_RET_ENC_NC; } + if (deserializedKey != NULL) { + wc_HpkeFreeKey(hpke, hpke->kem, deserializedKey, hpke->heap); + deserializedKey = NULL; + } /* Negative test case with NULL argument */ if (ret == 0) { - ret = wc_HpkeGenerateKeyPair(NULL, &receiverKey, rng); + ret = wc_HpkeInitOpenContext(NULL, context, receiverKey, pubKey, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ret = WC_TEST_RET_ENC_EC(ret); else ret = 0; } - if (ret == 0) { - ret = wc_HpkeGenerateKeyPair(hpke, NULL, rng); + ret = wc_HpkeInitOpenContext(hpke, NULL, receiverKey, pubKey, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ret = WC_TEST_RET_ENC_EC(ret); else ret = 0; } - if (ret == 0) { - ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, NULL); + ret = wc_HpkeInitOpenContext(hpke, context, NULL, pubKey, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, NULL, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, pubKey, + pubKeySz, NULL, (word32)XSTRLEN(info_text)); if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) ret = WC_TEST_RET_ENC_EC(ret); else ret = 0; } - if (ephemeralKey != NULL) - wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap); - - if (receiverKey != NULL) - wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, hpke->heap); - - WC_FREE_VAR_EX(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - - if (rngRet == 0) - wc_FreeRng(rng); - - return ret; -} + /* initialize a valid open context for ContextOpenBase tests */ + if (ret == 0) { + ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, pubKey, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } -static wc_test_ret_t hpke_test_multi(Hpke* hpke) -{ - wc_test_ret_t ret = 0; - int rngRet = 0; - WC_RNG rng[1]; - const char* start_text = "this is a test"; - const char* info_text = "info"; - const char* aad_text = "aad"; - byte ciphertexts[2][MAX_HPKE_LABEL_SZ]; - byte plaintext[MAX_HPKE_LABEL_SZ]; - void* receiverKey = NULL; - void* ephemeralKey = NULL; -#ifdef WOLFSSL_SMALL_STACK - HpkeBaseContext* context = NULL; - byte *pubKey = NULL; /* public key */ - word16 pubKeySz = (word16)HPKE_Npk_MAX; -#else - HpkeBaseContext context[1]; - byte pubKey[HPKE_Npk_MAX]; /* public key */ - word16 pubKeySz = (word16)sizeof(pubKey); -#endif - rngRet = ret = wc_InitRng(rng); - if (ret != 0) - return ret; -#ifdef WOLFSSL_SMALL_STACK - pubKey = (byte *)XMALLOC(pubKeySz, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); - if (pubKey == NULL) - ret = MEMORY_E; + /* Negative test case with NULL argument */ if (ret == 0) { - context = (HpkeBaseContext*)XMALLOC(sizeof(HpkeBaseContext), HEAP_HINT, - DYNAMIC_TYPE_TMP_BUFFER); + ret = wc_HpkeContextOpenBase(NULL, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[0], (word32)XSTRLEN(start_text), plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } - if (context == NULL) - ret = MEMORY_E; -#endif - /* generate the keys */ - if (ret == 0) - ret = wc_HpkeGenerateKeyPair(hpke, &ephemeralKey, rng); - if (ret == 0) - ret = wc_HpkeGenerateKeyPair(hpke, &receiverKey, rng); - /* setup seal context */ if (ret == 0) { - ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey, - (byte*)info_text, (word32)XSTRLEN(info_text)); + ret = wc_HpkeContextOpenBase(hpke, NULL, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[0], (word32)XSTRLEN(start_text), plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } - /* seal message 0 */ + /* NULL aad with non-zero aadSz */ if (ret == 0) { - ret = wc_HpkeContextSealBase(hpke, context, + ret = wc_HpkeContextOpenBase(hpke, context, + NULL, (word32)XSTRLEN(aad_text), + ciphertexts[0], (word32)XSTRLEN(start_text), plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ret == 0) { + ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text, (word32)XSTRLEN(aad_text), - (byte*)start_text, (word32)XSTRLEN(start_text), - ciphertexts[context->seq]); + NULL, (word32)XSTRLEN(start_text), plaintext); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } - /* seal message 1 */ if (ret == 0) { - ret = wc_HpkeContextSealBase(hpke, context, + ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text, (word32)XSTRLEN(aad_text), - (byte*)start_text, (word32)XSTRLEN(start_text), - ciphertexts[context->seq]); + ciphertexts[0], (word32)XSTRLEN(start_text), NULL); + if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; } - /* export ephemeral key */ - if (ret == 0) - ret = wc_HpkeSerializePublicKey(hpke, ephemeralKey, pubKey, &pubKeySz); - /* setup open context */ + + /* out-of-order open: try msg1 first */ if (ret == 0) { - ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, pubKey, - pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); + ret = wc_HpkeContextOpenBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[1], (word32)XSTRLEN(start_text), plaintext); + if (ret == 0) + ret = WC_TEST_RET_ENC_NC; + else + ret = 0; } + /* open message 0 */ if (ret == 0) { - ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text, - (word32)XSTRLEN(aad_text), ciphertexts[context->seq], - (word32)XSTRLEN(start_text), plaintext); + ret = wc_HpkeContextOpenBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[0], (word32)XSTRLEN(start_text), plaintext); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } /* check message 0 */ - if (ret == 0) + if (ret == 0) { ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_NC; + } /* open message 1 */ if (ret == 0) { - ret = wc_HpkeContextOpenBase(hpke, context, (byte*)aad_text, - (word32)XSTRLEN(aad_text), ciphertexts[context->seq], - (word32)XSTRLEN(start_text), plaintext); + ret = wc_HpkeContextOpenBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[1], (word32)XSTRLEN(start_text), plaintext); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); } /* check message 1 */ - if (ret == 0) + if (ret == 0) { ret = XMEMCMP(plaintext, start_text, XSTRLEN(start_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_NC; + } + + /* seal context overflowed */ + if (ret == 0) { + ret = wc_HpkeInitSealContext(hpke, context, ephemeralKey, receiverKey, + (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + if (ret == 0) { + context->seq = WC_MAX_SINT_OF(int); + ret = wc_HpkeContextSealBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + (byte*)start_text, (word32)XSTRLEN(start_text), ciphertexts[0]); + if (ret != WC_NO_ERR_TRACE(SEQ_OVERFLOW_E)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + /* open context overflowed */ + if (ret == 0) { + ret = wc_HpkeInitOpenContext(hpke, context, receiverKey, pubKey, + pubKeySz, (byte*)info_text, (word32)XSTRLEN(info_text)); + if (ret != 0) + ret = WC_TEST_RET_ENC_EC(ret); + } + if (ret == 0) { + context->seq = WC_MAX_SINT_OF(int); + ret = wc_HpkeContextOpenBase(hpke, context, + (byte*)aad_text, (word32)XSTRLEN(aad_text), + ciphertexts[0], (word32)XSTRLEN(start_text), plaintext); + if (ret != WC_NO_ERR_TRACE(SEQ_OVERFLOW_E)) + ret = WC_TEST_RET_ENC_EC(ret); + else + ret = 0; + } + if (ephemeralKey != NULL) wc_HpkeFreeKey(hpke, hpke->kem, ephemeralKey, hpke->heap); if (receiverKey != NULL) wc_HpkeFreeKey(hpke, hpke->kem, receiverKey, hpke->heap); + #ifdef WOLFSSL_SMALL_STACK if (pubKey != NULL) XFREE(pubKey, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); if (context != NULL) XFREE(context, HEAP_HINT, DYNAMIC_TYPE_TMP_BUFFER); #endif + if (rngRet == 0) wc_FreeRng(rng); + return ret; } @@ -32407,11 +33005,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if defined(HAVE_ECC) && defined(WOLFSSL_AES_128) #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && !defined(NO_SHA256) /* p256 */ - ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA256, - HPKE_AES_128_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA256, + HPKE_AES_128_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32422,11 +33017,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && \ !defined(NO_SHA256) && defined(WOLFSSL_SHA512) /* p256 with sha512 kdf */ - ret = wc_HpkeInit(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA512, - HPKE_AES_128_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_P256_HKDF_SHA256, HKDF_SHA512, + HPKE_AES_128_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32438,11 +33030,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if (defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)) && \ defined(WOLFSSL_SHA384) /* p384 */ - ret = wc_HpkeInit(hpke, DHKEM_P384_HKDF_SHA384, HKDF_SHA384, - HPKE_AES_128_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_P384_HKDF_SHA384, HKDF_SHA384, + HPKE_AES_128_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32453,11 +33042,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && \ defined(WOLFSSL_SHA512) /* p521 */ - ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA512, - HPKE_AES_128_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA512, + HPKE_AES_128_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32468,11 +33054,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if (defined(HAVE_ECC521) || defined(HAVE_ALL_CURVES)) && \ defined(WOLFSSL_SHA384) && defined(WOLFSSL_SHA512) /* p521 with sha384 kdf */ - ret = wc_HpkeInit(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA384, - HPKE_AES_128_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_P521_HKDF_SHA512, HKDF_SHA384, + HPKE_AES_128_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32483,11 +33066,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if defined(HAVE_CURVE25519) && !defined(NO_SHA256) && defined(WOLFSSL_AES_256) /* test with curve25519 and aes256 */ - ret = wc_HpkeInit(hpke, DHKEM_X25519_HKDF_SHA256, HKDF_SHA256, - HPKE_AES_256_GCM, NULL); - if (ret != 0) - return WC_TEST_RET_ENC_EC(ret); - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_X25519_HKDF_SHA256, HKDF_SHA256, + HPKE_AES_256_GCM); if (ret != 0) return ret; ret = hpke_test_multi(hpke); @@ -32498,15 +33078,8 @@ WOLFSSL_TEST_SUBROUTINE wc_test_ret_t hpke_test(void) #if defined(HAVE_CURVE448) && defined(WOLFSSL_SHA512) && \ defined(WOLFSSL_AES_256) - /* test with curve448 and aes256 */ - ret = wc_HpkeInit(hpke, DHKEM_X448_HKDF_SHA512, HKDF_SHA512, - HPKE_AES_256_GCM, NULL); - - /* HPKE does not support X448 yet, so expect failure */ - if (ret != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) - return WC_TEST_RET_ENC_EC(ret); - - ret = hpke_test_single(hpke); + ret = hpke_test_single(hpke, DHKEM_X448_HKDF_SHA512, HKDF_SHA512, + HPKE_AES_256_GCM); /* HPKE does not support X448 yet, so expect failure */ if (WC_TEST_RET_DEC_EC(ret) != WC_NO_ERR_TRACE(BAD_FUNC_ARG)) diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 5e512f76eb..2cfb968370 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -3131,9 +3131,9 @@ typedef struct WOLFSSL_ECH { byte* outerClientPayload; byte* confBuf; EchCipherSuite cipherSuite; - word16 aadLen; + word32 aadLen; + word32 innerClientHelloLen; word16 paddingLen; - word16 innerClientHelloLen; word16 kemId; word16 encLen; EchState state;