Merge pull request #7416 from SparkiDev/ecc_blind_k

ECC: blind private key after use in signing
This commit is contained in:
David Garske 2024-05-13 18:56:44 -07:00 committed by GitHub
commit 1c4479867e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 671 additions and 96 deletions

View File

@ -266,6 +266,49 @@ static int SSL_hmac(WOLFSSL* ssl, byte* digest, const byte* in, word32 sz,
#endif /* !WOLFSSL_NO_TLS12 */
#if !defined(NO_CERT) && defined(WOLFSSL_BLIND_PRIVATE_KEY)
int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key, DerBuffer** mask)
{
int ret = 0;
WC_RNG local_rng;
if (key != NULL) {
if (*mask != NULL) {
FreeDer(mask);
}
ret = AllocDer(mask, key->length, key->type, key->heap);
if ((ret == 0) && (rng == NULL)) {
if (wc_InitRng(&local_rng) != 0) {
ret = RNG_FAILURE_E;
}
else {
rng = &local_rng;
}
}
if (ret == 0) {
ret = wc_RNG_GenerateBlock(rng, (*mask)->buffer, (*mask)->length);
}
if (ret == 0) {
xorbuf(key->buffer, (*mask)->buffer, (*mask)->length);
}
if (rng == &local_rng) {
wc_FreeRng(rng);
}
}
return ret;
}
void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask)
{
if (key != NULL) {
xorbuf(key->buffer, mask->buffer, mask->length);
}
}
#endif
#if defined(WOLFSSL_RENESAS_FSPSM_TLS) || defined(WOLFSSL_RENESAS_TSIP_TLS)
#include <wolfssl/wolfcrypt/port/Renesas/renesas_cmn.h>
#endif
@ -2604,11 +2647,17 @@ void SSL_CtxResourceFree(WOLFSSL_CTX* ctx)
ForceZero(ctx->privateKey->buffer, ctx->privateKey->length);
}
FreeDer(&ctx->privateKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ctx->privateKeyMask);
#endif
#ifdef WOLFSSL_DUAL_ALG_CERTS
if (ctx->altPrivateKey != NULL && ctx->altPrivateKey->buffer != NULL) {
ForceZero(ctx->altPrivateKey->buffer, ctx->altPrivateKey->length);
}
FreeDer(&ctx->altPrivateKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ctx->altPrivateKeyMask);
#endif
#endif /* WOLFSSL_DUAL_ALG_CERTS */
#ifdef OPENSSL_ALL
wolfSSL_EVP_PKEY_free(ctx->privateKeyPKey);
@ -6763,14 +6812,45 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
#ifdef WOLFSSL_TLS13
ssl->buffers.certChainCnt = ctx->certChainCnt;
#endif
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.key = ctx->privateKey;
#else
if (ctx->privateKey != NULL) {
AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
ctx->privateKey->length, ctx->privateKey->type,
ctx->privateKey->heap);
ssl->buffers.weOwnKey = 1;
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
if (ret != 0) {
return ret;
}
}
#endif
ssl->buffers.keyType = ctx->privateKeyType;
ssl->buffers.keyId = ctx->privateKeyId;
ssl->buffers.keyLabel = ctx->privateKeyLabel;
ssl->buffers.keySz = ctx->privateKeySz;
ssl->buffers.keyDevId = ctx->privateKeyDevId;
#ifdef WOLFSSL_DUAL_ALG_CERTS
ssl->buffers.altKey = ctx->altPrivateKey;
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.altKey = ctx->altPrivateKey;
#else
if (ctx->altPrivateKey != NULL) {
AllocCopyDer(&ssl->buffers.altkey, ctx->altPrivateKey->buffer,
ctx->altPrivateKey->length, ctx->altPrivateKey->type,
ctx->altPrivateKey->heap);
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.altKey, ctx->altPrivateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
&ssl->buffers.altKeyMask);
if (ret != 0) {
return ret;
}
}
#endif
ssl->buffers.altKeyType = ctx->altPrivateKeyType;
ssl->buffers.altKeyId = ctx->altPrivateKeyId;
ssl->buffers.altKeyLabel = ctx->altPrivateKeyLabel;
@ -8518,8 +8598,14 @@ void FreeHandshakeResources(WOLFSSL* ssl)
}
#endif /* !NO_DH */
#ifndef NO_CERTS
wolfSSL_UnloadCertsKeys(ssl);
#if !defined(NO_CERTS) && !defined(OPENSSL_EXTRA) && \
!defined(WOLFSSL_WPAS_SMALL)
#ifndef WOLFSSL_POST_HANDSHAKE_AUTH
if (ssl->options.side != WOLFSSL_CLIENT_END)
#endif
{
wolfSSL_UnloadCertsKeys(ssl);
}
#endif
#ifdef HAVE_PK_CALLBACKS
#if defined(WOLFSSL_TLS13) && defined(WOLFSSL_POST_HANDSHAKE_AUTH)
@ -28322,6 +28408,10 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
ERROR_OUT(NO_PRIVATE_KEY, exit_dapk);
}
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.altKey, ssl->buffers.altKeyMask);
#endif
#ifdef WOLF_PRIVATE_KEY_ID
if (ssl->buffers.altKeyDevId != INVALID_DEVID &&
(ssl->buffers.altKeyId || ssl->buffers.altKeyLabel)) {
@ -28724,6 +28814,16 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
(void)length;
exit_dapk:
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
&ssl->buffers.altKeyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
if (ret != 0) {
WOLFSSL_ERROR_VERBOSE(ret);
}
@ -32746,6 +32846,10 @@ int SendCertificateVerify(WOLFSSL* ssl)
WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND);
WOLFSSL_ENTER("SendCertificateVerify");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_IO
if (ssl->async == NULL) {
ssl->async = (struct WOLFSSL_ASYNC*)
@ -32792,6 +32896,10 @@ int SendCertificateVerify(WOLFSSL* ssl)
case TLS_ASYNC_BEGIN:
{
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key,
ssl->buffers.keyMask);
#endif
return 0; /* sent blank cert, can't verify */
}
@ -33196,6 +33304,15 @@ int SendCertificateVerify(WOLFSSL* ssl)
} /* switch(ssl->options.asyncState) */
exit_scv:
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
WOLFSSL_LEAVE("SendCertificateVerify", ret);
WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);
@ -33859,6 +33976,10 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_START(WC_FUNC_SERVER_KEY_EXCHANGE_SEND);
WOLFSSL_ENTER("SendServerKeyExchange");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_IO
if (ssl->async == NULL) {
ssl->async = (struct WOLFSSL_ASYNC*)
@ -35415,6 +35536,16 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
exit_sske:
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
WOLFSSL_LEAVE("SendServerKeyExchange", ret);
WOLFSSL_END(WC_FUNC_SERVER_KEY_EXCHANGE_SEND);
@ -38937,6 +39068,10 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
WOLFSSL_START(WC_FUNC_CLIENT_KEY_EXCHANGE_DO);
WOLFSSL_ENTER("DoClientKeyExchange");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
if (ssl->async == NULL) {
ssl->async = (struct WOLFSSL_ASYNC*)
@ -40131,6 +40266,16 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
exit_dcke:
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
WOLFSSL_LEAVE("DoClientKeyExchange", ret);
WOLFSSL_END(WC_FUNC_CLIENT_KEY_EXCHANGE_DO);
#ifdef WOLFSSL_ASYNC_CRYPT

View File

@ -11704,7 +11704,8 @@ static int wolfssl_ec_key_int_copy(ecc_key* dst, const ecc_key* src)
if (ret == 0) {
/* Copy private key. */
ret = mp_copy(wc_ecc_key_get_priv(src), wc_ecc_key_get_priv(dst));
ret = mp_copy(wc_ecc_key_get_priv((ecc_key*)src),
wc_ecc_key_get_priv(dst));
if (ret != MP_OKAY) {
WOLFSSL_MSG("mp_copy error");
}

155
src/ssl.c
View File

@ -6339,20 +6339,54 @@ static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey,
* WOLFSSL_FAILURE if mismatched. */
int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
{
int res;
if (ctx == NULL) {
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_DUAL_ALG_CERTS
return check_cert_key(ctx->certificate, ctx->privateKey, ctx->altPrivateKey,
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
wolfssl_priv_der_unblind(ctx->altPrivateKey, ctx->altPrivateKeyMask);
#endif
res = check_cert_key(ctx->certificate, ctx->privateKey, ctx->altPrivateKey,
ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel,
ctx->privateKeyId, ctx->altPrivateKeyDevId, ctx->altPrivateKeyLabel,
ctx->altPrivateKeyId);
ctx->altPrivateKeyId) != 0
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
{
int ret;
ret = wolfssl_priv_der_blind(NULL, ctx->privateKey,
(DerBuffer**)&ctx->privateKeyMask);
if (ret == 0) {
ret = wolfssl_priv_der_blind(NULL, ctx->altPrivateKey,
(DerBuffer**)&ctx->altPrivateKeyMask);
}
if (ret != 0) {
res = WOLFSSL_FAILURE;
}
}
#endif
#else
return check_cert_key(ctx->certificate, ctx->privateKey, NULL, ctx->heap,
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
#endif
res = check_cert_key(ctx->certificate, ctx->privateKey, NULL, ctx->heap,
ctx->privateKeyDevId, ctx->privateKeyLabel, ctx->privateKeyId,
INVALID_DEVID, 0, 0);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
{
int ret = wolfssl_priv_der_blind(NULL, ctx->privateKey,
(DerBuffer**)&ctx->privateKeyMask);
if (ret != 0) {
res = WOLFSSL_FAILURE;
}
}
#endif
#endif
return res;
}
#endif /* !NO_CHECK_PRIVATE_KEY */
@ -6363,6 +6397,7 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
*/
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
{
WOLFSSL_EVP_PKEY* res;
const unsigned char *key;
int type;
@ -6399,12 +6434,22 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
key = ctx->privateKey->buffer;
if (ctx->privateKeyPKey != NULL)
return ctx->privateKeyPKey;
else
return wolfSSL_d2i_PrivateKey(type,
if (ctx->privateKeyPKey != NULL) {
res = ctx->privateKeyPKey;
}
else {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
#endif
res = wolfSSL_d2i_PrivateKey(type,
(WOLFSSL_EVP_PKEY**)&ctx->privateKeyPKey, &key,
(long)ctx->privateKey->length);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
#endif
}
return res;
}
#endif
@ -7584,19 +7629,53 @@ WOLFSSL_EVP_PKEY* wolfSSL_d2i_PrivateKey_id(int type, WOLFSSL_EVP_PKEY** out,
* WOLFSSL_FAILURE if mismatched. */
int wolfSSL_check_private_key(const WOLFSSL* ssl)
{
int res = WOLFSSL_SUCCESS;
if (ssl == NULL) {
return WOLFSSL_FAILURE;
}
#ifdef WOLFSSL_DUAL_ALG_CERTS
return check_cert_key(ssl->buffers.certificate, ssl->buffers.key,
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_unblind(ssl->buffers.altKey, ssl->buffers.altKeyMask);
#endif
res = check_cert_key(ssl->buffers.certificate, ssl->buffers.key,
ssl->buffers.altKey, ssl->heap, ssl->buffers.keyDevId,
ssl->buffers.keyLabel, ssl->buffers.keyId, ssl->buffers.altKeyDevId,
ssl->buffers.altKeyLabel, ssl->buffers.altKeyId);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (res == WOLFSSL_SUCCESS) {
int ret;
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
(DerBuffer**)&ssl->buffers.keyMask);
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
(DerBuffer**)&ssl->buffers.altKeyMask);
}
if (ret != 0) {
res = WOLFSSL_FAILURE;
}
}
#endif
#else
return check_cert_key(ssl->buffers.certificate, ssl->buffers.key, NULL,
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
#endif
res = check_cert_key(ssl->buffers.certificate, ssl->buffers.key, NULL,
ssl->heap, ssl->buffers.keyDevId, ssl->buffers.keyLabel,
ssl->buffers.keyId, INVALID_DEVID, 0, 0);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (res == WOLFSSL_SUCCESS) {
int ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
(DerBuffer**)&ssl->buffers.keyMask);
if (ret != 0) {
res = WOLFSSL_FAILURE;
}
}
#endif
#endif
return res;
}
#endif /* !NO_CHECK_PRIVATE_KEY */
@ -10726,6 +10805,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
WOLFSSL_MSG("Unloading key");
ForceZero(ssl->buffers.key->buffer, ssl->buffers.key->length);
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
ssl->buffers.weOwnKey = 0;
}
@ -10734,6 +10816,9 @@ int wolfSSL_set_compression(WOLFSSL* ssl)
WOLFSSL_MSG("Unloading alt key");
ForceZero(ssl->buffers.altKey->buffer, ssl->buffers.altKey->length);
FreeDer(&ssl->buffers.altKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
#endif
ssl->buffers.weOwnAltKey = 0;
}
#endif /* WOLFSSL_DUAL_ALG_CERTS */
@ -19405,18 +19490,32 @@ void wolfSSL_certs_clear(WOLFSSL* ssl)
#ifdef WOLFSSL_TLS13
ssl->buffers.certChainCnt = 0;
#endif
if (ssl->buffers.weOwnKey)
if (ssl->buffers.weOwnKey) {
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
}
ssl->buffers.key = NULL;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.keyMask = NULL;
#endif
ssl->buffers.keyType = 0;
ssl->buffers.keyId = 0;
ssl->buffers.keyLabel = 0;
ssl->buffers.keySz = 0;
ssl->buffers.keyDevId = 0;
#ifdef WOLFSSL_DUAL_ALG_CERTS
if (ssl->buffers.weOwnAltKey)
if (ssl->buffers.weOwnAltKey) {
FreeDer(&ssl->buffers.altKey);
ssl->buffers.altKey = NULL;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
#endif
}
ssl->buffers.altKey = NULL;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.altKeyMask = NULL;
#endif
#endif /* WOLFSSL_DUAL_ALG_CERTS */
}
#endif
@ -19985,7 +20084,22 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
#ifdef WOLFSSL_TLS13
ssl->buffers.certChainCnt = ctx->certChainCnt;
#endif
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.key = ctx->privateKey;
#else
if (ctx->privateKey != NULL) {
AllocCopyDer(&ssl->buffers.key, ctx->privateKey->buffer,
ctx->privateKey->length, ctx->privateKey->type,
ctx->privateKey->heap);
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
if (ret != 0) {
return ret;
}
}
#endif
ssl->buffers.keyType = ctx->privateKeyType;
ssl->buffers.keyId = ctx->privateKeyId;
ssl->buffers.keyLabel = ctx->privateKeyLabel;
@ -20000,7 +20114,22 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
ssl->options.haveFalconSig = ctx->haveFalconSig;
ssl->options.haveDilithiumSig = ctx->haveDilithiumSig;
#ifdef WOLFSSL_DUAL_ALG_CERTS
ssl->buffers.altKey = ctx->altPrivateKey;
#ifndef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.altKey = ctx->altPrivateKey;
#else
if (ctx->altPrivateKey != NULL) {
AllocCopyDer(&ssl->buffers.altkey, ctx->altPrivateKey->buffer,
ctx->altPrivateKey->length, ctx->altPrivateKey->type,
ctx->altPrivateKey->heap);
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.altKey, ctx->altPrivateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
&ssl->buffers.altKeyMask);
if (ret != 0) {
return ret;
}
}
#endif
ssl->buffers.altKeySz = ctx->altPrivateKeySz;
ssl->buffers.altKeyType = ctx->altPrivateKeyType;
#endif /* WOLFSSL_DUAL_ALG_CERTS */

View File

@ -1243,10 +1243,13 @@ static int ProcessBufferPrivPkcs8Dec(EncryptedInfo* info, DerBuffer* der,
* @param [in, out] ctx SSL context object.
* @param [in, out] ssl SSL object.
* @param [in] der DER encoding.
* @return 0 on success.
*/
static void ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
static int ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
DerBuffer** der, int type)
{
int ret = 0;
(void)type;
#ifdef WOLFSSL_DUAL_ALG_CERTS
@ -1256,6 +1259,9 @@ static void ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
/* Dispose of previous key if not context's. */
if (ssl->buffers.weOwnAltKey) {
FreeDer(&ssl->buffers.altKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
#endif
}
ssl->buffers.altKeyId = 0;
ssl->buffers.altKeyLabel = 0;
@ -1286,6 +1292,9 @@ static void ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
/* Dispose of previous key if not context's. */
if (ssl->buffers.weOwnKey) {
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
}
ssl->buffers.keyId = 0;
ssl->buffers.keyLabel = 0;
@ -1309,6 +1318,8 @@ static void ProcessBufferPrivKeyHandleDer(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
wc_MemZero_Add("CTX private key", (*der)->buffer, (*der)->length);
#endif
}
return ret;
}
/* Decode private key.
@ -1352,9 +1363,11 @@ static int ProcessBufferPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
#endif
/* Put the data into the SSL or SSL context object. */
ProcessBufferPrivKeyHandleDer(ctx, ssl, &der, type);
/* Try to decode the DER data. */
ret = ProcessBufferTryDecode(ctx, ssl, der, &algId, heap, type);
ret = ProcessBufferPrivKeyHandleDer(ctx, ssl, &der, type);
if (ret == 0) {
/* Try to decode the DER data. */
ret = ProcessBufferTryDecode(ctx, ssl, der, &algId, heap, type);
}
#if defined(WOLFSSL_ENCRYPTED_KEYS) && !defined(NO_PWDBASED)
/* If private key type PKCS8 header wasn't already removed (algId == 0). */
@ -1369,6 +1382,30 @@ static int ProcessBufferPrivateKey(WOLFSSL_CTX* ctx, WOLFSSL* ssl,
}
#endif /* WOLFSSL_ENCRYPTED_KEYS && !NO_PWDBASED */
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
#ifdef WOLFSSL_DUAL_ALG_CERTS
if (type == ALT_PRIVATEKEY_TYPE) {
if (ssl != NULL) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
&ssl->buffers.altKeyMask);
}
else {
ret = wolfssl_priv_der_blind(NULL, ctx->altPrivateKey,
&ctx->altPrivateKeyMask);
}
}
else
#endif
if (ssl != NULL) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
}
else {
ret = wolfssl_priv_der_blind(NULL, ctx->privateKey,
&ctx->privateKeyMask);
}
#endif
/* Check if we were able to determine algorithm id. */
if ((ret == 0) && (algId == 0)) {
#ifdef OPENSSL_EXTRA
@ -4257,6 +4294,9 @@ int wolfSSL_use_PrivateKey_Id(WOLFSSL* ssl, const unsigned char* id,
/* Dispose of old private key if owned and allocate and copy in id. */
if (ssl->buffers.weOwnKey) {
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
}
if (AllocCopyDer(&ssl->buffers.key, id, (word32)sz, PRIVATEKEY_TYPE,
ssl->heap) != 0) {
@ -4324,6 +4364,9 @@ int wolfSSL_use_PrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
/* Dispose of old private key if owned and allocate and copy in label. */
if (ssl->buffers.weOwnKey) {
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
}
if (AllocCopyDer(&ssl->buffers.key, (const byte*)label, (word32)sz,
PRIVATEKEY_TYPE, ssl->heap) != 0) {
@ -4366,6 +4409,9 @@ int wolfSSL_use_AltPrivateKey_Id(WOLFSSL* ssl, const unsigned char* id, long sz,
if (ret == 1) {
if (ssl->buffers.weOwnAltKey) {
FreeDer(&ssl->buffers.altKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
#endif
}
if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
ssl->heap) == 0) {
@ -4409,8 +4455,12 @@ int wolfSSL_use_AltPrivateKey_Label(WOLFSSL* ssl, const char* label, int devId)
if (ret == 1) {
sz = (word32)XSTRLEN(label) + 1;
if (ssl->buffers.weOwnAltKey)
if (ssl->buffers.weOwnAltKey) {
FreeDer(&ssl->buffers.altKey);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.altKeyMask);
#endif
}
if (AllocDer(&ssl->buffers.altKey, (word32)sz, ALT_PRIVATEKEY_TYPE,
ssl->heap) == 0) {
ret = 0;

View File

@ -8803,6 +8803,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
WOLFSSL_START(WC_FUNC_CERTIFICATE_VERIFY_SEND);
WOLFSSL_ENTER("SendTls13CertificateVerify");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
#endif
ssl->options.buildingMsg = 1;
#if defined(WOLFSSL_RENESAS_TSIP_TLS)
@ -8855,6 +8859,10 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
case TLS_ASYNC_BEGIN:
{
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key,
ssl->buffers.keyMask);
#endif
return 0; /* sent blank cert, can't verify */
}
@ -8915,10 +8923,16 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
/* If we own it, free key before overriding it. */
if (ssl->buffers.weOwnKey) {
FreeDer(&ssl->buffers.key);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
FreeDer(&ssl->buffers.keyMask);
#endif
}
/* Swap keys */
ssl->buffers.key = ssl->buffers.altKey;
ssl->buffers.key = ssl->buffers.altKey;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
ssl->buffers.keyMask = ssl->buffers.altKeyMask;
#endif
ssl->buffers.weOwnKey = ssl->buffers.weOwnAltKey;
}
#endif /* WOLFSSL_DUAL_ALG_CERTS */
@ -9543,6 +9557,15 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
} /* switch(ssl->options.asyncState) */
exit_scv:
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
if (ret == 0) {
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
WOLFSSL_LEAVE("SendTls13CertificateVerify", ret);
WOLFSSL_END(WC_FUNC_CERTIFICATE_VERIFY_SEND);

View File

@ -98,6 +98,12 @@ Possible ECC enable options:
* Use this when CPU state can be closely observed by
* attacker.
* default: off
* WOLFSSL_ECC_BLIND_K
* Blind the private key k by using a random mask.
* The private key is never stored unprotected but an
* unmasked copy is computed and stored each time it is
* needed.
* default: off
*/
/*
@ -297,6 +303,53 @@ ECC Curve Sizes:
#endif
#ifdef WOLFSSL_ECC_BLIND_K
mp_int* ecc_get_k(ecc_key* key)
{
mp_xor_ct(key->k, key->kb, key->dp->size, key->ku);
return key->ku;
}
void ecc_blind_k(ecc_key* key, mp_int* b)
{
mp_xor_ct(key->k, b, key->dp->size, key->k);
mp_xor_ct(key->kb, b, key->dp->size, key->kb);
}
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
{
int ret = 0;
WC_RNG local_rng;
#ifdef ECC_TIMING_RESISTANT
if (rng == NULL) {
rng = key->rng;
}
#endif
if (rng == NULL) {
ret = wc_InitRng(&local_rng);
if (ret == 0) {
rng = &local_rng;
}
}
if (ret == 0) {
ret = mp_rand(key->kb, (key->dp->size + sizeof(mp_digit) - 1) /
sizeof(mp_digit), rng);
if (ret == 0) {
mp_xor_ct(key->k, key->kb, key->dp->size, key->k);
}
}
if (rng == &local_rng) {
wc_FreeRng(&local_rng);
}
return ret;
}
mp_int* wc_ecc_key_get_priv(ecc_key* key)
{
return ecc_get_k(key);
}
#endif
/* forward declarations */
static int wc_ecc_new_point_ex(ecc_point** point, void* heap);
static void wc_ecc_del_point_ex(ecc_point* p, void* heap);
@ -4693,7 +4746,7 @@ int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
byte* out, word32* outlen)
{
int err = MP_OKAY;
mp_int* k = private_key->k;
mp_int* k = ecc_get_k(private_key);
#ifdef HAVE_ECC_CDH
#ifdef WOLFSSL_SMALL_STACK
mp_int *k_lcl = NULL;
@ -4723,7 +4776,7 @@ int wc_ecc_shared_secret_gen_sync(ecc_key* private_key, ecc_point* point,
goto errout;
}
/* multiply cofactor times private key "k" */
err = mp_mul_d(private_key->k, cofactor, k);
err = mp_mul_d(ecc_get_k(private_key), cofactor, k);
if (err != MP_OKAY)
goto errout;
}
@ -4964,7 +5017,8 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
word32 keySz = private_key->dp->size;
/* sync public key x/y */
err = wc_mp_to_bigint_sz(private_key->k, &private_key->k->raw, keySz);
err = wc_mp_to_bigint_sz(ecc_get_k(private_key),
&ecc_get_k(private_key)->raw, keySz);
if (err == MP_OKAY)
err = wc_mp_to_bigint_sz(point->x, &point->x->raw, keySz);
if (err == MP_OKAY)
@ -4978,7 +5032,7 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
NitroxEccGetSize(private_key)*2);
if (err == MP_OKAY)
err = NitroxEcdh(private_key,
&private_key->k->raw, &point->x->raw, &point->y->raw,
&ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
private_key->e->raw.buf, &private_key->e->raw.len,
&curve->prime->raw);
#else
@ -4986,7 +5040,7 @@ static int wc_ecc_shared_secret_gen_async(ecc_key* private_key,
err = wc_ecc_curve_load(private_key->dp, &curve, ECC_CURVE_FIELD_BF);
if (err == MP_OKAY)
err = IntelQaEcdh(&private_key->asyncDev,
&private_key->k->raw, &point->x->raw, &point->y->raw,
&ecc_get_k(private_key)->raw, &point->x->raw, &point->y->raw,
out, outlen,
&curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
private_key->dp->cofactor);
@ -5371,9 +5425,9 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
key->type = ECC_PRIVATEKEY_ONLY;
}
if ((err == MP_OKAY) && (mp_iszero(key->k) || mp_isneg(key->k) ||
(mp_cmp(key->k, curve->order) != MP_LT)))
{
if ((err == MP_OKAY) && (mp_iszero(ecc_get_k(key)) ||
mp_isneg(ecc_get_k(key)) ||
(mp_cmp(ecc_get_k(key), curve->order) != MP_LT))) {
err = ECC_PRIV_KEY_E;
}
@ -5395,10 +5449,10 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
if (err == MP_OKAY && key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_ECC) {
word32 keySz = key->dp->size;
/* sync private key to raw */
err = wc_mp_to_bigint_sz(key->k, &key->k->raw, keySz);
err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw, keySz);
if (err == MP_OKAY) {
err = IntelQaEccPointMul(&key->asyncDev,
&key->k->raw, pub->x, pub->y, pub->z,
&ecc_get_k(key)->raw, pub->x, pub->y, pub->z,
&curve->Gx->raw, &curve->Gy->raw,
&curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
key->dp->cofactor);
@ -5414,25 +5468,25 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
else
#ifndef WOLFSSL_SP_NO_256
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
err = sp_ecc_mulmod_base_256(key->k, pub, 1, key->heap);
err = sp_ecc_mulmod_base_256(ecc_get_k(key), pub, 1, key->heap);
}
else
#endif /* WOLFSSL_SP_NO_256 */
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
err = sp_ecc_mulmod_base_sm2_256(key->k, pub, 1, key->heap);
err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), pub, 1, key->heap);
}
else
#endif
#ifdef WOLFSSL_SP_384
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
err = sp_ecc_mulmod_base_384(key->k, pub, 1, key->heap);
err = sp_ecc_mulmod_base_384(ecc_get_k(key), pub, 1, key->heap);
}
else
#endif
#ifdef WOLFSSL_SP_521
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
err = sp_ecc_mulmod_base_521(key->k, pub, 1, key->heap);
err = sp_ecc_mulmod_base_521(ecc_get_k(key), pub, 1, key->heap);
}
else
#endif
@ -5464,8 +5518,8 @@ static int ecc_make_pub_ex(ecc_key* key, ecc_curve_spec* curve,
/* make the public key */
if (err == MP_OKAY) {
/* Map in a separate call as this should be constant time */
err = wc_ecc_mulmod_ex2(key->k, base, pub, curve->Af, curve->prime,
curve->order, rng, 0, key->heap);
err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, pub, curve->Af,
curve->prime, curve->order, rng, 0, key->heap);
if (err == MP_MEM) {
err = MEMORY_E;
}
@ -5720,6 +5774,11 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
if (err == SA_SILIB_RET_OK) {
err = mp_read_unsigned_bin(key->k, ucompressed_key, raw_size);
#ifdef WOLFSSL_ECC_BLIND_K
if (err == MP_OKAY) {
err = ecc_blind_k_rng(key, rng);
}
#endif
}
#elif defined(WOLFSSL_SILABS_SE_ACCEL)
@ -5771,7 +5830,12 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
err = xil_mpi_import(key->pubkey.y, key->keyRaw + key->dp->size,
key->dp->size, key->heap);
if (err == 0)
err = xil_mpi_import(key->k, key->privKey, key->dp->size, key->heap);
err = xil_mpi_import(key->k, key->privKey, key->dp->size,
key->heap);
#ifdef WOLFSSL_ECC_BLIND_K
if (err == 0)
err = ecc_blind_k_rng(key, rng);
#endif
if (err == 0)
err = mp_set(key->pubkey.z, 1);
if (err) {
@ -5953,6 +6017,11 @@ static int _ecc_make_key_ex(WC_RNG* rng, int keysize, ecc_key* key,
err = wc_mp_to_bigint(key->pubkey.z, &key->pubkey.z->raw);
#endif
#ifdef WOLFSSL_ECC_BLIND_K
if (err == MP_OKAY)
err = ecc_blind_k_rng(key, rng);
#endif
#endif /* HAVE_ECC_MAKE_PUB */
return err;
@ -6140,13 +6209,27 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
alt_fp_init(key->pubkey.z);
key->k = (mp_int*)key->ka;
alt_fp_init(key->k);
#ifdef WOLFSSL_ECC_BLIND_K
key->kb = (mp_int*)key->kba;
key->ku = (mp_int*)key->kia;
alt_fp_init(key->kb);
alt_fp_init(key->ku);
#endif
#else
ret = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
NULL, NULL);
#ifndef WOLFSSL_ECC_BLIND_K
NULL, NULL
#else
key->kb, key->ku
#endif
);
if (ret != MP_OKAY) {
return MEMORY_E;
}
#endif /* ALT_ECC_SIZE */
#ifdef WOLFSSL_ECC_BLIND_K
mp_forcezero(key->kb);
#endif
#endif /* WOLFSSL_ATECC508A */
#if (defined(WOLFSSL_ECDSA_SET_K) || defined(WOLFSSL_ECDSA_SET_K_ONE_LOOP) || \
defined(WOLFSSL_ECDSA_DETERMINISTIC_K) || \
@ -6190,6 +6273,10 @@ int wc_ecc_init_ex(ecc_key* key, void* heap, int devId)
#ifdef WOLFSSL_CHECK_MEM_ZERO
mp_memzero_add("ECC k", key->k);
#ifdef WOLFSSL_ECC_BLIND_K
mp_memzero_add("ECC kb", key->kb);
mp_memzero_add("ECC ku", key->ku);
#endif
#endif
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
@ -6750,7 +6837,7 @@ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
/* currently limiting to SHA256 for auto create */
if (mp_init(key->sign_k) != MP_OKAY ||
wc_ecc_gen_deterministic_k(in, inlen,
WC_HASH_TYPE_SHA256, key->k, key->sign_k,
WC_HASH_TYPE_SHA256, ecc_get_k(key), key->sign_k,
curve->order, key->heap) != 0) {
mp_free(key->sign_k);
XFREE(key->sign_k, key->heap, DYNAMIC_TYPE_ECC);
@ -6769,8 +6856,8 @@ static int deterministic_sign_helper(const byte* in, word32 inlen, ecc_key* key)
#else
key->sign_k_set = 0;
/* currently limiting to SHA256 for auto create */
if (wc_ecc_gen_deterministic_k(in, inlen, WC_HASH_TYPE_SHA256, key->k,
key->sign_k, curve->order, key->heap) != 0) {
if (wc_ecc_gen_deterministic_k(in, inlen, WC_HASH_TYPE_SHA256,
ecc_get_k(key), key->sign_k, curve->order, key->heap) != 0) {
err = ECC_PRIV_KEY_E;
}
else {
@ -6908,15 +6995,18 @@ static int ecc_sign_hash_sw(ecc_key* key, ecc_key* pubkey, WC_RNG* rng,
if (err != MP_OKAY) break;
if (mp_iszero(r) == MP_NO) {
mp_int* ep = pubkey->k;
mp_int* kp = pubkey->k;
mp_int* x = key->k;
mp_int* kp = ecc_get_k(pubkey);
mp_int* ep = kp;
mp_int* x = ecc_get_k(key);
/* Blind after getting. */
ecc_blind_k(key, b);
/* find s = (e + xr)/k
= b.(e/k.b + x.r/k.b) */
/* k' = k.b */
err = mp_mulmod(pubkey->k, b, curve->order, kp);
err = mp_mulmod(kp, b, curve->order, kp);
if (err != MP_OKAY) break;
/* k' = 1/k.b
@ -6995,12 +7085,12 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
#endif
if (key->nb_ctx) {
return sp_ecc_sign_256_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
}
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_sign_256_nb(&nb_ctx.sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
} while (err == FP_WOULDBLOCK);
return err;
#endif
@ -7009,8 +7099,8 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
{
int ret;
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = sp_ecc_sign_256(in, inlen, rng, key->k, r, s, sign_k,
key->heap);
ret = sp_ecc_sign_256(in, inlen, rng, ecc_get_k(key), r, s,
sign_k, key->heap);
RESTORE_VECTOR_REGISTERS();
return ret;
}
@ -7021,8 +7111,8 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
if (ecc_sets[key->idx].id == ECC_SM2P256V1) {
int ret;
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = sp_ecc_sign_sm2_256(in, inlen, rng, key->k, r, s, sign_k,
key->heap);
ret = sp_ecc_sign_sm2_256(in, inlen, rng, ecc_get_k(key), r, s,
sign_k, key->heap);
RESTORE_VECTOR_REGISTERS();
return ret;
}
@ -7035,12 +7125,12 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
#endif
if (key->nb_ctx) {
return sp_ecc_sign_384_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
}
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_sign_384_nb(&nb_ctx.sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
} while (err == FP_WOULDBLOCK);
return err;
#endif
@ -7049,8 +7139,8 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
{
int ret;
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = sp_ecc_sign_384(in, inlen, rng, key->k, r, s, sign_k,
key->heap);
ret = sp_ecc_sign_384(in, inlen, rng, ecc_get_k(key), r, s,
sign_k, key->heap);
RESTORE_VECTOR_REGISTERS();
return ret;
}
@ -7065,12 +7155,12 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
#endif
if (key->nb_ctx) {
return sp_ecc_sign_521_nb(&key->nb_ctx->sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
}
#ifdef WC_ECC_NONBLOCK_ONLY
do { /* perform blocking call to non-blocking function */
err = sp_ecc_sign_521_nb(&nb_ctx.sp_ctx, in, inlen, rng,
key->k, r, s, sign_k, key->heap);
ecc_get_k(key), r, s, sign_k, key->heap);
} while (err == FP_WOULDBLOCK);
return err;
#endif
@ -7079,8 +7169,8 @@ static int ecc_sign_hash_sp(const byte* in, word32 inlen, WC_RNG* rng,
{
int ret;
SAVE_VECTOR_REGISTERS(return _svr_ret;);
ret = sp_ecc_sign_521(in, inlen, rng, key->k, r, s, sign_k,
key->heap);
ret = sp_ecc_sign_521(in, inlen, rng, ecc_get_k(key), r, s,
sign_k, key->heap);
RESTORE_VECTOR_REGISTERS();
return ret;
}
@ -7303,7 +7393,8 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
if (err == MP_OKAY)
err = wc_mp_to_bigint_sz(e, &e->raw, keySz);
if (err == MP_OKAY)
err = wc_mp_to_bigint_sz(key->k, &key->k->raw, keySz);
err = wc_mp_to_bigint_sz(ecc_get_k(key), &ecc_get_k(key)->raw,
keySz);
if (err == MP_OKAY)
err = wc_ecc_gen_k(rng, key->dp->size, k, curve->order);
if (err == MP_OKAY)
@ -7311,14 +7402,15 @@ int wc_ecc_sign_hash_ex(const byte* in, word32 inlen, WC_RNG* rng,
#ifdef HAVE_CAVIUM_V
if (err == MP_OKAY)
err = NitroxEcdsaSign(key, &e->raw, &key->k->raw, &k->raw,
&r->raw, &s->raw, &curve->prime->raw, &curve->order->raw);
err = NitroxEcdsaSign(key, &e->raw, &ecc_get_k(key)->raw,
&k->raw, &r->raw, &s->raw, &curve->prime->raw,
&curve->order->raw);
#else
if (err == MP_OKAY)
err = IntelQaEcdsaSign(&key->asyncDev, &e->raw, &key->k->raw,
&k->raw, &r->raw, &s->raw, &curve->Af->raw, &curve->Bf->raw,
&curve->prime->raw, &curve->order->raw, &curve->Gx->raw,
&curve->Gy->raw);
err = IntelQaEcdsaSign(&key->asyncDev, &e->raw,
&ecc_get_k(key)->raw, &k->raw, &r->raw, &s->raw,
&curve->Af->raw, &curve->Bf->raw, &curve->prime->raw,
&curve->order->raw, &curve->Gx->raw, &curve->Gy->raw);
#endif
#ifndef HAVE_CAVIUM_V
@ -7820,6 +7912,16 @@ int wc_ecc_free(ecc_key* key)
if (key->k)
#endif
mp_forcezero(key->k);
#ifdef WOLFSSL_ECC_BLIND_K
#ifdef ALT_ECC_SIZE
if (key->kb)
#endif
mp_forcezero(key->kb);
#ifdef ALT_ECC_SIZE
if (key->ku)
#endif
mp_forcezero(key->ku);
#endif
#ifdef WOLFSSL_CUSTOM_CURVES
if (key->deallocSet && key->dp != NULL)
@ -9892,7 +9994,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#ifndef WOLFSSL_SP_NO_256
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
if (err == MP_OKAY) {
err = sp_ecc_mulmod_base_256(key->k, res, 1, key->heap);
err = sp_ecc_mulmod_base_256(ecc_get_k(key), res, 1, key->heap);
}
}
else
@ -9900,7 +10002,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
if (err == MP_OKAY) {
err = sp_ecc_mulmod_base_sm2_256(key->k, res, 1, key->heap);
err = sp_ecc_mulmod_base_sm2_256(ecc_get_k(key), res, 1, key->heap);
}
}
else
@ -9908,7 +10010,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#ifdef WOLFSSL_SP_384
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
if (err == MP_OKAY) {
err = sp_ecc_mulmod_base_384(key->k, res, 1, key->heap);
err = sp_ecc_mulmod_base_384(ecc_get_k(key), res, 1, key->heap);
}
}
else
@ -9916,7 +10018,7 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#ifdef WOLFSSL_SP_521
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
if (err == MP_OKAY) {
err = sp_ecc_mulmod_base_521(key->k, res, 1, key->heap);
err = sp_ecc_mulmod_base_521(ecc_get_k(key), res, 1, key->heap);
}
}
else
@ -9969,12 +10071,12 @@ static int ecc_check_privkey_gen(ecc_key* key, mp_int* a, mp_int* prime)
#else
#ifdef ECC_TIMING_RESISTANT
if (err == MP_OKAY)
err = wc_ecc_mulmod_ex2(key->k, base, res, a, prime, curve->order,
key->rng, 1, key->heap);
err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
curve->order, key->rng, 1, key->heap);
#else
if (err == MP_OKAY)
err = wc_ecc_mulmod_ex2(key->k, base, res, a, prime, curve->order,
NULL, 1, key->heap);
err = wc_ecc_mulmod_ex2(ecc_get_k(key), base, res, a, prime,
curve->order, NULL, 1, key->heap);
#endif
#endif /* WOLFSSL_KCAPI_ECC */
}
@ -10245,31 +10347,31 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
#ifndef WOLFSSL_SP_NO_256
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP256R1) {
return sp_ecc_check_key_256(key->pubkey.x, key->pubkey.y,
key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap);
key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
}
#endif
#if defined(WOLFSSL_SM2) && defined(WOLFSSL_SP_SM2)
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SM2P256V1) {
return sp_ecc_check_key_sm2_256(key->pubkey.x, key->pubkey.y,
key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap);
key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
}
#endif
#ifdef WOLFSSL_SP_384
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP384R1) {
return sp_ecc_check_key_384(key->pubkey.x, key->pubkey.y,
key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap);
key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
}
#endif
#ifdef WOLFSSL_SP_521
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SECP521R1) {
return sp_ecc_check_key_521(key->pubkey.x, key->pubkey.y,
key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap);
key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
}
#endif
#if defined(WOLFSSL_SP_1024) && defined(WOLFCRYPT_HAVE_SAKKE)
if (key->idx != ECC_CUSTOM_IDX && ecc_sets[key->idx].id == ECC_SAKKE_1) {
return sp_ecc_check_key_1024(key->pubkey.x, key->pubkey.y,
key->type == ECC_PRIVATEKEY ? key->k : NULL, key->heap);
key->type == ECC_PRIVATEKEY ? ecc_get_k(key) : NULL, key->heap);
}
#endif
#endif
@ -10380,8 +10482,8 @@ static int _ecc_validate_public_key(ecc_key* key, int partial, int priv)
/* SP 800-56Ar3, section 5.6.2.1.2 */
/* private keys must be in the range [1, n-1] */
if ((err == MP_OKAY) && (key->type == ECC_PRIVATEKEY) &&
(mp_iszero(key->k) || mp_isneg(key->k) ||
(mp_cmp(key->k, curve->order) != MP_LT))
(mp_iszero(ecc_get_k(key)) || mp_isneg(ecc_get_k(key)) ||
(mp_cmp(ecc_get_k(key), curve->order) != MP_LT))
#ifdef WOLFSSL_KCAPI_ECC
&& key->handle == NULL
#endif
@ -10466,12 +10568,26 @@ int wc_ecc_import_x963_ex(const byte* in, word32 inLen, ecc_key* key,
alt_fp_init(key->pubkey.z);
key->k = (mp_int*)key->ka;
alt_fp_init(key->k);
#ifdef WOLFSSL_ECC_BLIND_K
key->kb = (mp_int*)key->kba;
key->ku = (mp_int*)key->kua;
alt_fp_init(key->kb);
alt_fp_init(key->ku);
#endif
#else
err = mp_init_multi(key->k,
key->pubkey.x, key->pubkey.y, key->pubkey.z, NULL, NULL);
err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
#ifndef WOLFSSL_ECC_BLIND_K
NULL, NULL
#else
key->kb, key->ku
#endif
);
#endif
if (err != MP_OKAY)
return MEMORY_E;
#ifdef WOLFSSL_ECC_BLIND_K
mp_forcezero(key->kb);
#endif
SAVE_VECTOR_REGISTERS(return _svr_ret;);
@ -10780,7 +10896,7 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
return BUFFER_E;
}
err = wc_export_int(key->k, d, dLen, keySz + WC_CAAM_MAC_SZ,
err = wc_export_int(ecc_get_k(key), d, dLen, keySz + WC_CAAM_MAC_SZ,
encType);
*dLen = keySz + WC_CAAM_MAC_SZ;
}
@ -10802,7 +10918,7 @@ int wc_ecc_export_ex(ecc_key* key, byte* qx, word32* qxLen,
else
#endif
{
err = wc_export_int(key->k, d, dLen, keySz, encType);
err = wc_export_int(ecc_get_k(key), d, dLen, keySz, encType);
if (err != MP_OKAY)
return err;
}
@ -10937,6 +11053,11 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
}
ret = mp_read_unsigned_bin(key->k, priv, privSz);
#ifdef WOLFSSL_ECC_BLIND_K
if (ret == MP_OKAY) {
err = ecc_blind_k_rng(key, NULL);
}
#endif
}
#elif defined(WOLFSSL_QNX_CAAM) || defined(WOLFSSL_IMXRT1170_CAAM)
if ((wc_ecc_size(key) + WC_CAAM_MAC_SZ) == (int)privSz) {
@ -10968,11 +11089,21 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#else
key->blackKey = CAAM_BLACK_KEY_CCM;
ret = mp_read_unsigned_bin(key->k, priv, privSz);
#ifdef WOLFSSL_ECC_BLIND_K
if (ret == MP_OKAY) {
err = ecc_blind_k_rng(key, NULL);
}
#endif
#endif
}
else {
key->blackKey = 0;
ret = mp_read_unsigned_bin(key->k, priv, privSz);
#ifdef WOLFSSL_ECC_BLIND_K
if (ret == MP_OKAY) {
err = ecc_blind_k_rng(key, NULL);
}
#endif
/* If using AES-ECB encrypted black keys check here if key is valid,
* if not valid than assume is an encrypted key. A public key is needed
@ -11001,8 +11132,8 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
ret = mp_read_unsigned_bin(key->k, priv, privSz);
#ifdef HAVE_WOLF_BIGINT
if (ret == 0 &&
wc_bigint_from_unsigned_bin(&key->k->raw, priv, privSz) != 0) {
if (ret == 0 && wc_bigint_from_unsigned_bin(&key->k->raw, priv,
privSz) != 0) {
mp_clear(key->k);
ret = ASN_GETINT_E;
}
@ -11044,6 +11175,11 @@ int wc_ecc_import_private_key_ex(const byte* priv, word32 privSz,
#endif
}
#endif /* WOLFSSL_VALIDATE_ECC_IMPORT */
#ifdef WOLFSSL_ECC_BLIND_K
if (ret == 0) {
ret = ecc_blind_k_rng(key, NULL);
}
#endif
#endif /* WOLFSSL_CRYPTOCELL */
@ -11236,12 +11372,26 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
alt_fp_init(key->pubkey.z);
key->k = (mp_int*)key->ka;
alt_fp_init(key->k);
#ifdef WOLFSSL_ECC_BLIND_K
key->kb = (mp_int*)key->kba;
key->ku = (mp_int*)key->kua;
alt_fp_init(key->kb);
alt_fp_init(key->ku);
#endif
#else
err = mp_init_multi(key->k, key->pubkey.x, key->pubkey.y, key->pubkey.z,
NULL, NULL);
#ifndef WOLFSSL_ECC_BLIND_K
NULL, NULL
#else
key->kb, key->ku
#endif
);
#endif
if (err != MP_OKAY)
return MEMORY_E;
#ifdef WOLFSSL_ECC_BLIND_K
mp_forcezero(key->kb);
#endif
/* read Qx */
if (err == MP_OKAY) {
@ -11388,6 +11538,11 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
err = wc_export_int(key->k, &keyRaw[0], &keySz, keySz,
WC_TYPE_UNSIGNED_BIN);
}
#ifdef WOLFSSL_ECC_BLIND_K
if (err == 0) {
err = ecc_blind_k_rng(key, NULL);
}
#endif
if (err == MP_OKAY) {
/* Create private key from external key buffer*/
@ -11419,12 +11574,17 @@ static int wc_ecc_import_raw_private(ecc_key* key, const char* qx,
(word32)key->dp->size);
}
}
#ifdef WOLFSSL_ECC_BLIND_K
if (err == 0) {
err = ecc_blind_k_rng(key, NULL);
}
#endif
#if defined(WOLFSSL_XILINX_CRYPT_VERSAL)
if (err == MP_OKAY) {
const word32 key_size = key->dp->size;
word32 buf_size = key_size;
err = wc_export_int(key->k, key->privKey,
&buf_size, key_size, WC_TYPE_UNSIGNED_BIN);
err = wc_export_int(key, key->privKey, &buf_size, key_size,
WC_TYPE_UNSIGNED_BIN);
mp_reverse(key->privKey, key_size);
}
#endif

View File

@ -8097,6 +8097,27 @@ int sp_submod_ct(const sp_int* a, const sp_int* b, const sp_int* m, sp_int* r)
}
#endif /* WOLFSSL_SP_MATH_ALL && HAVE_ECC */
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC) && \
defined(WOLFSSL_ECC_BLIND_K)
void sp_xor_ct(const sp_int* a, const sp_int* b, int len, sp_int* r)
{
if ((a != NULL) && (b != NULL) && (r != NULL)) {
unsigned int i;
r->used = (len * 8 + SP_WORD_SIZE - 1) / SP_WORD_SIZE;
for (i = 0; i < r->used; i++) {
r->dp[i] = a->dp[i] ^ b->dp[i];
}
i = (len * 8) % SP_WORD_SIZE;
if (i > 0) {
r->dp[r->used - 1] &= ((sp_int_digit)1 << i) - 1;
}
/* Remove leading zeros. */
sp_clamp_ct(r);
}
}
#endif
/********************
* Shifting functoins
********************/

View File

@ -167,7 +167,8 @@ int get_rand_digit(WC_RNG* rng, mp_digit* d)
return wc_RNG_GenerateBlock(rng, (byte*)d, sizeof(mp_digit));
}
#if defined(WC_RSA_BLINDING) || defined(WOLFCRYPT_HAVE_SAKKE)
#if defined(WC_RSA_BLINDING) || defined(WOLFCRYPT_HAVE_SAKKE) || \
defined(WOLFSSL_ECC_BLIND_K)
int mp_rand(mp_int* a, int digits, WC_RNG* rng)
{
int ret = 0;
@ -221,7 +222,7 @@ int mp_rand(mp_int* a, int digits, WC_RNG* rng)
return ret;
}
#endif /* WC_RSA_BLINDING || WOLFCRYPT_HAVE_SAKKE */
#endif /* WC_RSA_BLINDING || WOLFCRYPT_HAVE_SAKKE || WOLFSSL_ECC_BLIND_K */
#endif /* !WC_NO_RNG */
#if defined(HAVE_ECC) || defined(WOLFSSL_EXPORT_INT)

View File

@ -2180,6 +2180,11 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length,
int hsType, int label, int id,
void* heap, int devId);
#endif
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
WOLFSSL_LOCAL int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key,
DerBuffer** mask);
WOLFSSL_LOCAL void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask);
#endif
WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word32* length);
#ifdef WOLFSSL_DUAL_ALG_CERTS
WOLFSSL_LOCAL int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length);
@ -3574,6 +3579,9 @@ struct WOLFSSL_CTX {
int certChainCnt;
#endif
DerBuffer* privateKey;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
DerBuffer* privateKeyMask; /* Mask of private key DER. */
#endif
byte privateKeyType;
byte privateKeyId:1;
byte privateKeyLabel:1;
@ -3582,6 +3590,9 @@ struct WOLFSSL_CTX {
#ifdef WOLFSSL_DUAL_ALG_CERTS
DerBuffer* altPrivateKey;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
DerBuffer* altPrivateKeyMask; /* Mask of alt private key DER. */
#endif
byte altPrivateKeyType;
byte altPrivateKeyId:1;
byte altPrivateKeyLabel:1;
@ -4553,6 +4564,9 @@ typedef struct Buffers {
#ifndef NO_CERTS
DerBuffer* certificate; /* WOLFSSL_CTX owns, unless we own */
DerBuffer* key; /* WOLFSSL_CTX owns, unless we own */
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
DerBuffer* keyMask; /* Mask of private key DER. */
#endif
byte keyType; /* Type of key */
byte keyId:1; /* Key data is an id not data */
byte keyLabel:1; /* Key data is a label not data */
@ -4560,6 +4574,9 @@ typedef struct Buffers {
int keyDevId; /* Device Id for key */
#ifdef WOLFSSL_DUAL_ALG_CERTS
DerBuffer* altKey; /* WOLFSSL_CTX owns, unless we own */
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
DerBuffer* altKeyMask; /* Mask of alt private key DER. */
#endif
byte altKeyType; /* Type of alt key */
byte altKeyId:1; /* Key data is an id not data */
byte altKeyLabel:1; /* Key data is a label not data */

View File

@ -501,6 +501,17 @@ struct ecc_key {
mp_int* k;
alt_fp_int ka[1];
#endif
#ifdef WOLFSSL_ECC_BLIND_K
#ifndef ALT_ECC_SIZE
mp_int kb[1];
mp_int ku[1];
#else
mp_int* kb;
mp_int* ku;
alt_fp_int kba[1];
alt_fp_int kua[1];
#endif
#endif
#ifdef WOLFSSL_CAAM
word32 blackKey; /* address of key encrypted and in secure memory */
@ -598,7 +609,20 @@ struct ecc_key {
#endif
};
#define wc_ecc_key_get_priv(key) ((key)->k)
#ifndef WOLFSSL_ECC_BLIND_K
#define ecc_get_k(key) (key)->k
#define ecc_blind_k(key, b) (void)b
#define ecc_blind_k_rng(key, rng) 0
#define wc_ecc_key_get_priv(key) (key)->k
#else
mp_int* ecc_get_k(ecc_key* key);
void ecc_blind_k(ecc_key* key, mp_int* b);
int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng);
WOLFSSL_API mp_int* wc_ecc_key_get_priv(ecc_key* key);
#endif
#define WOLFSSL_HAVE_ECC_KEY_GET_PRIV

View File

@ -996,6 +996,9 @@ MP_API int sp_submod_ct(const sp_int* a, const sp_int* b, const sp_int* m,
MP_API int sp_addmod_ct(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
MP_API void sp_xor_ct(const sp_int* a, const sp_int* b, int len, sp_int* r);
#endif
MP_API int sp_lshd(sp_int* a, int s);
#ifdef WOLFSSL_SP_MATH_ALL
@ -1144,6 +1147,7 @@ WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
#define mp_submod sp_submod
#define mp_addmod_ct sp_addmod_ct
#define mp_submod_ct sp_submod_ct
#define mp_xor_ct sp_xor_ct
#define mp_lshd sp_lshd
#define mp_rshd sp_rshd
#define mp_div sp_div