From b8263f44f70b5e775dffd9941bff3e4e77d760f9 Mon Sep 17 00:00:00 2001 From: David Garske Date: Mon, 23 Aug 2021 17:09:13 -0700 Subject: [PATCH] Added new EVP API for creating a private key for use with crypto callbacks. Improvements to heap hint and devId with EVP layer. --- src/ssl.c | 203 ++++++++++++++++++++++++++++++------------ wolfcrypt/src/ecc.c | 2 +- wolfcrypt/src/evp.c | 2 +- wolfssl/openssl/ec.h | 3 + wolfssl/openssl/rsa.h | 1 + wolfssl/ssl.h | 4 + 6 files changed, 158 insertions(+), 57 deletions(-) diff --git a/src/ssl.c b/src/ssl.c index 0baa9449a..0ac1b0b7d 100644 --- a/src/ssl.c +++ b/src/ssl.c @@ -8383,6 +8383,77 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, return _d2i_PublicKey(type, out, in, inSz, 1); } +#ifdef WOLF_CRYPTO_CB +/* Create an EVP structure for use with crypto callbacks */ +WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, WOLFSSL_EVP_PKEY** out, + void* heap, int devId) +{ + WOLFSSL_EVP_PKEY* local; + + if (out != NULL && *out != NULL) { + wolfSSL_EVP_PKEY_free(*out); + *out = NULL; + } + + local = wolfSSL_EVP_PKEY_new_ex(heap); + if (local == NULL) { + return NULL; + } + + local->type = type; + local->pkey_sz = 0; + local->pkcs8HeaderSz = 0; + + switch (type) { +#ifndef NO_RSA + case EVP_PKEY_RSA: + { + RsaKey* key; + local->ownRsa = 1; + local->rsa = wolfSSL_RSA_new_ex(heap, devId); + if (local->rsa == NULL) { + wolfSSL_EVP_PKEY_free(local); + return NULL; + } + key = (RsaKey*)local->rsa->internal; + key->devId = devId; + local->rsa->inSet = 1; + break; + } +#endif /* !NO_RSA */ +#ifdef HAVE_ECC + case EVP_PKEY_EC: + { + ecc_key* key; + local->ownEcc = 1; + local->ecc = wolfSSL_EC_KEY_new_ex(heap, devId); + if (local->ecc == NULL) { + wolfSSL_EVP_PKEY_free(local); + return NULL; + } + key = (ecc_key*)local->ecc->internal; + key->devId = devId; + key->type = ECC_PRIVATEKEY; + wc_ecc_set_curve(key, 32, ECC_CURVE_DEF); + + local->ecc->inSet = 1; + break; + } +#endif /* HAVE_ECC */ + default: + WOLFSSL_MSG("Unsupported private key id type"); + wolfSSL_EVP_PKEY_free(local); + return NULL; + } + + if (local != NULL && out != NULL) { + *out = local; + } + + return local; +} +#endif /* WOLF_CRYPTO_CB */ + #ifndef NO_CERTS int wolfSSL_check_private_key(const WOLFSSL* ssl) @@ -35442,22 +35513,23 @@ static void InitwolfSSL_ECKey(WOLFSSL_EC_KEY* key) } } -WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void) +WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId) { WOLFSSL_EC_KEY *external; WOLFSSL_ENTER("wolfSSL_EC_KEY_new"); - external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), NULL, + external = (WOLFSSL_EC_KEY*)XMALLOC(sizeof(WOLFSSL_EC_KEY), heap, DYNAMIC_TYPE_ECC); if (external == NULL) { WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc WOLFSSL_EC_KEY failure"); return NULL; } XMEMSET(external, 0, sizeof(WOLFSSL_EC_KEY)); + external->heap = heap; InitwolfSSL_ECKey(external); - external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), NULL, + external->internal = (ecc_key*)XMALLOC(sizeof(ecc_key), heap, DYNAMIC_TYPE_ECC); if (external->internal == NULL) { WOLFSSL_MSG("wolfSSL_EC_KEY_new malloc ecc key failure"); @@ -35465,7 +35537,7 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void) } XMEMSET(external->internal, 0, sizeof(ecc_key)); - if (wc_ecc_init((ecc_key*)external->internal) != 0) { + if (wc_ecc_init_ex((ecc_key*)external->internal, heap, devId) != 0) { WOLFSSL_MSG("wolfSSL_EC_KEY_new init ecc key failure"); goto error; } @@ -35497,21 +35569,28 @@ error: return NULL; } +WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void) +{ + return wolfSSL_EC_KEY_new_ex(NULL, INVALID_DEVID); +} + void wolfSSL_EC_KEY_free(WOLFSSL_EC_KEY *key) { WOLFSSL_ENTER("wolfSSL_EC_KEY_free"); if (key != NULL) { + void* heap = key->heap; if (key->internal != NULL) { wc_ecc_free((ecc_key*)key->internal); - XFREE(key->internal, NULL, DYNAMIC_TYPE_ECC); + XFREE(key->internal, heap, DYNAMIC_TYPE_ECC); } wolfSSL_BN_free(key->priv_key); wolfSSL_EC_POINT_free(key->pub_key); wolfSSL_EC_GROUP_free(key->group); InitwolfSSL_ECKey(key); /* set back to NULLs for safety */ - XFREE(key, NULL, DYNAMIC_TYPE_ECC); + XFREE(key, heap, DYNAMIC_TYPE_ECC); + (void)heap; /* key = NULL, don't try to access or double free it */ } } @@ -37287,32 +37366,35 @@ WOLFSSL_ECDSA_SIG *wolfSSL_ECDSA_do_sign(const unsigned char *d, int dlen, } if (rng) { - mp_int sig_r, sig_s; - - if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) { - if (wc_ecc_sign_hash_ex(d, dlen, rng, (ecc_key*)key->internal, - &sig_r, &sig_s) != MP_OKAY) { - WOLFSSL_MSG("wc_ecc_sign_hash_ex failed"); - } - else { + byte out[ECC_BUFSIZE]; + word32 outlen = ECC_BUFSIZE; + /* use wc_ecc_sign_hash because it supports crypto callbacks */ + if (wc_ecc_sign_hash(d, dlen, out, &outlen, rng, + (ecc_key*)key->internal) == 0) { + mp_int sig_r, sig_s; + if (mp_init_multi(&sig_r, &sig_s, NULL, NULL, NULL, NULL) == MP_OKAY) { /* put signature blob in ECDSA structure */ - sig = wolfSSL_ECDSA_SIG_new(); - if (sig == NULL) - WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed"); - else if (SetIndividualExternal(&(sig->r), &sig_r)!=WOLFSSL_SUCCESS){ - WOLFSSL_MSG("ecdsa r key error"); - wolfSSL_ECDSA_SIG_free(sig); - sig = NULL; + if (DecodeECC_DSA_Sig(out, outlen, &sig_r, &sig_s) == 0) { + sig = wolfSSL_ECDSA_SIG_new(); + if (sig == NULL) + WOLFSSL_MSG("wolfSSL_ECDSA_SIG_new failed"); + else if (SetIndividualExternal(&sig->r, &sig_r) != WOLFSSL_SUCCESS) { + WOLFSSL_MSG("ecdsa r key error"); + wolfSSL_ECDSA_SIG_free(sig); + sig = NULL; + } + else if (SetIndividualExternal(&sig->s, &sig_s)!=WOLFSSL_SUCCESS){ + WOLFSSL_MSG("ecdsa s key error"); + wolfSSL_ECDSA_SIG_free(sig); + sig = NULL; + } } - else if (SetIndividualExternal(&(sig->s), &sig_s)!=WOLFSSL_SUCCESS){ - WOLFSSL_MSG("ecdsa s key error"); - wolfSSL_ECDSA_SIG_free(sig); - sig = NULL; - } - + mp_free(&sig_r); + mp_free(&sig_s); } - mp_free(&sig_r); - mp_free(&sig_s); + } + else { + WOLFSSL_MSG("wc_ecc_sign_hash_ex failed"); } } @@ -52498,33 +52580,37 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) WOLFSSL_ENTER("wolfSSL_RSA_free"); if (rsa) { +#if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) + int doFree = 0; +#endif + void* heap = rsa->heap; + #ifdef HAVE_EX_DATA_CLEANUP_HOOKS wolfSSL_CRYPTO_cleanup_ex_data(&rsa->ex_data); #endif #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) - int doFree = 0; -#ifndef SINGLE_THREADED + #ifndef SINGLE_THREADED if (wc_LockMutex(&rsa->refMutex) != 0) { WOLFSSL_MSG("Couldn't lock rsa mutex"); } -#endif + #endif /* only free if all references to it are done */ rsa->refCount--; if (rsa->refCount == 0) { doFree = 1; } -#ifndef SINGLE_THREADED + #ifndef SINGLE_THREADED wc_UnLockMutex(&rsa->refMutex); -#endif + #endif if (!doFree) { return; } -#ifndef SINGLE_THREADED + #ifndef SINGLE_THREADED wc_FreeMutex(&rsa->refMutex); -#endif + #endif #endif if (rsa->internal) { @@ -52537,12 +52623,12 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) rng = ((RsaKey*)rsa->internal)->rng; if (rng != NULL && rng != &globalRNG) { wc_FreeRng(rng); - XFREE(rng, NULL, DYNAMIC_TYPE_RNG); + XFREE(rng, heap, DYNAMIC_TYPE_RNG); } } #endif /* WC_RSA_BLINDING */ wc_FreeRsaKey((RsaKey*)rsa->internal); - XFREE(rsa->internal, NULL, DYNAMIC_TYPE_RSA); + XFREE(rsa->internal, heap, DYNAMIC_TYPE_RSA); rsa->internal = NULL; } wolfSSL_BN_free(rsa->iqmp); @@ -52558,7 +52644,7 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) if (rsa->rng && wc_FreeRng(rsa->rng) != 0) { WOLFSSL_MSG("Issue freeing rng"); } - XFREE(rsa->rng, NULL, DYNAMIC_TYPE_RNG); + XFREE(rsa->rng, heap, DYNAMIC_TYPE_RNG); #endif #if defined(OPENSSL_EXTRA) && !defined(WOLFCRYPT_ONLY) @@ -52569,33 +52655,35 @@ void wolfSSL_RSA_free(WOLFSSL_RSA* rsa) InitwolfSSL_Rsa(rsa); /* set back to NULLs for safety */ - XFREE(rsa, NULL, DYNAMIC_TYPE_RSA); + XFREE(rsa, heap, DYNAMIC_TYPE_RSA); + (void)heap; /* rsa = NULL, don't try to access or double free it */ } } -WOLFSSL_RSA* wolfSSL_RSA_new(void) +WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId) { WOLFSSL_RSA* external; - RsaKey* key; + RsaKey* key; WOLFSSL_ENTER("wolfSSL_RSA_new"); - key = (RsaKey*) XMALLOC(sizeof(RsaKey), NULL, DYNAMIC_TYPE_RSA); + key = (RsaKey*)XMALLOC(sizeof(RsaKey), heap, DYNAMIC_TYPE_RSA); if (key == NULL) { WOLFSSL_MSG("wolfSSL_RSA_new malloc RsaKey failure"); return NULL; } - external = (WOLFSSL_RSA*) XMALLOC(sizeof(WOLFSSL_RSA), NULL, + external = (WOLFSSL_RSA*)XMALLOC(sizeof(WOLFSSL_RSA), heap, DYNAMIC_TYPE_RSA); if (external == NULL) { WOLFSSL_MSG("wolfSSL_RSA_new malloc WOLFSSL_RSA failure"); - XFREE(key, NULL, DYNAMIC_TYPE_RSA); + XFREE(key, heap, DYNAMIC_TYPE_RSA); return NULL; } + external->heap = heap; InitwolfSSL_Rsa(external); #if defined(OPENSSL_EXTRA_X509_SMALL) || defined(OPENSSL_EXTRA) @@ -52603,17 +52691,17 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) #ifndef SINGLE_THREADED if (wc_InitMutex(&external->refMutex) != 0) { WOLFSSL_MSG("wc_InitMutex WOLFSSL_RSA failure"); - XFREE(external, NULL, DYNAMIC_TYPE_RSA); - XFREE(key, NULL, DYNAMIC_TYPE_RSA); + XFREE(external, heap, DYNAMIC_TYPE_RSA); + XFREE(key, heap, DYNAMIC_TYPE_RSA); return NULL; } #endif #endif - if (wc_InitRsaKey(key, NULL) != 0) { + if (wc_InitRsaKey_ex(key, heap, devId) != 0) { WOLFSSL_MSG("InitRsaKey WOLFSSL_RSA failure"); - XFREE(external, NULL, DYNAMIC_TYPE_RSA); - XFREE(key, NULL, DYNAMIC_TYPE_RSA); + XFREE(external, heap, DYNAMIC_TYPE_RSA); + XFREE(key, heap, DYNAMIC_TYPE_RSA); return NULL; } @@ -52622,10 +52710,10 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) { WC_RNG* rng; - rng = (WC_RNG*) XMALLOC(sizeof(WC_RNG), NULL, DYNAMIC_TYPE_RNG); - if (rng != NULL && wc_InitRng(rng) != 0) { + rng = (WC_RNG*)XMALLOC(sizeof(WC_RNG), heap, DYNAMIC_TYPE_RNG); + if (rng != NULL && wc_InitRng_ex(rng, heap, devId) != 0) { WOLFSSL_MSG("InitRng failure, attempting to use global RNG"); - XFREE(rng, NULL, DYNAMIC_TYPE_RNG); + XFREE(rng, heap, DYNAMIC_TYPE_RNG); rng = NULL; } @@ -52637,8 +52725,8 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) if (rng == NULL) { WOLFSSL_MSG("wolfSSL_RSA_new no WC_RNG for blinding"); - XFREE(external, NULL, DYNAMIC_TYPE_RSA); - XFREE(key, NULL, DYNAMIC_TYPE_RSA); + XFREE(external, heap, DYNAMIC_TYPE_RSA); + XFREE(key, heap, DYNAMIC_TYPE_RSA); return NULL; } @@ -52652,6 +52740,11 @@ WOLFSSL_RSA* wolfSSL_RSA_new(void) external->inSet = 0; return external; } + +WOLFSSL_RSA* wolfSSL_RSA_new(void) +{ + return wolfSSL_RSA_new_ex(NULL, INVALID_DEVID); +} #endif /* !NO_RSA && (OPENSSL_EXTRA || OPENSSL_EXTRA_X509_SMALL) */ diff --git a/wolfcrypt/src/ecc.c b/wolfcrypt/src/ecc.c index 9e803d571..568167432 100644 --- a/wolfcrypt/src/ecc.c +++ b/wolfcrypt/src/ecc.c @@ -5275,7 +5275,7 @@ int wc_ecc_sign_hash(const byte* in, word32 inlen, byte* out, word32 *outlen, #endif if (rng == NULL) { - WOLFSSL_MSG("rng was NULL"); + WOLFSSL_MSG("ECC sign RNG missing"); return ECC_BAD_ARG_E; } diff --git a/wolfcrypt/src/evp.c b/wolfcrypt/src/evp.c index 83ebdb595..5eb9f7854 100644 --- a/wolfcrypt/src/evp.c +++ b/wolfcrypt/src/evp.c @@ -2904,7 +2904,7 @@ int wolfSSL_EVP_DigestSignFinal(WOLFSSL_EVP_MD_CTX *ctx, unsigned char *sig, if (ctx == NULL || siglen == NULL) return WOLFSSL_FAILURE; - /* Return the maximum size of the signaure when sig is NULL. */ + /* Return the maximum size of the signature when sig is NULL. */ if (ctx->isHMAC) { hashLen = wolfssl_mac_len(ctx->hash.hmac.macType); diff --git a/wolfssl/openssl/ec.h b/wolfssl/openssl/ec.h index 28741cc89..7efee174d 100644 --- a/wolfssl/openssl/ec.h +++ b/wolfssl/openssl/ec.h @@ -117,6 +117,7 @@ struct WOLFSSL_EC_KEY { WOLFSSL_BIGNUM *priv_key; void* internal; /* our ECC Key */ + void* heap; char form; /* Either POINT_CONVERSION_UNCOMPRESSED or * POINT_CONVERSION_COMPRESSED */ word16 pkcs8HeaderSz; @@ -200,6 +201,8 @@ WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_by_curve_name(int nid); WOLFSSL_API const char* wolfSSL_EC_curve_nid2nist(int nid); WOLFSSL_API int wolfSSL_EC_curve_nist2nid(const char* name); WOLFSSL_API +WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new_ex(void* heap, int devId); +WOLFSSL_API WOLFSSL_EC_KEY *wolfSSL_EC_KEY_new(void); WOLFSSL_API int wolfSSL_EC_KEY_set_group(WOLFSSL_EC_KEY *key, WOLFSSL_EC_GROUP *group); diff --git a/wolfssl/openssl/rsa.h b/wolfssl/openssl/rsa.h index 1c010e4bd..b8c3d1af8 100644 --- a/wolfssl/openssl/rsa.h +++ b/wolfssl/openssl/rsa.h @@ -101,6 +101,7 @@ typedef struct WOLFSSL_RSA { typedef WOLFSSL_RSA RSA; typedef WOLFSSL_RSA_METHOD RSA_METHOD; +WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new_ex(void* heap, int devId); WOLFSSL_API WOLFSSL_RSA* wolfSSL_RSA_new(void); WOLFSSL_API void wolfSSL_RSA_free(WOLFSSL_RSA*); diff --git a/wolfssl/ssl.h b/wolfssl/ssl.h index 3733154d5..2733d45aa 100644 --- a/wolfssl/ssl.h +++ b/wolfssl/ssl.h @@ -1732,6 +1732,10 @@ WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PublicKey(int, WOLFSSL_EVP_PKEY**, const unsigned char **, long); WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey(int type, WOLFSSL_EVP_PKEY** out, const unsigned char **in, long inSz); +#ifdef WOLF_CRYPTO_CB +WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, + WOLFSSL_EVP_PKEY** out, void* heap, int devId); +#endif WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_EVP(WOLFSSL_EVP_PKEY** key, unsigned char** in, long inSz); WOLFSSL_API int wolfSSL_i2d_PrivateKey(const WOLFSSL_EVP_PKEY* key,