Merge pull request #9436 from douzzer/20251114-WOLFSSL_BLIND_PRIVATE_KEY-thread-safety

20251114-WOLFSSL_BLIND_PRIVATE_KEY-thread-safety
This commit is contained in:
JacobBarthelmeh
2025-11-17 15:01:13 -07:00
committed by GitHub
5 changed files with 107 additions and 61 deletions
+36 -13
View File
@@ -293,12 +293,32 @@ int wolfssl_priv_der_blind(WC_RNG* rng, DerBuffer* key, DerBuffer** mask)
return ret;
}
void wolfssl_priv_der_unblind(DerBuffer* key, DerBuffer* mask)
void wolfssl_priv_der_blind_toggle(DerBuffer* key, const DerBuffer* mask)
{
if (key != NULL) {
if ((key != NULL) && (mask != NULL)) {
xorbuf(key->buffer, mask->buffer, mask->length);
}
}
DerBuffer *wolfssl_priv_der_unblind(const DerBuffer* key, const DerBuffer* mask)
{
DerBuffer *ret;
if ((key == NULL) || (mask == NULL))
return NULL;
if (mask->length > key->length)
return NULL;
if (AllocDer(&ret, key->length, key->type, key->heap) != 0)
return NULL;
xorbufout(ret->buffer, key->buffer, mask->buffer, mask->length);
return ret;
}
void wolfssl_priv_der_unblind_free(DerBuffer* key)
{
if (key != NULL)
FreeDer(&key);
}
#endif /* !NO_CERT && WOLFSSL_BLIND_PRIVATE_KEY */
@@ -7090,7 +7110,7 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
}
ssl->buffers.weOwnKey = 1;
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
if (ret != 0) {
@@ -7115,7 +7135,8 @@ int SetSSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx, int writeDup)
return ret;
}
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.altKey, ctx->altPrivateKeyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.altKey,
ctx->altPrivateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.altKey,
&ssl->buffers.altKeyMask);
if (ret != 0) {
@@ -30281,7 +30302,7 @@ int DecodeAltPrivateKey(WOLFSSL *ssl, word32* length)
}
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.altKey, ssl->buffers.altKeyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.altKey, ssl->buffers.altKeyMask);
#endif
#ifdef WOLF_PRIVATE_KEY_ID
@@ -30691,7 +30712,7 @@ exit_dapk:
&ssl->buffers.altKeyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
@@ -34386,7 +34407,7 @@ int SendCertificateVerify(WOLFSSL* ssl)
WOLFSSL_ENTER("SendCertificateVerify");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_IO
@@ -34436,7 +34457,7 @@ int SendCertificateVerify(WOLFSSL* ssl)
{
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key,
wolfssl_priv_der_blind_toggle(ssl->buffers.key,
ssl->buffers.keyMask);
#endif
return 0; /* sent blank cert, can't verify */
@@ -34864,7 +34885,7 @@ exit_scv:
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
@@ -35538,7 +35559,7 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
WOLFSSL_ENTER("SendServerKeyExchange");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_IO
@@ -37123,7 +37144,8 @@ static int DoSessionTicket(WOLFSSL* ssl, const byte* input, word32* inOutIdx,
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key,
ssl->buffers.keyMask);
}
#endif
@@ -41041,7 +41063,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
WOLFSSL_ENTER("DoClientKeyExchange");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
#endif
#ifdef WOLFSSL_ASYNC_CRYPT
@@ -41848,7 +41870,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ],
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key,
ssl->buffers.keyMask);
}
#endif
+62 -43
View File
@@ -7361,9 +7361,9 @@ static int check_cert_key_dev(word32 keyOID, byte* privKey, word32 privSz,
*
* Returns WOLFSSL_SUCCESS on good private key
* WOLFSSL_FAILURE if mismatched */
static int check_cert_key(DerBuffer* cert, DerBuffer* key, DerBuffer* altKey,
void* heap, int devId, int isKeyLabel, int isKeyId, int altDevId,
int isAltKeyLabel, int isAltKeyId)
static int check_cert_key(const DerBuffer* cert, const DerBuffer* key,
const DerBuffer* altKey, void* heap, int devId, int isKeyLabel, int isKeyId,
int altDevId, int isAltKeyLabel, int isAltKeyId)
{
WC_DECLARE_VAR(der, DecodedCert, 1, 0);
word32 size;
@@ -7498,7 +7498,18 @@ 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;
int res = WOLFSSL_SUCCESS;
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
DerBuffer *privateKey;
#ifdef WOLFSSL_DUAL_ALG_CERTS
DerBuffer *altPrivateKey;
#endif
#else
const DerBuffer *privateKey;
#ifdef WOLFSSL_DUAL_ALG_CERTS
const DerBuffer *altPrivateKey;
#endif
#endif
if (ctx == NULL) {
return WOLFSSL_FAILURE;
@@ -7506,42 +7517,42 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
#ifdef WOLFSSL_DUAL_ALG_CERTS
#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) != 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;
}
privateKey = wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
altPrivateKey = wolfssl_priv_der_unblind(ctx->altPrivateKey,
ctx->altPrivateKeyMask);
if ((privateKey == NULL) || (altPrivateKey == NULL)) {
res = WOLFSSL_FAILURE;
}
#else
privateKey = ctx->privateKey;
altPrivateKey = ctx->altPrivateKey;
#endif
if (res == WOLFSSL_SUCCESS) {
res = check_cert_key(ctx->certificate, privateKey, altPrivateKey,
ctx->heap, ctx->privateKeyDevId, ctx->privateKeyLabel,
ctx->privateKeyId, ctx->altPrivateKeyDevId,
ctx->altPrivateKeyLabel, ctx->altPrivateKeyId) != 0;
}
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind_free(privateKey);
wolfssl_priv_der_unblind_free(altPrivateKey);
#endif
#else
#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;
}
privateKey = wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
if (privateKey == NULL) {
res = WOLFSSL_FAILURE;
}
#else
privateKey = ctx->privateKey;
#endif
if (res == WOLFSSL_SUCCESS) {
res = check_cert_key(ctx->certificate, privateKey, NULL, ctx->heap,
ctx->privateKeyDevId, ctx->privateKeyLabel,
ctx->privateKeyId, INVALID_DEVID, 0, 0);
}
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind_free(privateKey);
#endif
#endif
@@ -7558,8 +7569,12 @@ int wolfSSL_CTX_check_private_key(const WOLFSSL_CTX* ctx)
/**
* Return the private key of the WOLFSSL_CTX struct
* @return WOLFSSL_EVP_PKEY* The caller doesn *NOT*` free the returned object.
*
* Note, even though the supplied ctx pointer is designated const, on success
* ctx->privateKeyPKey is changed by this call. The change is done safely using
* a hardware-synchronized store.
*/
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx)
WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx)
{
WOLFSSL_EVP_PKEY* res;
const unsigned char *key;
@@ -7596,19 +7611,23 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx)
return NULL;
}
key = ctx->privateKey->buffer;
if (ctx->privateKeyPKey != NULL) {
res = ctx->privateKeyPKey;
}
else {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
DerBuffer *unblinded_privateKey =
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
if (unblinded_privateKey == NULL)
return NULL;
key = unblinded_privateKey->buffer;
#else
key = ctx->privateKey->buffer;
#endif
res = wolfSSL_d2i_PrivateKey(type, NULL, &key,
(long)ctx->privateKey->length);
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ctx->privateKey, ctx->privateKeyMask);
wolfssl_priv_der_unblind_free(unblinded_privateKey);
#endif
if (res) {
#ifdef WOLFSSL_ATOMIC_OPS
@@ -7621,7 +7640,7 @@ WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx)
res = current_pkey;
}
#else
ctx->privateKeyPKey = res;
((WOLFSSL_CTX *)ctx)->privateKeyPKey = res;
#endif
}
}
@@ -8874,7 +8893,7 @@ int wolfSSL_check_private_key(const WOLFSSL* ssl)
#endif
#else
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(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,
@@ -20971,7 +20990,7 @@ WOLFSSL_CTX* wolfSSL_set_SSL_CTX(WOLFSSL* ssl, WOLFSSL_CTX* ctx)
return NULL;
}
/* Blind the private key for the SSL with new random mask. */
wolfssl_priv_der_unblind(ssl->buffers.key, ctx->privateKeyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ctx->privateKeyMask);
ret = wolfssl_priv_der_blind(ssl->rng, ssl->buffers.key,
&ssl->buffers.keyMask);
if (ret != 0) {
+3 -3
View File
@@ -9131,7 +9131,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
WOLFSSL_ENTER("SendTls13CertificateVerify");
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
#endif
ssl->options.buildingMsg = 1;
@@ -9187,7 +9187,7 @@ static int SendTls13CertificateVerify(WOLFSSL* ssl)
{
if (ssl->options.sendVerify == SEND_BLANK_CERT) {
#ifdef WOLFSSL_BLIND_PRIVATE_KEY
wolfssl_priv_der_unblind(ssl->buffers.key,
wolfssl_priv_der_blind_toggle(ssl->buffers.key,
ssl->buffers.keyMask);
#endif
return 0; /* sent blank cert, can't verify */
@@ -9882,7 +9882,7 @@ exit_scv:
&ssl->buffers.keyMask);
}
else {
wolfssl_priv_der_unblind(ssl->buffers.key, ssl->buffers.keyMask);
wolfssl_priv_der_blind_toggle(ssl->buffers.key, ssl->buffers.keyMask);
}
#endif
+5 -1
View File
@@ -2183,7 +2183,11 @@ WOLFSSL_LOCAL int CreateDevPrivateKey(void** pkey, byte* data, word32 length,
#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);
WOLFSSL_LOCAL void wolfssl_priv_der_blind_toggle(DerBuffer* key,
const DerBuffer* mask);
WOLFSSL_LOCAL WARN_UNUSED_RESULT DerBuffer *wolfssl_priv_der_unblind(
const DerBuffer* key, const DerBuffer* mask);
WOLFSSL_LOCAL void wolfssl_priv_der_unblind_free(DerBuffer* key);
#endif
WOLFSSL_LOCAL int DecodePrivateKey(WOLFSSL *ssl, word32* length);
#ifdef WOLFSSL_DUAL_ALG_CERTS
+1 -1
View File
@@ -3228,7 +3228,7 @@ WOLFSSL_API int wolfSSL_want_write(WOLFSSL* ssl);
#ifdef OPENSSL_EXTRA
WOLFSSL_API int wolfSSL_want(WOLFSSL* ssl);
WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(WOLFSSL_CTX* ctx);
WOLFSSL_API WOLFSSL_EVP_PKEY* wolfSSL_CTX_get0_privatekey(const WOLFSSL_CTX* ctx);
#include <stdarg.h> /* var_arg */
WOLFSSL_API int wolfSSL_BIO_vprintf(WOLFSSL_BIO* bio, const char* format,