Unit tests for post-quantum groups.

Also, fixes for the things they caught such as:

- ssl->arrays->preMasterSecret is pre-allocated so copy into it instead of
  moving ownership of buffer.
- server does not need to save the public key.
- in TLSX_KeyShare_Parse() don't call TLSX_KeyShare_Use() because its done in
  TLSX_PopulateExtensions().
- in TLSX_KeyShare_Use(), the server generates the ciphertext while the client
  generates the public key.
- in TLSX_PopulateExtensions(), prevent client from calling TLSX_KeyShare_Use()
  because its already been done.
- Support longer curve/group names.
pull/4433/head
Anthony Hu 2021-09-27 10:29:41 -04:00
parent a4f927999f
commit 0e80923fb3
7 changed files with 385 additions and 45 deletions

View File

@ -7306,12 +7306,16 @@ static int TLSX_KeyShare_ProcessOqs(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
if (ssl->options.side == WOLFSSL_SERVER_END) {
/* I am the server, the shared secret has already been generated and
* is in keyShareEntry->ke; transfer ownership of the buffer. */
if (ssl->arrays->preMasterSecret != NULL)
XFREE(ssl->arrays->preMasterSecret, ssl->heap,
DYNAMIC_TYPE_SECRET);
ssl->arrays->preMasterSecret = keyShareEntry->ke;
* is in keyShareEntry->ke; copy it to the pre-master secret
* pre-allocated buffer. */
if (keyShareEntry->keLen > ENCRYPT_LEN) {
WOLFSSL_MSG("shared secret is too long.\n");
return LENGTH_ERROR;
}
XMEMCPY(ssl->arrays->preMasterSecret, keyShareEntry->ke, keyShareEntry->keLen);
ssl->arrays->preMasterSz = keyShareEntry->keLen;
XFREE(keyShareEntry->ke, sl->heap, DYNAMIC_TYPE_TLSX)
keyShareEntry->ke = NULL;
keyShareEntry->keLen = 0;
return 0;
@ -7404,10 +7408,16 @@ static int TLSX_KeyShare_ProcessOqs(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
}
}
if (sharedSecretLen > ENCRYPT_LEN) {
WOLFSSL_MSG("shared secret is too long.\n");
ret = LENGTH_ERROR;
}
if (ret == 0) {
ssl->arrays->preMasterSecret = sharedSecret;
/* Copy the shared secret to the pre-master secret pre-allocated
* buffer. */
XMEMCPY(ssl->arrays->preMasterSecret, sharedSecret, sharedSecretLen);
ssl->arrays->preMasterSz = (word32) sharedSecretLen;
sharedSecret = NULL;
}
if (sharedSecret != NULL) {
@ -7493,16 +7503,29 @@ static int TLSX_KeyShareEntry_Parse(WOLFSSL* ssl, const byte* input,
if (keLen > length - offset)
return BUFFER_ERROR;
#ifdef HAVE_LIBOQS
if (group >= WOLFSSL_OQS_MIN &&
group <= WOLFSSL_OQS_MAX &&
ssl->options.side == WOLFSSL_SERVER_END) {
/* For KEMs, the public key is not stored. Casting away const because
* we know for KEMs, it will be read-only.*/
ke = (byte *) &input[offset];
} else
#endif
{
/* Store a copy in the key share object. */
ke = (byte*)XMALLOC(keLen, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
if (ke == NULL)
return MEMORY_E;
XMEMCPY(ke, &input[offset], keLen);
}
/* Populate a key share object in the extension. */
ret = TLSX_KeyShare_Use(ssl, group, keLen, ke, kse);
if (ret != 0) {
if (ke != &input[offset]) {
XFREE(ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
return ret;
}
@ -7685,7 +7708,10 @@ static int TLSX_KeyShare_Parse(WOLFSSL* ssl, const byte* input, word16 length,
return ret;
}
/* Try to use the server's group. */
#ifdef HAVE_LIBOQS
/* For oqs groups, do this in TLSX_PopulateExtensions(). */
if (group < WOLFSSL_OQS_MIN || group > WOLFSSL_OQS_MAX)
#endif
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);
}
else {
@ -7923,7 +7949,7 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
return ret;
}
if (data != NULL) {
#ifdef HAVE_LIBOQS
if (group >= WOLFSSL_OQS_MIN &&
group <= WOLFSSL_OQS_MAX &&
@ -7935,14 +7961,13 @@ int TLSX_KeyShare_Use(WOLFSSL* ssl, word16 group, word16 len, byte* data,
}
else
#endif
{
if (data != NULL) {
if (keyShareEntry->ke != NULL) {
XFREE(keyShareEntry->ke, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
}
keyShareEntry->ke = data;
keyShareEntry->keLen = len;
}
}
else {
/* Generate a key pair. */
ret = TLSX_KeyShare_GenKey(ssl, keyShareEntry);
@ -10316,6 +10341,10 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
namedGroup = kse->group;
}
if (namedGroup > 0) {
#ifdef HAVE_LIBOQS
/* For KEMs, the key share has already been generated. */
if (namedGroup < WOLFSSL_OQS_MIN || namedGroup > WOLFSSL_OQS_MAX)
#endif
ret = TLSX_KeyShare_Use(ssl, namedGroup, 0, NULL, NULL);
if (ret != 0)
return ret;

View File

@ -8690,15 +8690,21 @@ int wolfSSL_UseKeyShare(WOLFSSL* ssl, word16 group)
#ifdef HAVE_LIBOQS
if (group >= WOLFSSL_OQS_MIN &&
group <= WOLFSSL_OQS_MAX &&
ssl->options.side == WOLFSSL_SERVER_END) {
group <= WOLFSSL_OQS_MAX) {
if (ssl->ctx != NULL && ssl->ctx->method != NULL &&
ssl->ctx->method->version.minor != TLSv1_3_MINOR) {
return BAD_FUNC_ARG;
}
if (ssl->options.side == WOLFSSL_SERVER_END) {
/* If I am the server of a KEM connection, do not do keygen because I'm
* going to encapsulate with the client's public key. Note that I might
* be the client and ssl->option.side has not been properly set yet. In
* that case the KeyGen operation will be deferred to connection time.
*/
* that case the KeyGen operation will be deferred to connection time. */
return WOLFSSL_SUCCESS;
}
}
#endif
ret = TLSX_KeyShare_Use(ssl, group, 0, NULL, NULL);

View File

@ -44755,7 +44755,13 @@ static int test_tls13_apis(void)
int outSz;
#endif
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
int groups[2] = { WOLFSSL_ECC_SECP256R1, WOLFSSL_ECC_SECP256R1 };
int groups[2] = { WOLFSSL_ECC_SECP256R1,
#ifdef HAVE_LIBOQS
WOLFSSL_SABER_LEVEL3
#else
WOLFSSL_ECC_SECP256R1
#endif
};
int bad_groups[2] = { 0xDEAD, 0xBEEF };
int numGroups = 2;
#endif
@ -44770,6 +44776,12 @@ static int test_tls13_apis(void)
#endif
#if (!defined(NO_ECC256) || defined(HAVE_ALL_CURVES)) && ECC_MIN_KEY_SZ <= 256
"P-256"
#ifdef HAVE_LIBOQS
":P256_SABER_LEVEL1"
#endif
#endif
#ifdef HAVE_LIBOQS
":KYBER_LEVEL1"
#endif
"";
#endif /* !defined(NO_ECC_SECP) */
@ -44872,6 +44884,22 @@ static int test_tls13_apis(void)
AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_ECC_SECP256R1),
NOT_COMPILED_IN);
#endif
#endif
#if defined(HAVE_LIBOQS)
AssertIntEQ(wolfSSL_UseKeyShare(NULL, WOLFSSL_KYBER_LEVEL3), BAD_FUNC_ARG);
#ifndef NO_WOLFSSL_SERVER
AssertIntEQ(wolfSSL_UseKeyShare(serverSsl, WOLFSSL_KYBER_LEVEL3),
WOLFSSL_SUCCESS);
#endif
#ifndef NO_WOLFSSL_CLIENT
#ifndef WOLFSSL_NO_TLS12
AssertIntEQ(wolfSSL_UseKeyShare(clientTls12Ssl, WOLFSSL_KYBER_LEVEL3),
BAD_FUNC_ARG);
#endif
AssertIntEQ(wolfSSL_UseKeyShare(clientSsl, WOLFSSL_KYBER_LEVEL3),
WOLFSSL_SUCCESS);
#endif
#endif
AssertIntEQ(wolfSSL_NoKeyShares(NULL), BAD_FUNC_ARG);

View File

@ -17,13 +17,14 @@ tests_unit_test_CFLAGS = -DNO_MAIN_DRIVER $(AM_CFLAGS) $(WOLFSENTRY_INCLUD
tests_unit_test_LDADD = src/libwolfssl.la $(LIB_STATIC_ADD) $(WOLFSENTRY_LIB)
tests_unit_test_DEPENDENCIES = src/libwolfssl.la
endif
EXTRA_DIST += tests/unit.h
EXTRA_DIST += tests/test.conf \
EXTRA_DIST += tests/unit.h \
tests/test.conf \
tests/test-sha2.conf \
tests/test-tls13.conf \
tests/test-tls13-down.conf \
tests/test-tls13-ecc.conf \
tests/test-tls13-psk.conf \
tests/test-tls13-pq.conf \
tests/test-psk.conf \
tests/test-psk-no-id.conf \
tests/test-psk-no-id-sha2.conf \

View File

@ -867,7 +867,7 @@ int SuiteTest(int argc, char** argv)
}
#endif
#ifndef WOLFSSL_NO_TLS12
/* add TLSv13 downgrade tets */
/* add TLSv13 downgrade tests */
strcpy(argv0[1], "tests/test-tls13-down.conf");
printf("starting TLSv13 Downgrade extra tests\n");
test_harness(&args);
@ -877,6 +877,17 @@ int SuiteTest(int argc, char** argv)
goto exit;
}
#endif
#ifdef HAVE_LIBOQS
/* add TLSv13 pq tests */
strcpy(argv0[1], "tests/test-tls13-pq.conf");
printf("starting TLSv13 post-quantum groups tests\n");
test_harness(&args);
if (args.return_code != 0) {
printf("error from script %d\n", args.return_code);
args.return_code = EXIT_FAILURE;
goto exit;
}
#endif
#endif
#if defined(HAVE_CURVE25519) && defined(HAVE_ED25519) && \
defined(HAVE_ED25519_SIGN) && defined(HAVE_ED25519_VERIFY) && \

View File

@ -0,0 +1,260 @@
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs KYBER_90S_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_NTRU_HPS_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_NTRU_HPS_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_NTRU_HPS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_NTRU_HPS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_NTRU_HPS_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_NTRU_HPS_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_NTRU_HRSS_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_NTRU_HRSS_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_SABER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_SABER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_SABER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_SABER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_SABER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_SABER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_KYBER_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_KYBER_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_KYBER_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_KYBER_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_KYBER_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_KYBER_LEVEL5
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_KYBER_90S_LEVEL1
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P256_KYBER_90S_LEVEL1
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_KYBER_90S_LEVEL3
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P384_KYBER_90S_LEVEL3
# server TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_KYBER_90S_LEVEL5
# client TLSv1.3 with post-quantum group
-v 4
-l TLS13-AES256-GCM-SHA384
--oqs P521_KYBER_90S_LEVEL5

View File

@ -4579,10 +4579,15 @@ typedef struct {
int nid;
} WOLF_EC_NIST_NAME;
extern const WOLF_EC_NIST_NAME kNistCurves[];
/* This is the longest and shortest curve name in the kNistCurves list */
/* This is the longest and shortest curve name in the kNistCurves list. Note we
* also have quantum-safe group names as well. */
#define kNistCurves_MIN_NAME_LEN 5
#ifdef HAVE_LIBOQS
#define kNistCurves_MAX_NAME_LEN 32
#else
#define kNistCurves_MAX_NAME_LEN 7
#endif
#endif
/* internal functions */
WOLFSSL_LOCAL int SendChangeCipher(WOLFSSL*);