Add Curve448, X448, Ed448 implementations

This commit is contained in:
Sean Parkinson
2020-02-19 18:07:45 +10:00
parent c7a2510d97
commit 2c6eb7cb39
79 changed files with 24343 additions and 2390 deletions

View File

@@ -462,6 +462,25 @@ endif
endif
endif
if BUILD_CURVE448
src_libwolfssl_la_SOURCES += wolfcrypt/src/curve448.c
endif
if BUILD_ED448
src_libwolfssl_la_SOURCES += wolfcrypt/src/ed448.c
endif
if BUILD_FE448
src_libwolfssl_la_SOURCES += wolfcrypt/src/fe_448.c
endif
if BUILD_GE448
src_libwolfssl_la_SOURCES += wolfcrypt/src/ge_448.c
if !BUILD_FE448
src_libwolfssl_la_SOURCES += wolfcrypt/src/fe_448.c
endif
endif
if BUILD_LIBZ
src_libwolfssl_la_SOURCES += wolfcrypt/src/compress.c
endif

File diff suppressed because it is too large Load Diff

View File

@@ -241,7 +241,7 @@ int SetCipherSpecs(WOLFSSL* ssl)
switch (ssl->options.cipherSuite) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
#ifdef BUILD_TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 :
@@ -417,9 +417,10 @@ int SetCipherSpecs(WOLFSSL* ssl)
break;
#endif
#endif /* HAVE_ECC || HAVE_CURVE25519 */
#endif /* HAVE_ECC || HAVE_CURVE25519 || HAVE_CURVE448 */
#if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && defined(HAVE_ED25519))
#if defined(HAVE_ECC) || (defined(HAVE_CURVE25519) && defined(HAVE_ED25519)) \
|| (defined(HAVE_CURVE448) && defined(HAVE_ED448))
#ifdef BUILD_TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 :
@@ -630,7 +631,7 @@ int SetCipherSpecs(WOLFSSL* ssl)
break;
#endif
#endif /* HAVE_ECC || (HAVE_CURVE25519 && HAVE_ED25519) */
#endif /* HAVE_ECC || (CURVE25519 && ED25519) || (CURVE448 && ED448) */
#if defined(HAVE_ECC)

604
src/ssl.c
View File

@@ -52,7 +52,7 @@
#if !defined(WOLFSSL_ALLOW_NO_SUITES) && !defined(WOLFCRYPT_ONLY)
#if defined(NO_DH) && !defined(HAVE_ECC) && !defined(WOLFSSL_STATIC_RSA) \
&& !defined(WOLFSSL_STATIC_DH) && !defined(WOLFSSL_STATIC_PSK) \
&& !defined(HAVE_ED25519)
&& !defined(HAVE_ED25519) && !defined(HAVE_ED448)
#error "No cipher suites defined because DH disabled, ECC disabled, and no static suites defined. Please see top of README"
#endif
#ifdef WOLFSSL_CERT_GEN
@@ -87,6 +87,8 @@
#include <wolfssl/openssl/ec.h>
#include <wolfssl/openssl/ec25519.h>
#include <wolfssl/openssl/ed25519.h>
#include <wolfssl/openssl/ec448.h>
#include <wolfssl/openssl/ed448.h>
#include <wolfssl/openssl/ecdsa.h>
#include <wolfssl/openssl/ecdh.h>
#include <wolfssl/openssl/err.h>
@@ -105,6 +107,7 @@
#include <wolfssl/wolfcrypt/idea.h>
#include <wolfssl/wolfcrypt/curve25519.h>
#include <wolfssl/wolfcrypt/ed25519.h>
#include <wolfssl/wolfcrypt/curve448.h>
#if defined(OPENSSL_ALL) || defined(HAVE_STUNNEL)
#include <wolfssl/openssl/ocsp.h>
#endif /* WITH_STUNNEL */
@@ -2344,6 +2347,7 @@ int wolfSSL_UseSupportedCurve(WOLFSSL* ssl, word16 name)
case WOLFSSL_ECC_BRAINPOOLP384R1:
case WOLFSSL_ECC_BRAINPOOLP512R1:
case WOLFSSL_ECC_X25519:
case WOLFSSL_ECC_X448:
case WOLFSSL_FFDHE_2048:
case WOLFSSL_FFDHE_3072:
@@ -2383,6 +2387,7 @@ int wolfSSL_CTX_UseSupportedCurve(WOLFSSL_CTX* ctx, word16 name)
case WOLFSSL_ECC_BRAINPOOLP384R1:
case WOLFSSL_ECC_BRAINPOOLP512R1:
case WOLFSSL_ECC_X25519:
case WOLFSSL_ECC_X448:
case WOLFSSL_FFDHE_2048:
case WOLFSSL_FFDHE_3072:
case WOLFSSL_FFDHE_4096:
@@ -5069,6 +5074,15 @@ int AddCA(WOLFSSL_CERT_MANAGER* cm, DerBuffer** pDer, int type, int verify)
}
break;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case ED448k:
if (cm->minEccKeySz < 0 ||
ED448_KEY_SIZE < (word16)cm->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("\tCA ECC key size error");
}
break;
#endif /* HAVE_ED448 */
default:
WOLFSSL_MSG("\tNo key size check done on CA");
@@ -5510,8 +5524,10 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
*idx = 0;
if (wc_RsaPrivateKeyDecode(der->buffer, idx, key, der->length)
!= 0) {
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519)
WOLFSSL_MSG("RSA decode failed and ECC/ED25519 not enabled to try");
#if !defined(HAVE_ECC) && !defined(HAVE_ED25519) && \
!defined(HAVE_ED448)
WOLFSSL_MSG("RSA decode failed and ECC/ED25519/ED448 not "
"enabled to try");
ret = WOLFSSL_BAD_FILE;
#endif
}
@@ -5623,11 +5639,7 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
if (ret == 0) {
*idx = 0;
if (wc_Ed25519PrivateKeyDecode(der->buffer, idx, key,
der->length) != 0) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
der->length) == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
ctx->minEccKeySz;
@@ -5636,20 +5648,20 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
WOLFSSL_MSG("ED25519 private key too small");
ret = ECC_KEY_SIZE_E;
}
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed25519_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed25519_sa_algo;
ctx->privateKeySz = *keySz;
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed25519_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed25519_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED25519k;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
*keyFormat = ED25519k;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
}
@@ -5661,6 +5673,63 @@ static int ProcessBufferTryDecode(WOLFSSL_CTX* ctx, WOLFSSL* ssl, DerBuffer* der
#endif
}
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
if (ret == 0 && (*keyFormat == 0 || *keyFormat == ED448k)) {
/* make sure Ed448 key can be used */
#ifdef WOLFSSL_SMALL_STACK
ed448_key* key = NULL;
#else
ed448_key key[1];
#endif
#ifdef WOLFSSL_SMALL_STACK
key = (ed448_key*)XMALLOC(sizeof(ed448_key), heap, DYNAMIC_TYPE_ED448);
if (key == NULL)
return MEMORY_E;
#endif
ret = wc_ed448_init(key);
if (ret == 0) {
*idx = 0;
if (wc_Ed448PrivateKeyDecode(der->buffer, idx, key,
der->length) != 0) {
ret = WOLFSSL_BAD_FILE;
}
if (ret == 0) {
/* check for minimum key size and then free */
int minKeySz = ssl ? ssl->options.minEccKeySz :
ctx->minEccKeySz;
*keySz = ED448_KEY_SIZE;
if (*keySz < minKeySz) {
WOLFSSL_MSG("ED448 private key too small");
ret = ECC_KEY_SIZE_E;
}
}
if (ret == 0) {
if (ssl) {
ssl->buffers.keyType = ed448_sa_algo;
ssl->buffers.keySz = *keySz;
}
else if (ctx) {
ctx->privateKeyType = ed448_sa_algo;
ctx->privateKeySz = *keySz;
}
*keyFormat = ED448k;
if (ssl && ssl->options.side == WOLFSSL_SERVER_END) {
*resetSuites = 1;
}
}
wc_ed448_free(key);
}
#ifdef WOLFSSL_SMALL_STACK
XFREE(key, heap, DYNAMIC_TYPE_ED448);
#endif
}
#endif /* HAVE_ED448 */
return ret;
}
@@ -5997,12 +6066,19 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
else if (ctx)
ctx->haveECDSAsig = 1;
break;
case CTC_ED448:
WOLFSSL_MSG("ED448 cert signature");
if (ssl)
ssl->options.haveECDSAsig = 1;
else if (ctx)
ctx->haveECDSAsig = 1;
break;
default:
WOLFSSL_MSG("Not ECDSA cert signature");
break;
}
#if defined(HAVE_ECC) || defined(HAVE_ED25519)
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
if (ssl) {
ssl->pkCurveOID = cert->pkCurveOID;
#ifndef WC_STRICT_SIG
@@ -6014,6 +6090,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ssl->options.haveECC = 1;
}
#endif
#ifdef HAVE_ED448
else if (cert->keyOID == ED448k) {
ssl->options.haveECC = 1;
}
#endif
#else
ssl->options.haveECC = ssl->options.haveECDSAsig;
#endif
@@ -6029,6 +6110,11 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
ctx->haveECC = 1;
}
#endif
#ifdef HAVE_ED448
else if (cert->keyOID == ED448k) {
ctx->haveECC = 1;
}
#endif
#else
ctx->haveECC = ctx->haveECDSAsig;
#endif
@@ -6137,6 +6223,37 @@ int ProcessBuffer(WOLFSSL_CTX* ctx, const unsigned char* buff,
}
break;
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
case ED448k:
#ifdef HAVE_PK_CALLBACKS
keyType = ed448_sa_algo;
#endif
#ifdef HAVE_PKCS11
if (ctx) {
ctx->privateKeyType = ed448_sa_algo;
}
else {
ssl->buffers.keyType = ed448_sa_algo;
}
#endif
/* ED448 is fixed key size */
keySz = ED448_KEY_SIZE;
if (ssl && !ssl->options.verifyNone) {
if (ssl->options.minEccKeySz < 0 ||
keySz < (int)ssl->options.minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("Certificate Ed key size error");
}
}
else if (ctx && !ctx->verifyNone) {
if (ctx->minEccKeySz < 0 ||
keySz < (int)ctx->minEccKeySz) {
ret = ECC_KEY_SIZE_E;
WOLFSSL_MSG("Certificate ECC key size error");
}
}
break;
#endif /* HAVE_ED448 */
default:
WOLFSSL_MSG("No key size check done on certificate");
@@ -22427,7 +22544,8 @@ void wolfSSL_sk_CIPHER_free(WOLF_STACK_OF(WOLFSSL_CIPHER)* sk)
}
#endif
#if defined(HAVE_ECC) || !defined(NO_DH)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448) || \
!defined(NO_DH)
#ifdef HAVE_FFDHE
static const char* wolfssl_ffdhe_name(word16 group)
{
@@ -22476,6 +22594,12 @@ const char* wolfSSL_get_curve_name(WOLFSSL* ssl)
}
#endif
#ifdef HAVE_CURVE448
if (ssl->ecdhCurveOID == ECC_X448_OID && cName == NULL) {
cName = "X448";
}
#endif
#ifdef HAVE_ECC
if (ssl->ecdhCurveOID != 0 && cName == NULL) {
cName = wc_ecc_get_name(wc_ecc_get_oid(ssl->ecdhCurveOID, NULL,
@@ -33444,22 +33568,22 @@ int wolfSSL_EVP_PKEY_assign(WOLFSSL_EVP_PKEY *pkey, int type, void *key)
switch(type) {
#ifndef NO_RSA
case EVP_PKEY_RSA:
ret = wolfSSL_EVP_PKEY_assign_RSA(pkey,key);
ret = wolfSSL_EVP_PKEY_assign_RSA(pkey, (WOLFSSL_RSA*)key);
break;
#endif
#ifndef NO_DSA
case EVP_PKEY_DSA:
ret = wolfSSL_EVP_PKEY_assign_DSA(pkey, key);
ret = wolfSSL_EVP_PKEY_assign_DSA(pkey, (WOLFSSL_DSA*)key);
break;
#endif
#ifdef HAVE_ECC
case EVP_PKEY_EC:
ret = wolfSSL_EVP_PKEY_assign_EC_KEY(pkey,key);
ret = wolfSSL_EVP_PKEY_assign_EC_KEY(pkey, (WOLFSSL_EC_KEY*)key);
break;
#endif
#ifdef NO_DH
case EVP_PKEY_DH:
ret = wolfSSL_EVP_PKEY_assign_DH(pkey,key);
ret = wolfSSL_EVP_PKEY_assign_DH(pkey, (WOLFSSL_DH*)key);
break;
#endif
default:
@@ -38720,6 +38844,84 @@ void* wolfSSL_GetX25519SharedSecretCtx(WOLFSSL* ssl)
}
#endif /* HAVE_CURVE25519 */
#ifdef HAVE_ED448
void wolfSSL_CTX_SetEd448SignCb(WOLFSSL_CTX* ctx, CallbackEd448Sign cb)
{
if (ctx)
ctx->Ed448SignCb = cb;
}
void wolfSSL_SetEd448SignCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->Ed448SignCtx = ctx;
}
void* wolfSSL_GetEd448SignCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->Ed448SignCtx;
return NULL;
}
void wolfSSL_CTX_SetEd448VerifyCb(WOLFSSL_CTX* ctx, CallbackEd448Verify cb)
{
if (ctx)
ctx->Ed448VerifyCb = cb;
}
void wolfSSL_SetEd448VerifyCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->Ed448VerifyCtx = ctx;
}
void* wolfSSL_GetEd448VerifyCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->Ed448VerifyCtx;
return NULL;
}
#endif /* HAVE_ED448 */
#ifdef HAVE_CURVE448
void wolfSSL_CTX_SetX448KeyGenCb(WOLFSSL_CTX* ctx,
CallbackX448KeyGen cb)
{
if (ctx)
ctx->X448KeyGenCb = cb;
}
void wolfSSL_SetX448KeyGenCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->X448KeyGenCtx = ctx;
}
void* wolfSSL_GetX448KeyGenCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->X448KeyGenCtx;
return NULL;
}
void wolfSSL_CTX_SetX448SharedSecretCb(WOLFSSL_CTX* ctx,
CallbackX448SharedSecret cb)
{
if (ctx)
ctx->X448SharedSecretCb = cb;
}
void wolfSSL_SetX448SharedSecretCtx(WOLFSSL* ssl, void *ctx)
{
if (ssl)
ssl->X448SharedSecretCtx = ctx;
}
void* wolfSSL_GetX448SharedSecretCtx(WOLFSSL* ssl)
{
if (ssl)
return ssl->X448SharedSecretCtx;
return NULL;
}
#endif /* HAVE_CURVE448 */
#ifndef NO_RSA
void wolfSSL_CTX_SetRsaSignCb(WOLFSSL_CTX* ctx, CallbackRsaSign cb)
{
@@ -41581,12 +41783,15 @@ err:
break;
#ifdef HAVE_ED25519
case ED25519k:
#endif
#ifdef HAVE_ED448
case ED448k:
#endif
case ECDSAk:
ctx->haveECC = 1;
#if defined(HAVE_ECC) || defined(HAVE_ED25519)
#if defined(HAVE_ECC) || defined(HAVE_ED25519) || defined(HAVE_ED448)
ctx->pkCurveOID = x->pkCurveOID;
#endif
#endif
break;
}
@@ -43437,7 +43642,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
ret = WOLFSSL_FAILURE;
break;
}
return wolfSSL_CTX_add_extra_chain_cert(ctx,pt);
return wolfSSL_CTX_add_extra_chain_cert(ctx, (WOLFSSL_X509*)pt);
#ifndef NO_DH
case SSL_CTRL_SET_TMP_DH:
@@ -43447,7 +43652,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
ret = WOLFSSL_FAILURE;
break;
}
return wolfSSL_CTX_set_tmp_dh(ctx, pt);
return wolfSSL_CTX_set_tmp_dh(ctx, (WOLFSSL_DH*)pt);
#endif
#ifdef HAVE_ECC
@@ -43458,7 +43663,7 @@ long wolfSSL_CTX_ctrl(WOLFSSL_CTX* ctx, int cmd, long opt, void* pt)
ret = WOLFSSL_FAILURE;
break;
}
return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx,pt);
return wolfSSL_SSL_CTX_set_tmp_ecdh(ctx, (WOLFSSL_EC_KEY*)pt);
#endif
case SSL_CTRL_MODE:
wolfSSL_CTX_set_mode(ctx,opt);
@@ -45456,6 +45661,338 @@ int wolfSSL_ED25519_verify(const unsigned char *msg, unsigned int msgSz,
#endif /* OPENSSL_EXTRA && HAVE_ED25519 */
#if defined(OPENSSL_EXTRA) && defined(HAVE_CURVE448)
/* return 1 if success, 0 if error
* output keys are little endian format
*/
int wolfSSL_EC448_generate_key(unsigned char *priv, unsigned int *privSz,
unsigned char *pub, unsigned int *pubSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
(void) priv;
(void) privSz;
(void) pub;
(void) pubSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
int ret = WOLFSSL_FAILURE;
int initTmpRng = 0;
WC_RNG *rng = NULL;
#ifdef WOLFSSL_SMALL_STACK
WC_RNG *tmpRNG = NULL;
#else
WC_RNG tmpRNG[1];
#endif
WOLFSSL_ENTER("wolfSSL_EC448_generate_key");
if (priv == NULL || privSz == NULL || *privSz < CURVE448_KEY_SIZE ||
pub == NULL || pubSz == NULL || *pubSz < CURVE448_KEY_SIZE) {
WOLFSSL_MSG("Bad arguments");
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_SMALL_STACK
tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG == NULL)
return WOLFSSL_FAILURE;
#endif
if (wc_InitRng(tmpRNG) == 0) {
rng = tmpRNG;
initTmpRng = 1;
}
else {
WOLFSSL_MSG("Bad RNG Init, trying global");
if (initGlobalRNG == 0)
WOLFSSL_MSG("Global RNG no Init");
else
rng = &globalRNG;
}
if (rng) {
curve448_key key;
if (wc_curve448_init(&key) != MP_OKAY)
WOLFSSL_MSG("wc_curve448_init failed");
else if (wc_curve448_make_key(rng, CURVE448_KEY_SIZE, &key)!=MP_OKAY)
WOLFSSL_MSG("wc_curve448_make_key failed");
/* export key pair */
else if (wc_curve448_export_key_raw_ex(&key, priv, privSz, pub, pubSz,
EC448_LITTLE_ENDIAN)
!= MP_OKAY)
WOLFSSL_MSG("wc_curve448_export_key_raw_ex failed");
else
ret = WOLFSSL_SUCCESS;
wc_curve448_free(&key);
}
if (initTmpRng)
wc_FreeRng(tmpRNG);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
#endif
return ret;
#endif /* WOLFSSL_KEY_GEN */
}
/* return 1 if success, 0 if error
* input and output keys are little endian format
*/
int wolfSSL_EC448_shared_key(unsigned char *shared, unsigned int *sharedSz,
const unsigned char *priv, unsigned int privSz,
const unsigned char *pub, unsigned int pubSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
(void) shared;
(void) sharedSz;
(void) priv;
(void) privSz;
(void) pub;
(void) pubSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
int ret = WOLFSSL_FAILURE;
curve448_key privkey, pubkey;
WOLFSSL_ENTER("wolfSSL_EC448_shared_key");
if (shared == NULL || sharedSz == NULL || *sharedSz < CURVE448_KEY_SIZE ||
priv == NULL || privSz < CURVE448_KEY_SIZE ||
pub == NULL || pubSz < CURVE448_KEY_SIZE) {
WOLFSSL_MSG("Bad arguments");
return WOLFSSL_FAILURE;
}
/* import private key */
if (wc_curve448_init(&privkey) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_init privkey failed");
return ret;
}
if (wc_curve448_import_private_ex(priv, privSz, &privkey,
EC448_LITTLE_ENDIAN) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_import_private_ex failed");
wc_curve448_free(&privkey);
return ret;
}
/* import public key */
if (wc_curve448_init(&pubkey) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_init pubkey failed");
wc_curve448_free(&privkey);
return ret;
}
if (wc_curve448_import_public_ex(pub, pubSz, &pubkey,
EC448_LITTLE_ENDIAN) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_import_public_ex failed");
wc_curve448_free(&privkey);
wc_curve448_free(&pubkey);
return ret;
}
if (wc_curve448_shared_secret_ex(&privkey, &pubkey, shared, sharedSz,
EC448_LITTLE_ENDIAN) != MP_OKAY)
WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
else
ret = WOLFSSL_SUCCESS;
wc_curve448_free(&privkey);
wc_curve448_free(&pubkey);
return ret;
#endif /* WOLFSSL_KEY_GEN */
}
#endif /* OPENSSL_EXTRA && HAVE_CURVE448 */
#if defined(OPENSSL_EXTRA) && defined(HAVE_ED448)
/* return 1 if success, 0 if error
* output keys are little endian format
*/
int wolfSSL_ED448_generate_key(unsigned char *priv, unsigned int *privSz,
unsigned char *pub, unsigned int *pubSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
(void) priv;
(void) privSz;
(void) pub;
(void) pubSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
int ret = WOLFSSL_FAILURE;
int initTmpRng = 0;
WC_RNG *rng = NULL;
#ifdef WOLFSSL_SMALL_STACK
WC_RNG *tmpRNG = NULL;
#else
WC_RNG tmpRNG[1];
#endif
WOLFSSL_ENTER("wolfSSL_ED448_generate_key");
if (priv == NULL || privSz == NULL || *privSz < ED448_PRV_KEY_SIZE ||
pub == NULL || pubSz == NULL || *pubSz < ED448_PUB_KEY_SIZE) {
WOLFSSL_MSG("Bad arguments");
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_SMALL_STACK
tmpRNG = (WC_RNG*)XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG);
if (tmpRNG == NULL)
return WOLFSSL_FATAL_ERROR;
#endif
if (wc_InitRng(tmpRNG) == 0) {
rng = tmpRNG;
initTmpRng = 1;
}
else {
WOLFSSL_MSG("Bad RNG Init, trying global");
if (initGlobalRNG == 0)
WOLFSSL_MSG("Global RNG no Init");
else
rng = &globalRNG;
}
if (rng) {
ed448_key key;
if (wc_ed448_init(&key) != MP_OKAY)
WOLFSSL_MSG("wc_ed448_init failed");
else if (wc_ed448_make_key(rng, ED448_KEY_SIZE, &key) != MP_OKAY)
WOLFSSL_MSG("wc_ed448_make_key failed");
/* export private key */
else if (wc_ed448_export_key(&key, priv, privSz, pub, pubSz) != MP_OKAY)
WOLFSSL_MSG("wc_ed448_export_key failed");
else
ret = WOLFSSL_SUCCESS;
wc_ed448_free(&key);
}
if (initTmpRng)
wc_FreeRng(tmpRNG);
#ifdef WOLFSSL_SMALL_STACK
XFREE(tmpRNG, NULL, DYNAMIC_TYPE_RNG);
#endif
return ret;
#endif /* WOLFSSL_KEY_GEN */
}
/* return 1 if success, 0 if error
* input and output keys are little endian format
* priv is a buffer containing private and public part of key
*/
int wolfSSL_ED448_sign(const unsigned char *msg, unsigned int msgSz,
const unsigned char *priv, unsigned int privSz,
unsigned char *sig, unsigned int *sigSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
(void) msg;
(void) msgSz;
(void) priv;
(void) privSz;
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
ed448_key key;
int ret = WOLFSSL_FAILURE;
WOLFSSL_ENTER("wolfSSL_ED448_sign");
if (priv == NULL || privSz != ED448_PRV_KEY_SIZE || msg == NULL ||
sig == NULL || *sigSz < ED448_SIG_SIZE) {
WOLFSSL_MSG("Bad arguments");
return WOLFSSL_FAILURE;
}
/* import key */
if (wc_ed448_init(&key) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_init failed");
return ret;
}
if (wc_ed448_import_private_key(priv, privSz/2, priv+(privSz/2),
ED448_PUB_KEY_SIZE, &key) != MP_OKAY){
WOLFSSL_MSG("wc_ed448_import_private failed");
wc_ed448_free(&key);
return ret;
}
if (wc_ed448_sign_msg(msg, msgSz, sig, sigSz, &key) != MP_OKAY)
WOLFSSL_MSG("wc_curve448_shared_secret_ex failed");
else
ret = WOLFSSL_SUCCESS;
wc_ed448_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
}
/* return 1 if success, 0 if error
* input and output keys are little endian format
* pub is a buffer containing public part of key
*/
int wolfSSL_ED448_verify(const unsigned char *msg, unsigned int msgSz,
const unsigned char *pub, unsigned int pubSz,
const unsigned char *sig, unsigned int sigSz)
{
#ifndef WOLFSSL_KEY_GEN
WOLFSSL_MSG("No Key Gen built in");
(void) msg;
(void) msgSz;
(void) pub;
(void) pubSz;
(void) sig;
(void) sigSz;
return WOLFSSL_FAILURE;
#else /* WOLFSSL_KEY_GEN */
ed448_key key;
int ret = WOLFSSL_FAILURE, check = 0;
WOLFSSL_ENTER("wolfSSL_ED448_verify");
if (pub == NULL || pubSz != ED448_PUB_KEY_SIZE || msg == NULL ||
sig == NULL || sigSz != ED448_SIG_SIZE) {
WOLFSSL_MSG("Bad arguments");
return WOLFSSL_FAILURE;
}
/* import key */
if (wc_ed448_init(&key) != MP_OKAY) {
WOLFSSL_MSG("wc_curve448_init failed");
return ret;
}
if (wc_ed448_import_public(pub, pubSz, &key) != MP_OKAY){
WOLFSSL_MSG("wc_ed448_import_public failed");
wc_ed448_free(&key);
return ret;
}
if ((ret = wc_ed448_verify_msg((byte*)sig, sigSz, msg, msgSz, &check,
&key)) != MP_OKAY) {
WOLFSSL_MSG("wc_ed448_verify_msg failed");
}
else if (!check)
WOLFSSL_MSG("wc_ed448_verify_msg failed (signature invalid)");
else
ret = WOLFSSL_SUCCESS;
wc_ed448_free(&key);
return ret;
#endif /* WOLFSSL_KEY_GEN */
}
#endif /* OPENSSL_EXTRA && HAVE_ED448 */
#ifdef WOLFSSL_JNI
int wolfSSL_set_jobject(WOLFSSL* ssl, void* objPtr)
@@ -46490,6 +47027,9 @@ int wolfSSL_CTX_set1_curves_list(WOLFSSL_CTX* ctx, const char* names)
else if (XSTRNCMP(name, "X25519", len) == 0) {
curve = WOLFSSL_ECC_X25519;
}
else if (XSTRNCMP(name, "X448", len) == 0) {
curve = WOLFSSL_ECC_X448;
}
else {
#if !defined(HAVE_FIPS) && !defined(HAVE_SELFTEST)
int ret;

271
src/tls.c
View File

@@ -43,7 +43,9 @@
#ifdef HAVE_CURVE25519
#include <wolfssl/wolfcrypt/curve25519.h>
#endif
#ifdef HAVE_CURVE448
#include <wolfssl/wolfcrypt/curve448.h>
#endif
#ifdef HAVE_NTRU
#include "libntruencrypt/ntru_crypto.h"
#include <wolfssl/wolfcrypt/random.h>
@@ -65,10 +67,10 @@ static int TLSX_KeyShare_IsSupported(int namedGroup);
#if ((!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
(defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \
!defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \
((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
defined(HAVE_SUPPORTED_CURVES))) && \
(defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
&& !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))) && \
defined(HAVE_TLS_EXTENSIONS)
static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions);
#endif
@@ -3696,7 +3698,8 @@ int TLSX_UseCertificateStatusRequestV2(TLSX** extensions, byte status_type,
#ifdef HAVE_SUPPORTED_CURVES
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_FFDHE)
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && !defined(HAVE_CURVE448) \
&& !defined(HAVE_FFDHE)
#error Elliptic Curves Extension requires Elliptic Curve Cryptography. \
Use --enable-ecc in the configure script or define HAVE_ECC. \
Alternatively use FFDHE for DH ciperhsuites.
@@ -3815,7 +3818,8 @@ static void TLSX_SupportedCurve_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
return;
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)
return;
#endif
}
@@ -3839,7 +3843,8 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
return;
if (ssl->suites->suites[i] == ECC_BYTE ||
ssl->suites->suites[i] == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)
return;
#endif
}
@@ -3860,7 +3865,8 @@ static void TLSX_PointFormat_ValidateRequest(WOLFSSL* ssl, byte* semaphore)
static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
{
#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_FFDHE) || defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)
(void)semaphore;
#endif
@@ -3868,7 +3874,7 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
return;
if (ssl->options.cipherSuite0 == ECC_BYTE ||
ssl->options.cipherSuite0 == CHACHA_BYTE) {
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
return;
#endif
}
@@ -3878,7 +3884,8 @@ static void TLSX_PointFormat_ValidateResponse(WOLFSSL* ssl, byte* semaphore)
#endif
}
#if !defined(HAVE_FFDHE) || (!defined(HAVE_ECC) && !defined(HAVE_CURVE25519))
#if !defined(HAVE_FFDHE) || (!defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
&& !defined(HAVE_CURVE448))
/* turns semaphore on to avoid sending this extension. */
TURN_ON(semaphore, TLSX_ToSemaphore(TLSX_EC_POINT_FORMATS));
#endif
@@ -4244,7 +4251,7 @@ static int TLSX_PointFormat_Parse(WOLFSSL* ssl, byte* input, word16 length,
return 0;
}
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if defined(HAVE_ECC) || defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
TLSX* extension = NULL;
SupportedCurve* curve = NULL;
@@ -4273,7 +4280,7 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
#ifdef OPENSSL_EXTRA
/* skip if name is not in supported ECC range */
if (curve->name > WOLFSSL_ECC_X25519)
if (curve->name > WOLFSSL_ECC_X448)
continue;
/* skip if curve is disabled by user */
if (ssl->ctx->disabledCurves & (1 << curve->name))
@@ -4366,6 +4373,19 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
break;
#endif /* HAVE_ECC_BRAINPOOL */
#endif
#endif
#ifdef HAVE_CURVE448
case WOLFSSL_ECC_X448:
oid = ECC_X448_OID;
#ifdef HAVE_ED448
pkOid = ECC_ED448_OID;
#else
pkOid = ECC_X448_OID;
#endif
octets = 57;
break;
#endif /* HAVE_CURVE448 */
#ifdef HAVE_ECC
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP384R1:
@@ -4460,6 +4480,10 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
defOid = 0;
defSz = 80;
}
if (oid == ECC_X448_OID && defOid == oid) {
defOid = 0;
defSz = 80;
}
sig |= ssl->pkCurveOID == pkOid;
key |= ssl->pkCurveOID == oid;
break;
@@ -4493,6 +4517,10 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
defOid = 0;
defSz = 80;
}
if (oid == ECC_X448_OID && defOid == oid) {
defOid = 0;
defSz = 80;
}
sig = 1;
key |= ssl->pkCurveOID == pkOid;
break;
@@ -4503,8 +4531,13 @@ int TLSX_ValidateSupportedCurves(WOLFSSL* ssl, byte first, byte second) {
defOid = 0;
defSz = 80;
}
if (oid != ECC_X25519_OID)
if (oid == ECC_X448_OID && defOid == oid) {
defOid = 0;
defSz = 80;
}
if (oid != ECC_X25519_OID && oid != ECC_X448_OID) {
sig = 1;
}
key = 1;
break;
}
@@ -6667,8 +6700,8 @@ static int TLSX_KeyShare_GenX25519Key(WOLFSSL *ssl, KeyShareEntry* kse)
curve25519_key* key;
/* Allocate an ECC key to hold private key. */
key = (curve25519_key*)XMALLOC(sizeof(curve25519_key),
ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
key = (curve25519_key*)XMALLOC(sizeof(curve25519_key), ssl->heap,
DYNAMIC_TYPE_PRIVATE_KEY);
if (key == NULL) {
WOLFSSL_MSG("EccTempKey Memory error");
return MEMORY_E;
@@ -6725,6 +6758,80 @@ end:
return ret;
}
/* Create a key share entry using X448 parameters group.
* Generates a key pair.
*
* ssl The SSL/TLS object.
* kse The key share entry object.
* returns 0 on success, otherwise failure.
*/
static int TLSX_KeyShare_GenX448Key(WOLFSSL *ssl, KeyShareEntry* kse)
{
int ret;
#ifdef HAVE_CURVE448
byte* keyData = NULL;
word32 dataSize = CURVE448_KEY_SIZE;
curve448_key* key;
/* Allocate an ECC key to hold private key. */
key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
DYNAMIC_TYPE_PRIVATE_KEY);
if (key == NULL) {
WOLFSSL_MSG("EccTempKey Memory error");
return MEMORY_E;
}
/* Make an ECC key. */
ret = wc_curve448_init(key);
if (ret != 0)
goto end;
ret = wc_curve448_make_key(ssl->rng, CURVE448_KEY_SIZE, key);
if (ret != 0)
goto end;
/* Allocate space for the public key. */
keyData = (byte*)XMALLOC(CURVE448_KEY_SIZE, ssl->heap,
DYNAMIC_TYPE_PUBLIC_KEY);
if (keyData == NULL) {
WOLFSSL_MSG("Key data Memory error");
ret = MEMORY_E;
goto end;
}
/* Export public key. */
if (wc_curve448_export_public_ex(key, keyData, &dataSize,
EC448_LITTLE_ENDIAN) != 0) {
ret = ECC_EXPORT_ERROR;
goto end;
}
kse->pubKey = keyData;
kse->pubKeyLen = CURVE448_KEY_SIZE;
kse->key = key;
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Public Curve448 Key");
WOLFSSL_BUFFER(keyData, dataSize);
#endif
end:
if (ret != 0) {
/* Data owned by key share entry otherwise. */
if (keyData != NULL)
XFREE(keyData, ssl->heap, DYNAMIC_TYPE_PUBLIC_KEY);
wc_curve448_free(key);
XFREE(key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
}
#else
(void)ssl;
(void)kse;
ret = NOT_COMPILED_IN;
#endif /* HAVE_CURVE448 */
return ret;
}
/* Create a key share entry using named elliptic curve parameters group.
* Generates a key pair.
*
@@ -6859,6 +6966,8 @@ static int TLSX_KeyShare_GenKey(WOLFSSL *ssl, KeyShareEntry *kse)
return TLSX_KeyShare_GenDhKey(ssl, kse);
if (kse->group == WOLFSSL_ECC_X25519)
return TLSX_KeyShare_GenX25519Key(ssl, kse);
if (kse->group == WOLFSSL_ECC_X448)
return TLSX_KeyShare_GenX448Key(ssl, kse);
return TLSX_KeyShare_GenEccKey(ssl, kse);
}
@@ -6877,6 +6986,11 @@ static void TLSX_KeyShare_FreeAll(KeyShareEntry* list, void* heap)
if (current->group == WOLFSSL_ECC_X25519) {
#ifdef HAVE_CURVE25519
wc_curve25519_free((curve25519_key*)current->key);
#endif
}
else if (current->group == WOLFSSL_ECC_X448) {
#ifdef HAVE_CURVE448
wc_curve448_free((curve448_key*)current->key);
#endif
}
else {
@@ -7179,6 +7293,82 @@ static int TLSX_KeyShare_ProcessX25519(WOLFSSL* ssl,
return ret;
}
/* Process the X448 key share extension on the client side.
*
* ssl The SSL/TLS object.
* keyShareEntry The key share entry object to use to calculate shared secret.
* returns 0 on success and other values indicate failure.
*/
static int TLSX_KeyShare_ProcessX448(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
{
int ret;
#ifdef HAVE_CURVE448
curve448_key* key = (curve448_key*)keyShareEntry->key;
curve448_key* peerX448Key;
#ifdef HAVE_ECC
if (ssl->peerEccKey != NULL) {
wc_ecc_free(ssl->peerEccKey);
ssl->peerEccKey = NULL;
}
#endif
peerX448Key = (curve448_key*)XMALLOC(sizeof(curve448_key), ssl->heap,
DYNAMIC_TYPE_TLSX);
if (peerX448Key == NULL) {
WOLFSSL_MSG("PeerEccKey Memory error");
return MEMORY_ERROR;
}
ret = wc_curve448_init(peerX448Key);
if (ret != 0) {
XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
return ret;
}
#ifdef WOLFSSL_DEBUG_TLS
WOLFSSL_MSG("Peer Curve448 Key");
WOLFSSL_BUFFER(keyShareEntry->ke, keyShareEntry->keLen);
#endif
if (wc_curve448_check_public(keyShareEntry->ke, keyShareEntry->keLen,
EC448_LITTLE_ENDIAN) != 0) {
ret = ECC_PEERKEY_ERROR;
}
if (ret == 0) {
if (wc_curve448_import_public_ex(keyShareEntry->ke,
keyShareEntry->keLen, peerX448Key,
EC448_LITTLE_ENDIAN) != 0) {
ret = ECC_PEERKEY_ERROR;
}
}
if (ret == 0) {
ssl->ecdhCurveOID = ECC_X448_OID;
ret = wc_curve448_shared_secret_ex(key, peerX448Key,
ssl->arrays->preMasterSecret,
&ssl->arrays->preMasterSz,
EC448_LITTLE_ENDIAN);
}
wc_curve448_free(peerX448Key);
XFREE(peerX448Key, ssl->heap, DYNAMIC_TYPE_TLSX);
wc_curve448_free((curve448_key*)keyShareEntry->key);
if (keyShareEntry->key != NULL) {
XFREE(keyShareEntry->key, ssl->heap, DYNAMIC_TYPE_PRIVATE_KEY);
keyShareEntry->key = NULL;
}
#else
(void)ssl;
(void)keyShareEntry;
ret = PEER_KEY_ERROR;
#endif /* HAVE_CURVE448 */
return ret;
}
/* Process the ECC key share extension on the client side.
*
* ssl The SSL/TLS object.
@@ -7306,6 +7496,8 @@ static int TLSX_KeyShare_Process(WOLFSSL* ssl, KeyShareEntry* keyShareEntry)
ret = TLSX_KeyShare_ProcessDh(ssl, keyShareEntry);
else if (keyShareEntry->group == WOLFSSL_ECC_X25519)
ret = TLSX_KeyShare_ProcessX25519(ssl, keyShareEntry);
else if (keyShareEntry->group == WOLFSSL_ECC_X448)
ret = TLSX_KeyShare_ProcessX448(ssl, keyShareEntry);
else
ret = TLSX_KeyShare_ProcessEcc(ssl, keyShareEntry);
@@ -7703,6 +7895,10 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
case WOLFSSL_ECC_X25519:
break;
#endif
#ifdef HAVE_CURVE448
case WOLFSSL_ECC_X448:
break;
#endif
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
case WOLFSSL_ECC_SECP384R1:
@@ -7714,10 +7910,6 @@ static int TLSX_KeyShare_IsSupported(int namedGroup)
case WOLFSSL_ECC_SECP521R1:
break;
#endif /* !NO_ECC_SECP */
#endif
#ifdef HAVE_X448
case WOLFSSL_ECC_X448:
break;
#endif
default:
return 0;
@@ -7751,6 +7943,11 @@ static int TLSX_KeyShare_GroupRank(WOLFSSL* ssl, int group)
ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X25519;
#endif
#endif
#ifndef HAVE_FIPS
#if defined(HAVE_CURVE448)
ssl->group[ssl->numGroups++] = WOLFSSL_ECC_X448;
#endif
#endif
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
#if defined(HAVE_ECC384) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
@@ -9526,10 +9723,10 @@ static byte* TLSX_QSHKeyFind_Pub(QSHKey* qsh, word16* pubLen, word16 name)
#if (!defined(NO_WOLFSSL_SERVER) && defined(WOLFSSL_TLS13) && \
!defined(WOLFSSL_NO_SERVER_GROUPS_EXT)) || \
(defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && \
!defined(HAVE_CURVE25519) && defined(HAVE_SUPPORTED_CURVES)) || \
((defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
defined(HAVE_SUPPORTED_CURVES))
(defined(WOLFSSL_TLS13) && !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) \
&& !defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)) || \
((defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES))
/* Populates the default supported groups / curves */
static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
@@ -9583,6 +9780,17 @@ static int TLSX_PopulateSupportedGroups(WOLFSSL* ssl, TLSX** extensions)
if (ret != WOLFSSL_SUCCESS) return ret;
#endif
#endif
#endif /* HAVE_ECC && HAVE_SUPPORTED_CURVES */
#ifndef HAVE_FIPS
#if defined(HAVE_CURVE448)
ret = TLSX_UseSupportedCurve(extensions,
WOLFSSL_ECC_X448, ssl->heap);
if (ret != WOLFSSL_SUCCESS) return ret;
#endif
#endif /* HAVE_FIPS */
#if defined(HAVE_ECC) && defined(HAVE_SUPPORTED_CURVES)
#if !defined(NO_ECC256) || defined(HAVE_ALL_CURVES)
#ifndef NO_ECC_SECP
ret = TLSX_UseSupportedCurve(extensions,
@@ -9811,8 +10019,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
}
#endif
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519)) && \
defined(HAVE_SUPPORTED_CURVES)
#if (defined(HAVE_ECC) || defined(HAVE_CURVE25519) || \
defined(HAVE_CURVE448)) && defined(HAVE_SUPPORTED_CURVES)
if (!ssl->options.userCurves && !ssl->ctx->userCurves) {
if (TLSX_Find(ssl->ctx->extensions,
TLSX_SUPPORTED_GROUPS) == NULL) {
@@ -9829,7 +10037,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
if (ret != WOLFSSL_SUCCESS)
return ret;
}
#endif /* (HAVE_ECC || HAVE_CURVE25519) && HAVE_SUPPORTED_CURVES */
#endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
} /* is not server */
#if !defined(WOLFSSL_NO_SIGALG)
@@ -9851,7 +10059,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
}
#if !defined(HAVE_ECC) && !defined(HAVE_CURVE25519) && \
defined(HAVE_SUPPORTED_CURVES)
!defined(HAVE_CURVE448) && defined(HAVE_SUPPORTED_CURVES)
if (TLSX_Find(ssl->ctx->extensions, TLSX_SUPPORTED_GROUPS) == NULL) {
/* Put in DH groups for TLS 1.3 only. */
ret = TLSX_PopulateSupportedGroups(ssl, &ssl->extensions);
@@ -9859,7 +10067,7 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
return ret;
ret = 0;
}
#endif /* !HAVE_ECC && !HAVE_CURVE25519 && HAVE_SUPPORTED_CURVES */
#endif /* (HAVE_ECC || CURVE25519 || CURVE448) && HAVE_SUPPORTED_CURVES */
#if !defined(WOLFSSL_TLS13_DRAFT_18) && !defined(WOLFSSL_TLS13_DRAFT_22)
if (ssl->certHashSigAlgoSz > 0) {
@@ -9885,6 +10093,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
namedGroup = WOLFSSL_ECC_SECP256R1;
#elif defined(HAVE_CURVE25519)
namedGroup = WOLFSSL_ECC_X25519;
#elif defined(HAVE_CURVE448)
namedGroup = WOLFSSL_ECC_X448;
#elif defined(HAVE_ECC) && (!defined(NO_ECC384) || \
defined(HAVE_ALL_CURVES)) && !defined(NO_ECC_SECP)
namedGroup = WOLFSSL_ECC_SECP384R1;
@@ -9996,7 +10206,8 @@ int TLSX_PopulateExtensions(WOLFSSL* ssl, byte isServer)
/* Pre-shared key modes: mandatory extension for resumption. */
modes = 1 << PSK_KE;
#if !defined(NO_DH) || defined(HAVE_ECC) || defined(HAVE_CURVE25519)
#if !defined(NO_DH) || defined(HAVE_ECC) || \
defined(HAVE_CURVE25519) || defined(HAVE_CURVE448)
if (!ssl->options.noPskDheKe)
modes |= 1 << PSK_DHE_KE;
#endif

View File

@@ -4861,7 +4861,8 @@ static int SendTls13CertificateRequest(WOLFSSL* ssl, byte* reqCtx,
#endif /* NO_WOLFSSL_SERVER */
#ifndef NO_CERTS
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)
/* Encode the signature algorithm into buffer.
*
* hashalgo The hash algorithm.
@@ -4885,6 +4886,14 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
(void)hashAlgo;
break;
#endif
#ifdef HAVE_ED448
/* ED448: 0x0808 */
case ed448_sa_algo:
output[0] = ED448_SA_MAJOR;
output[1] = ED448_SA_MINOR;
(void)hashAlgo;
break;
#endif
#ifndef NO_RSA
/* PSS signatures: 0x080[4-6] */
case rsa_pss_sa_algo:
@@ -4892,7 +4901,6 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
output[1] = hashAlgo;
break;
#endif
/* ED448: 0x0808 */
}
}
@@ -4900,7 +4908,7 @@ static WC_INLINE void EncodeSigAlg(byte hashAlgo, byte hsType, byte* output)
*
* input The encoded signature algorithm.
* hashalgo The hash algorithm.
* hsType The signature type.
* hsType The signature type.
* returns INVALID_PARAMETER if not recognized and 0 otherwise.
*/
static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo,
@@ -4922,10 +4930,17 @@ static WC_INLINE int DecodeTls13SigAlg(byte* input, byte* hashAlgo,
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
#endif
#ifdef HAVE_ED448
/* ED448: 0x0808 */
else if (input[1] == ED448_SA_MINOR) {
*hsType = ed448_sa_algo;
/* Hash performed as part of sign/verify operation. */
*hashAlgo = sha512_mac;
}
#endif
else
ret = INVALID_PARAMETER;
/* ED448: 0x0808 */
break;
default:
*hashAlgo = input[0];
@@ -5637,6 +5652,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
#ifdef HAVE_ED25519
else if (ssl->hsType == DYNAMIC_TYPE_ED25519)
args->sigAlgo = ed25519_sa_algo;
#endif
#ifdef HAVE_ED448
else if (ssl->hsType == DYNAMIC_TYPE_ED448)
args->sigAlgo = ed448_sa_algo;
#endif
EncodeSigAlg(ssl->suites->hashAlgo, args->sigAlgo, args->verify);
@@ -5701,7 +5720,16 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
}
sig->length = ED25519_SIG_SIZE;
}
#endif /* HAVE_ECC */
#endif /* HAVE_ED25519 */
#ifdef HAVE_ED448
if (ssl->hsType == DYNAMIC_TYPE_ED448) {
ret = Ed448CheckPubKey(ssl);
if (ret < 0) {
ERROR_OUT(ret, exit_scv);
}
sig->length = ED448_SIG_SIZE;
}
#endif /* HAVE_ED448 */
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@@ -5739,6 +5767,20 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
args->length = (word16)sig->length;
}
#endif
#ifdef HAVE_ED448
if (ssl->hsType == DYNAMIC_TYPE_ED448) {
ret = Ed448Sign(ssl, args->sigData, args->sigDataSz,
args->verify + HASH_SIG_SIZE + VERIFY_HEADER,
(word32*)&sig->length, (ed448_key*)ssl->hsKey,
#ifdef HAVE_PK_CALLBACKS
ssl->buffers.key
#else
NULL
#endif
);
args->length = (word16)sig->length;
}
#endif
#ifndef NO_RSA
if (ssl->hsType == DYNAMIC_TYPE_RSA) {
ret = RsaSign(ssl, sig->buffer, (word32)sig->length,
@@ -5903,7 +5945,8 @@ static int DoTls13Certificate(WOLFSSL* ssl, byte* input, word32* inOutIdx,
return ret;
}
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)
typedef struct Dcv13Args {
byte* output; /* not allocated */
@@ -6028,6 +6071,11 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
WOLFSSL_MSG("Oops, peer sent ED25519 key but not in verify");
}
#endif
#ifdef HAVE_ED448
if (args->sigAlgo == ed448_sa_algo && !ssl->peerEd448KeyPresent) {
WOLFSSL_MSG("Oops, peer sent ED448 key but not in verify");
}
#endif
#ifdef HAVE_ECC
if (args->sigAlgo == ecc_dsa_sa_algo &&
!ssl->peerEccDsaKeyPresent) {
@@ -6058,7 +6106,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
WOLFSSL_MSG("Doing ECC peer cert verify");
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
DYNAMIC_TYPE_SIGNATURE);
if (args->sigData == NULL) {
ERROR_OUT(MEMORY_E, exit_dcv);
}
@@ -6079,7 +6127,7 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
WOLFSSL_MSG("Doing ED25519 peer cert verify");
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
DYNAMIC_TYPE_SIGNATURE);
if (args->sigData == NULL) {
ERROR_OUT(MEMORY_E, exit_dcv);
}
@@ -6088,6 +6136,20 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
ret = 0;
}
#endif
#ifdef HAVE_ED448
if (ssl->peerEd448KeyPresent) {
WOLFSSL_MSG("Doing ED448 peer cert verify");
args->sigData = (byte*)XMALLOC(MAX_SIG_DATA_SZ, ssl->heap,
DYNAMIC_TYPE_SIGNATURE);
if (args->sigData == NULL) {
ERROR_OUT(MEMORY_E, exit_dcv);
}
CreateSigData(ssl, args->sigData, &args->sigDataSz, 1);
ret = 0;
}
#endif
/* Advance state and proceed */
ssl->options.asyncState = TLS_ASYNC_DO;
@@ -6155,6 +6217,27 @@ static int DoTls13CertificateVerify(WOLFSSL* ssl, byte* input,
}
}
#endif
#ifdef HAVE_ED448
if (ssl->peerEd448KeyPresent) {
WOLFSSL_MSG("Doing ED448 peer cert verify");
ret = Ed448Verify(ssl, input + args->idx, args->sz,
args->sigData, args->sigDataSz,
ssl->peerEd448Key,
#ifdef HAVE_PK_CALLBACKS
&ssl->buffers.peerEd448Key
#else
NULL
#endif
);
if (ret >= 0) {
FreeKey(ssl, DYNAMIC_TYPE_ED448,
(void**)&ssl->peerEd448Key);
ssl->peerEd448KeyPresent = 0;
}
}
#endif
/* Check for error */
if (ret != 0) {
@@ -7473,8 +7556,9 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
case server_hello:
WOLFSSL_MSG("processing server hello");
ret = DoTls13ServerHello(ssl, input, inOutIdx, size, &type);
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && defined(HAVE_ED25519) && \
!defined(NO_ED25519_CLIENT_AUTH)
#if !defined(WOLFSSL_NO_CLIENT_AUTH) && \
((defined(HAVE_ED25519) && !defined(NO_ED25519_CLIENT_AUTH)) || \
(defined(HAVE_ED448) && !defined(NO_ED448_CLIENT_AUTH)))
if (ssl->options.resuming || !IsAtLeastTLSv1_2(ssl) ||
IsAtLeastTLSv1_3(ssl->version)) {
ssl->options.cacheMessages = 0;
@@ -7527,7 +7611,8 @@ int DoTls13HandShakeMsgType(WOLFSSL* ssl, byte* input, word32* inOutIdx,
break;
#endif
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519)
#if !defined(NO_RSA) || defined(HAVE_ECC) || defined(HAVE_ED25519) || \
defined(HAVE_ED448)
case certificate_verify:
WOLFSSL_MSG("processing certificate verify");
ret = DoTls13CertificateVerify(ssl, input, inOutIdx, size);