SSL/TLS: blind private key DER

When WOLFSSL_BLIND_PRIVATE_KEY is defined, blind the private key DER
encoding so that stored private key data is always changing.
This commit is contained in:
Sean Parkinson
2024-04-22 12:28:36 +10:00
parent f24ebdde25
commit b7eca574bb
8 changed files with 403 additions and 24 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
*/
/*
@@ -337,6 +343,11 @@ int ecc_blind_k_rng(ecc_key* key, WC_RNG* rng)
}
return ret;
}
mp_int* wc_ecc_key_get_priv(ecc_key* key)
{
return ecc_get_k(key);
}
#endif
/* forward declarations */

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

@@ -613,13 +613,16 @@ struct ecc_key {
#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 wc_ecc_key_get_priv(key) (ecc_get_k(key))
#define WOLFSSL_HAVE_ECC_KEY_GET_PRIV