diff --git a/src/internal.c b/src/internal.c index 17e7c0882..0607b4e6e 100644 --- a/src/internal.c +++ b/src/internal.c @@ -1404,6 +1404,13 @@ void InitSuites(Suites* suites, ProtocolVersion pv, word16 haveRSA, } #endif +#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + if (tls && havePSK) { + suites->suites[idx++] = ECC_BYTE; + suites->suites[idx++] = TLS_ECDHE_PSK_WITH_NULL_SHA256; + } +#endif + #ifdef BUILD_TLS_DHE_PSK_WITH_NULL_SHA256 if (tls && haveDH && havePSK) { suites->suites[idx++] = 0; @@ -5497,6 +5504,7 @@ static int SanityCheckMsgReceived(WOLFSSL* ssl, byte type) if (ssl->msgsReceived.got_certificate == 0) { if (ssl->specs.kea == psk_kea || ssl->specs.kea == dhe_psk_kea || + ssl->specs.kea == ecdhe_psk_kea || ssl->options.usingAnon_cipher) { WOLFSSL_MSG("No Cert required"); } else { @@ -9929,6 +9937,10 @@ static const char* const cipher_names[] = #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA "ECDHE-ECDSA-NULL-SHA", #endif + +#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + "ECDHE-PSK-NULL-SHA256", +#endif }; @@ -10347,6 +10359,10 @@ static int cipher_name_idx[] = #ifdef BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA TLS_ECDHE_ECDSA_WITH_NULL_SHA, #endif + +#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + TLS_ECDHE_PSK_WITH_NULL_SHA256, +#endif }; @@ -11573,6 +11589,80 @@ static void PickHashSigAlgo(WOLFSSL* ssl, break; } #endif /* !NO_DH || !NO_PSK */ + + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + byte b; + + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { + return BUFFER_ERROR; + } + + ato16(input + *inOutIdx, &length); + *inOutIdx += OPAQUE16_LEN; + + if ((*inOutIdx - begin) + length > size) { + return BUFFER_ERROR; + } + + /* get PSK server hint from the wire */ + XMEMCPY(ssl->arrays->server_hint, input + *inOutIdx, + min(length, MAX_PSK_ID_LEN)); + + ssl->arrays->server_hint[min(length, MAX_PSK_ID_LEN - 1)] = 0; + *inOutIdx += length; + + + if ((*inOutIdx - begin) + ENUM_LEN + OPAQUE16_LEN + + OPAQUE8_LEN > size) { + return BUFFER_ERROR; + } + + /* Check curve name and ID */ + b = input[(*inOutIdx)++]; + if (b != named_curve) { + return ECC_CURVETYPE_ERROR; + } + + *inOutIdx += 1; /* curve type, eat leading 0 */ + b = input[(*inOutIdx)++]; + if (CheckCurveId(b) != 0) { + return ECC_CURVE_ERROR; + } + + length = input[(*inOutIdx)++]; + + if ((*inOutIdx - begin) + length > size) { + return BUFFER_ERROR; + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + return MEMORY_E; + } + wc_ecc_init(ssl->peerEccKey); + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + wc_ecc_init(ssl->peerEccKey); + } + + if (wc_ecc_import_x963(input + *inOutIdx, length, + ssl->peerEccKey) != 0) { + return ECC_PEERKEY_ERROR; + } + + *inOutIdx += length; + ssl->peerEccKeyPresent = 1; + + break; + } + #endif /* HAVE_ECC || !NO_PSK */ } /* switch() */ #if !defined(NO_DH) || defined(HAVE_ECC) @@ -12616,6 +12706,11 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) { byte* pms = ssl->arrays->preMasterSecret; + /* sanity check that PSK client callback has been set */ + if (ssl->options.client_psk_cb == NULL) { + WOLFSSL_MSG("No client PSK callback set"); + return PSK_KEY_ERROR; + } ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); @@ -12676,6 +12771,11 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) return NO_PEER_KEY; } + /* sanity check that PSK client callback has been set */ + if (ssl->options.client_psk_cb == NULL) { + WOLFSSL_MSG("No client PSK callback set"); + return PSK_KEY_ERROR; + } ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, ssl->arrays->server_hint, ssl->arrays->client_identity, MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); @@ -12749,6 +12849,117 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) } break; #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + byte* es = encSecret; + ecc_key myKey; + ecc_key* peerKey = NULL; + word32 size = MAX_ENCRYPT_SZ; + word32 esSz = 0; + + /* sanity check that PSK client callback has been set */ + if (ssl->options.client_psk_cb == NULL) { + WOLFSSL_MSG("No client PSK callback set"); + return PSK_KEY_ERROR; + } + + /* Send PSK client identity */ + ssl->arrays->psk_keySz = ssl->options.client_psk_cb(ssl, + ssl->arrays->server_hint, ssl->arrays->client_identity, + MAX_PSK_ID_LEN, ssl->arrays->psk_key, MAX_PSK_KEY_LEN); + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return PSK_KEY_ERROR; + } + esSz = (word32)XSTRLEN(ssl->arrays->client_identity); + + if (esSz > MAX_PSK_ID_LEN) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return CLIENT_ID_ERROR; + } + + /* place size and identity in output buffer sz:identity */ + c16toa((word16)esSz, es); + es += OPAQUE16_LEN; + XMEMCPY(es, ssl->arrays->client_identity, esSz); + es += esSz; + encSz = esSz + OPAQUE16_LEN; + + /* Send Client ECC public key */ + if (!ssl->peerEccKey || !ssl->peerEccKeyPresent || + !ssl->peerEccKey->dp) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return NO_PEER_KEY; + } + peerKey = ssl->peerEccKey; + + if (peerKey == NULL) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return NO_PEER_KEY; + } + + wc_ecc_init(&myKey); + ret = wc_ecc_make_key(ssl->rng, peerKey->dp->size, &myKey); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ECC_MAKEKEY_ERROR; + } + + /* Place ECC key in output buffer, leaving room for size */ + ret = wc_ecc_export_x963(&myKey, es + 1, &size); + *es = size; /* place size of key in output buffer */ + encSz += size + 1; + + if (ret != 0) + ret = ECC_EXPORT_ERROR; + else { + size = sizeof(ssl->arrays->preMasterSecret); + /* Create shared ECC key leaveing room at the begining + of buffer for size of shared key */ + ret = wc_ecc_shared_secret(&myKey, peerKey, + ssl->arrays->preMasterSecret + OPAQUE16_LEN, &size); + if (ret != 0) + ret = ECC_SHARED_ERROR; + } + + wc_ecc_free(&myKey); + if (ret != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(encSecret, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ret; + } + + /* Create pre master secret is the concatination of + eccSize + eccSharedKey + pskSize + pskKey */ + c16toa((word16)size, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN + size; + pms += ssl->arrays->preMasterSz; + + c16toa((word16)ssl->arrays->psk_keySz, pms); + pms += OPAQUE16_LEN; + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz += + ssl->arrays->psk_keySz + OPAQUE16_LEN; + + ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->psk_keySz = 0; /* No further need */ + } + break; + #endif /* HAVE_ECC && !NO_PSK */ #ifdef HAVE_NTRU case ntru_kea: { @@ -12881,7 +13092,8 @@ static word32 QSH_KeyExchangeWrite(WOLFSSL* ssl, byte isServer) tlsSz = 2; if (ssl->specs.kea == ecc_diffie_hellman_kea || - ssl->specs.kea == dhe_psk_kea) /* always off */ + ssl->specs.kea == dhe_psk_kea || + ssl->specs.kea == ecdhe_psk_kea) /* always off */ tlsSz = 0; sendSz = encSz + tlsSz + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; @@ -13905,6 +14117,169 @@ int DoSessionTicket(WOLFSSL* ssl, } #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + word32 hintLen; + word32 length, idx = RECORD_HEADER_SZ + HANDSHAKE_HEADER_SZ; + int sendSz; + byte *output; + ecc_key dsaKey; + #ifdef WOLFSSL_SMALL_STACK + byte* exportBuf = NULL; + #else + byte exportBuf[MAX_EXPORT_ECC_SZ]; + #endif + word32 expSz = MAX_EXPORT_ECC_SZ; + + /* curve type, named curve, length(1) */ + length = ENUM_LEN + CURVE_LEN + ENUM_LEN; + /* pub key size */ + WOLFSSL_MSG("Using ephemeral ECDH"); + + /* need ephemeral key now, create it if missing */ + if (ssl->eccTempKey == NULL) { + /* alloc/init on demand */ + ssl->eccTempKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->eccTempKey == NULL) { + WOLFSSL_MSG("EccTempKey Memory error"); + return MEMORY_E; + } + wc_ecc_init(ssl->eccTempKey); + } + if (ssl->eccTempKeyPresent == 0) { + if (wc_ecc_make_key(ssl->rng, ssl->eccTempKeySz, + ssl->eccTempKey) != 0) { + return ECC_MAKEKEY_ERROR; + } + ssl->eccTempKeyPresent = 1; + } + + #ifdef WOLFSSL_SMALL_STACK + exportBuf = (byte*)XMALLOC(MAX_EXPORT_ECC_SZ, NULL, + DYNAMIC_TYPE_TMP_BUFFER); + if (exportBuf == NULL) { + return MEMORY_E; + } + #endif + + if (wc_ecc_export_x963(ssl->eccTempKey, exportBuf, &expSz) != 0) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ECC_EXPORT_ERROR; + } + length += expSz; + + /* include size part */ + hintLen = (word32)XSTRLEN(ssl->arrays->server_hint); + if (hintLen > MAX_PSK_ID_LEN) { + #ifdef WOLFSSL_SMALL_STACK + XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return SERVER_HINT_ERROR; + } + length += hintLen + HINT_LEN_SZ; + sendSz = length + HANDSHAKE_HEADER_SZ + RECORD_HEADER_SZ; + + #ifdef HAVE_QSH + length += qshSz; + sendSz += qshSz; + #endif + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + sendSz += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + idx += DTLS_RECORD_EXTRA + DTLS_HANDSHAKE_EXTRA; + } + #endif + /* check for available size */ + if ((ret = CheckAvailableSize(ssl, sendSz)) != 0) { + wc_ecc_free(&dsaKey); + #ifdef WOLFSSL_SMALL_STACK + XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + return ret; + } + + /* get output buffer */ + output = ssl->buffers.outputBuffer.buffer + + ssl->buffers.outputBuffer.length; + + /* key data */ + c16toa((word16)hintLen, output + idx); + idx += HINT_LEN_SZ; + XMEMCPY(output + idx, ssl->arrays->server_hint, hintLen); + idx += hintLen; + + /* ECC key exchange data */ + output[idx++] = named_curve; + output[idx++] = 0x00; /* leading zero */ + output[idx++] = SetCurveId(wc_ecc_size(ssl->eccTempKey)); + output[idx++] = (byte)expSz; + XMEMCPY(output + idx, exportBuf, expSz); + #ifdef WOLFSSL_SMALL_STACK + XFREE(exportBuf, NULL, DYNAMIC_TYPE_TMP_BUFFER); + #endif + + #ifdef HAVE_QSH + if (ssl->peerQSHKeyPresent) { + if (qshSz > 0) { + idx = sendSz - qshSz; + QSH_KeyExchangeWrite(ssl, 1); + + /* extension type */ + c16toa(TLSX_QUANTUM_SAFE_HYBRID, output + idx); + idx += OPAQUE16_LEN; + + /* write to output and check amount written */ + if (TLSX_QSHPK_Write(ssl->QSH_secret->list, output + idx) + > qshSz - OPAQUE16_LEN) { + return MEMORY_E; + } + } + } + #endif + + + AddHeaders(output, length, server_key_exchange, ssl); + + #ifdef WOLFSSL_DTLS + if (ssl->options.dtls) { + if ((ret = DtlsPoolSave(ssl, output, sendSz)) != 0) { + return ret; + } + } + #endif + + ret = HashOutput(ssl, output, sendSz, 0); + + if (ret != 0) { + return ret; + } + + #ifdef WOLFSSL_CALLBACKS + if (ssl->hsInfoOn) { + AddPacketName("ServerKeyExchange", &ssl->handShakeInfo); + } + if (ssl->toInfoOn) { + AddPacketInfo("ServerKeyExchange", &ssl->timeoutInfo, output, + sendSz, ssl->heap); + } + #endif + + ssl->buffers.outputBuffer.length += sendSz; + if (ssl->options.groupMessages) { + ret = 0; + } + else { + ret = SendBuffered(ssl); + } + ssl->options.serverState = SERVER_KEYEXCHANGE_COMPLETE; + break; + } + #endif /* HAVE_ECC && !NO_PSK */ + #ifdef HAVE_ECC case ecc_diffie_hellman_kea: { @@ -16549,6 +16924,12 @@ int DoSessionTicket(WOLFSSL* ssl, byte* pms = ssl->arrays->preMasterSecret; word16 ci_sz; + /* sanity check that PSK server callback has been set */ + if (ssl->options.server_psk_cb == NULL) { + WOLFSSL_MSG("No server PSK callback set"); + return PSK_KEY_ERROR; + } + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { return BUFFER_ERROR; } @@ -16848,6 +17229,12 @@ int DoSessionTicket(WOLFSSL* ssl, word16 clientSz; DhKey dhKey; + /* sanity check that PSK server callback has been set */ + if (ssl->options.server_psk_cb == NULL) { + WOLFSSL_MSG("No server PSK callback set"); + return PSK_KEY_ERROR; + } + /* Read in the PSK hint */ if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { return BUFFER_ERROR; @@ -16948,6 +17335,141 @@ int DoSessionTicket(WOLFSSL* ssl, } break; #endif /* !NO_DH && !NO_PSK */ + #if defined(HAVE_ECC) && !defined(NO_PSK) + case ecdhe_psk_kea: + { + byte* pms = ssl->arrays->preMasterSecret; + word16 clientSz; + + /* sanity check that PSK server callback has been set */ + if (ssl->options.server_psk_cb == NULL) { + WOLFSSL_MSG("No server PSK callback set"); + return PSK_KEY_ERROR; + } + + /* Read in the PSK hint */ + if ((*inOutIdx - begin) + OPAQUE16_LEN > size) { + return BUFFER_ERROR; + } + + ato16(input + *inOutIdx, &clientSz); + *inOutIdx += OPAQUE16_LEN; + if (clientSz > MAX_PSK_ID_LEN) { + return CLIENT_ID_ERROR; + } + + if ((*inOutIdx - begin) + clientSz > size) { + return BUFFER_ERROR; + } + + XMEMCPY(ssl->arrays->client_identity, + input + *inOutIdx, clientSz); + *inOutIdx += clientSz; + ssl->arrays->client_identity[min(clientSz, MAX_PSK_ID_LEN-1)] = + 0; + + /* ECC key */ + if ((*inOutIdx - begin) + OPAQUE8_LEN > size) { + return BUFFER_ERROR; + } + + length = input[(*inOutIdx)++]; + + if ((*inOutIdx - begin) + length > size) { + return BUFFER_ERROR; + } + + if (ssl->peerEccKey == NULL) { + /* alloc/init on demand */ + ssl->peerEccKey = (ecc_key*)XMALLOC(sizeof(ecc_key), + ssl->ctx->heap, DYNAMIC_TYPE_ECC); + if (ssl->peerEccKey == NULL) { + WOLFSSL_MSG("PeerEccKey Memory error"); + return MEMORY_E; + } + wc_ecc_init(ssl->peerEccKey); + } else if (ssl->peerEccKeyPresent) { /* don't leak on reuse */ + wc_ecc_free(ssl->peerEccKey); + ssl->peerEccKeyPresent = 0; + wc_ecc_init(ssl->peerEccKey); + } + + if (wc_ecc_import_x963(input + *inOutIdx, length, + ssl->peerEccKey)) { + return ECC_PEERKEY_ERROR; + } + + *inOutIdx += length; + ssl->peerEccKeyPresent = 1; + + length = sizeof(ssl->arrays->preMasterSecret); + + if (ssl->eccTempKeyPresent == 0) { + WOLFSSL_MSG("Ecc ephemeral key not made correctly"); + ret = ECC_MAKEKEY_ERROR; + } else { + ret = wc_ecc_shared_secret(ssl->eccTempKey, + ssl->peerEccKey, ssl->arrays->preMasterSecret + + OPAQUE16_LEN, &length); + } + + if (ret != 0) { + return ECC_SHARED_ERROR; + } + + c16toa((word16)length, pms); + ssl->arrays->preMasterSz += OPAQUE16_LEN + length; + pms += ssl->arrays->preMasterSz; + + /* Use the PSK hint to look up the PSK and add it to the + * preMasterSecret here. */ + ssl->arrays->psk_keySz = ssl->options.server_psk_cb(ssl, + ssl->arrays->client_identity, ssl->arrays->psk_key, + MAX_PSK_KEY_LEN); + + if (ssl->arrays->psk_keySz == 0 || + ssl->arrays->psk_keySz > MAX_PSK_KEY_LEN) { + return PSK_KEY_ERROR; + } + + c16toa((word16) ssl->arrays->psk_keySz, pms); + pms += OPAQUE16_LEN; + + XMEMCPY(pms, ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->preMasterSz += + ssl->arrays->psk_keySz + OPAQUE16_LEN; + + #ifdef HAVE_QSH + if (ssl->options.haveQSH) { + /* extension name */ + ato16(input + *inOutIdx, &name); + *inOutIdx += OPAQUE16_LEN; + + if (name == TLSX_QUANTUM_SAFE_HYBRID) { + /* if qshSz is larger than 0 it is the length of + buffer used */ + if ((qshSz = TLSX_QSHCipher_Parse(ssl, input + *inOutIdx, + size - *inOutIdx + begin, 1)) < 0) { + return qshSz; + } + *inOutIdx += qshSz; + } + else { + /* unknown extension sent client ignored + handshake */ + return BUFFER_ERROR; + } + } + #endif + if (ret == 0) + ret = MakeMasterSecret(ssl); + + /* No further need for PSK */ + ForceZero(ssl->arrays->psk_key, ssl->arrays->psk_keySz); + ssl->arrays->psk_keySz = 0; + } + break; + #endif /* HAVE_ECC && !NO_PSK */ default: { WOLFSSL_MSG("Bad kea type"); diff --git a/src/keys.c b/src/keys.c index 7dcf824be..bbbc766c2 100644 --- a/src/keys.c +++ b/src/keys.c @@ -781,6 +781,24 @@ int SetCipherSpecs(WOLFSSL* ssl) break; #endif + +#ifdef BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + case TLS_ECDHE_PSK_WITH_NULL_SHA256 : + ssl->specs.bulk_cipher_algorithm = wolfssl_cipher_null; + ssl->specs.cipher_type = stream; + ssl->specs.mac_algorithm = sha256_mac; + ssl->specs.kea = ecdhe_psk_kea; + ssl->specs.sig_algo = anonymous_sa_algo; + ssl->specs.hash_size = SHA256_DIGEST_SIZE; + ssl->specs.pad_size = PAD_SHA; + ssl->specs.static_ecdh = 0; + ssl->specs.key_size = 0; + ssl->specs.block_size = 0; + ssl->specs.iv_size = 0; + + ssl->options.usingPSK_cipher = 1; + break; +#endif #endif /* HAVE_ECC */ #ifdef BUILD_TLS_RSA_WITH_AES_128_CCM_8 diff --git a/tests/test-dtls.conf b/tests/test-dtls.conf index 7a821fa04..625e11320 100644 --- a/tests/test-dtls.conf +++ b/tests/test-dtls.conf @@ -10,7 +10,7 @@ # server DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 -u --v 2 +-v 2 -l ECDHE-RSA-CHACHA20-POLY1305 # client DTLSv1 ECDHE-RSA-CHACHA20-POLY1305 @@ -43,7 +43,7 @@ # server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 -u --v 3 +-v 3 -l ECDHE-RSA-CHACHA20-POLY1305 # client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 @@ -64,6 +64,39 @@ -l ECDHE-ECDSA-CHACHA20-POLY1305 -A ./certs/server-ecc.pem +# server DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l DHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client DTLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server DTLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client DTLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-u +-v 3 +-l ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/server-ecc.pem + # server DTLSv1 RC4-SHA -u -v 2 @@ -284,6 +317,45 @@ -v 3 -l ECDHE-RSA-AES256-SHA +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-v 1 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-u +-v 2 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-u +-v 3 +-l ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + # server DTLSv1.1 ECDHE-EDCSA-RC4 -u -v 2 @@ -674,6 +746,42 @@ -l ECDH-ECDSA-AES256-SHA384 -A ./certs/server-ecc.pem +# server TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-u +-v 3 +-l ECDHE-PSK-NULL-SHA256 + # server DTLSv1 PSK-AES128 -s -u diff --git a/tests/test-qsh.conf b/tests/test-qsh.conf index c465531bb..d6fca56af 100644 --- a/tests/test-qsh.conf +++ b/tests/test-qsh.conf @@ -18,7 +18,7 @@ -A ./certs/server-ecc.pem # server TLSv1 ECDHE-RSA-CHACHA20-POLY1305 --v 1 +-v 1 -l QSH:ECDHE-RSA-CHACHA20-POLY1305 # client TLSv1 ECDHE-RSA-CHACHA20-POLY1305 @@ -34,7 +34,7 @@ -l QSH:DHE-RSA-CHACHA20-POLY1305 # server TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 --v 2 +-v 2 -l QSH:ECDHE-RSA-CHACHA20-POLY1305 # client TLSv1.1 ECDHE-RSA-CHACHA20-POLY1305 @@ -52,6 +52,33 @@ -l QSH:ECDHE-ECDSA-CHACHA20-POLY1305 -A ./certs/server-ecc.pem +# server TLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:DHE-RSA-CHACHA20-POLY1305-OLD + +# client TLSv1.2 DHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:DHE-RSA-CHACHA20-POLY1305-OLD + +# server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:ECDHE-RSA-CHACHA20-POLY1305-OLD + +# client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:ECDHE-RSA-CHACHA20-POLY1305-OLD + +# server TLSv1.2 ECDHE-EDCSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-v 3 +-l QSH:ECDHE-ECDSA-CHACHA20-POLY1305-OLD +-A ./certs/server-ecc.pem + # server TLSv1.2 DHE-RSA-CHACHA20-POLY1305 -v 3 -l QSH:DHE-RSA-CHACHA20-POLY1305 @@ -61,7 +88,7 @@ -l QSH:DHE-RSA-CHACHA20-POLY1305 # server TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 --v 3 +-v 3 -l QSH:ECDHE-RSA-CHACHA20-POLY1305 # client TLSv1.2 ECDHE-RSA-CHACHA20-POLY1305 @@ -311,11 +338,11 @@ -v 1 -l QSH:ECDHE-RSA-DES-CBC3-SHA -# server TLSv1 ECDHE-RSA-AES128 +# server TLSv1 ECDHE-RSA-AES128 -v 1 -l QSH:ECDHE-RSA-AES128-SHA -# client TLSv1 ECDHE-RSA-AES128 +# client TLSv1 ECDHE-RSA-AES128 -v 1 -l QSH:ECDHE-RSA-AES128-SHA @@ -327,6 +354,39 @@ -v 1 -l QSH:ECDHE-RSA-AES256-SHA +# server TLSv1 ECDHE-ECDSA-NULL-SHA +-v 1 +-l QSH:ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-v 1 +-l QSH:ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.1 ECDHE-ECDSA-NULL-SHA +-v 2 +-l QSH:ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1 ECDHE-ECDSA-NULL-SHA +-v 2 +-l QSH:ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + +# server TLSv1.2 ECDHE-ECDSA-NULL-SHA +-v 3 +-l QSH:ECDHE-ECDSA-NULL-SHA +-c ./certs/server-ecc.pem +-k ./certs/ecc-key.pem + +# client TLSv1.2 ECDHE-ECDSA-NULL-SHA +-v 3 +-l QSH:ECDHE-ECDSA-NULL-SHA +-A ./certs/server-ecc.pem + # server TLSv1.1 ECDHE-RSA-RC4 -v 2 -l QSH:ECDHE-RSA-RC4-SHA @@ -1095,6 +1155,36 @@ -v 3 -l QSH:DHE-RSA-AES256-SHA256 +# server TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-v 1 +-l QSH:ECDHE-PSK-NULL-SHA256 + +# client TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-v 1 +-l QSH:ECDHE-PSK-NULL-SHA256 + +# server TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-v 2 +-l QSH:ECDHE-PSK-NULL-SHA256 + +# client TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-v 2 +-l QSH:ECDHE-PSK-NULL-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-v 3 +-l QSH:ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-v 3 +-l QSH:ECDHE-PSK-NULL-SHA256 + # server TLSv1 PSK-AES128 -s -v 1 diff --git a/tests/test.conf b/tests/test.conf index 7cee48a1f..1e8f6db33 100644 --- a/tests/test.conf +++ b/tests/test.conf @@ -1128,6 +1128,36 @@ -v 3 -l DHE-RSA-AES256-SHA256 +# server TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1 ECDHE-PSK-NULL-SHA256 +-s +-v 1 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.1 ECDHE-PSK-NULL-SHA256 +-s +-v 2 +-l ECDHE-PSK-NULL-SHA256 + +# server TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-v 3 +-l ECDHE-PSK-NULL-SHA256 + +# client TLSv1.2 ECDHE-PSK-NULL-SHA256 +-s +-v 3 +-l ECDHE-PSK-NULL-SHA256 + # server TLSv1 PSK-AES128 -s -v 1 diff --git a/wolfssl/internal.h b/wolfssl/internal.h index 0acb6e4de..4d47de042 100644 --- a/wolfssl/internal.h +++ b/wolfssl/internal.h @@ -520,8 +520,13 @@ typedef byte word24[3]; #endif #endif /* NO_SHA */ #endif - #if defined(HAVE_NULL_CIPHER) && !defined(NO_SHA) - #define BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA + #if defined(HAVE_NULL_CIPHER) + #if !defined(NO_SHA) + #define BUILD_TLS_ECDHE_ECDSA_WITH_NULL_SHA + #endif + #if !defined(NO_PSK) && !defined(NO_SHA256) + #define BUILD_TLS_ECDHE_PSK_WITH_NULL_SHA256 + #endif #endif #endif #if defined(HAVE_CHACHA) && defined(HAVE_POLY1305) && !defined(NO_SHA256) \ @@ -709,6 +714,7 @@ enum { TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0x28, TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0x24, TLS_ECDHE_ECDSA_WITH_NULL_SHA = 0x06, + TLS_ECDHE_PSK_WITH_NULL_SHA256 = 0x3a, /* static ECDH, first byte is 0xC0 (ECC_BYTE) */ TLS_ECDH_RSA_WITH_AES_256_CBC_SHA = 0x0F, @@ -1942,6 +1948,7 @@ enum KeyExchangeAlgorithm { fortezza_kea, psk_kea, dhe_psk_kea, + ecdhe_psk_kea, ntru_kea, ecc_diffie_hellman_kea, ecc_static_diffie_hellman_kea /* for verify suite only */