From 2e1e8d27892e64eb6446a94333fd88c6a454b781 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 25 Jul 2022 17:48:26 +0200 Subject: [PATCH 1/5] misc.c: introduce ctMaskCopy() --- wolfcrypt/src/misc.c | 11 +++++++++++ wolfssl/wolfcrypt/misc.h | 2 ++ 2 files changed, 13 insertions(+) diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index da2778ea9..7d534ffde 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -544,6 +544,17 @@ WC_STATIC WC_INLINE byte ctSetLTE(int a, int b) { return (byte)(((word32)a - b - 1) >> 31); } + +/* Constant time - copy size bytes from left to dst if mask is set, size bytes + * from right to dst if mask is not set */ +WC_STATIC WC_INLINE void ctMaskCopy(byte m, byte* dst, byte* left, byte* right, + word16 size) +{ + int i; + for (i = 0; i < size; ++i) + dst[i] = ctMaskSel(m, left[i], right[i]); +} + #endif #if defined(WOLFSSL_W64_WRAPPER) diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index 03312bfcc..d0231e5ff 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -126,6 +126,8 @@ WOLFSSL_LOCAL byte ctMaskNotEq(int a, int b); WOLFSSL_LOCAL byte ctMaskSel(byte m, byte a, byte b); WOLFSSL_LOCAL int ctMaskSelInt(byte m, int a, int b); WOLFSSL_LOCAL byte ctSetLTE(int a, int b); +WOLFSSL_LOCAL void ctMaskCopy(byte m, byte* dst, byte* left, byte* right, + word16 size); #endif /* NO_INLINE */ From 1727efbc2cea493f722f577bc9b3c5b0d05258f3 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 25 Jul 2022 17:48:49 +0200 Subject: [PATCH 2/5] internal.c: rsa decription buffer handling --- src/internal.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/internal.c b/src/internal.c index d83a7e236..39898165c 100644 --- a/src/internal.c +++ b/src/internal.c @@ -34730,6 +34730,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], #ifndef NO_RSA case rsa_kea: { + byte *tmpRsa; byte mask; int i; @@ -34762,6 +34763,9 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], ssl->arrays->preMasterSecret[0] = ssl->chVersion.major; ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; + tmpRsa = input + args->idx - VERSION_SZ - SECRET_LEN; + ctMaskCopy(mask, (byte*)&args->output, + (byte*)&args->output, (byte*)&tmpRsa, sizeof(args->output)); if (args->output != NULL) { /* Use random secret on error */ for (i = VERSION_SZ; i < SECRET_LEN; i++) { From 856ea2ffc8dda947cd01269ce20569b6813bcc63 Mon Sep 17 00:00:00 2001 From: Marco Oliverio Date: Mon, 25 Jul 2022 17:50:25 +0200 Subject: [PATCH 3/5] internal.c: RsaDec improvements --- src/internal.c | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/internal.c b/src/internal.c index 39898165c..77d291a02 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4626,6 +4626,10 @@ int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, word32 sigSz, int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, RsaKey* key, DerBuffer* keyBufInfo) { + word32 outSzTmp; + byte *outTmp; + byte mask; + int zero; int ret; #ifdef HAVE_PK_CALLBACKS const byte* keyBuf = NULL; @@ -4642,6 +4646,7 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, WOLFSSL_ENTER("RsaDec"); + outTmp = *out; #ifdef WOLFSSL_ASYNC_CRYPT /* initialize event */ ret = wolfSSL_AsyncInit(ssl, &key->asyncDev, WC_ASYNC_FLAG_CALL_AGAIN); @@ -4652,7 +4657,7 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, #ifdef HAVE_PK_CALLBACKS if (ssl->ctx->RsaDecCb) { void* ctx = wolfSSL_GetRsaDecCtx(ssl); - ret = ssl->ctx->RsaDecCb(ssl, in, inSz, out, keyBuf, keySz, ctx); + ret = ssl->ctx->RsaDecCb(ssl, in, inSz, &outTmp, keyBuf, keySz, ctx); } else #endif /* HAVE_PK_CALLBACKS */ @@ -4672,11 +4677,13 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, } #endif /* WOLFSSL_ASYNC_CRYPT */ - /* For positive response return in outSz */ - if (ret > 0) { - *outSz = ret; - ret = 0; - } + mask = ctMaskGT(ret, 0); + *outSz = 0; + zero = 0; + outSzTmp = (word32)ret; + ctMaskCopy(mask, (byte*)outSz, (byte*)&outSzTmp, (byte*)outSz, sizeof(*outSz)); + ctMaskCopy(mask, (byte*)&ret, (byte*)&zero, (byte*)&ret, sizeof(ret)); + ctMaskCopy(mask, (byte*)out, (byte*)&outTmp, (byte*)out, sizeof(*out)); WOLFSSL_LEAVE("RsaDec", ret); From 9c480ece66c0b8fb17af78bb4c37c4ab9581408d Mon Sep 17 00:00:00 2001 From: David Garske Date: Tue, 26 Jul 2022 15:48:58 -0700 Subject: [PATCH 4/5] Fix to use the new `outTmp`. --- src/internal.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/internal.c b/src/internal.c index 77d291a02..0ec64b148 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4667,7 +4667,7 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, if (ret != 0) return ret; #endif - ret = wc_RsaPrivateDecryptInline(in, inSz, out, key); + ret = wc_RsaPrivateDecryptInline(in, inSz, &outTmp, key); } /* Handle async pending response */ From 01aad13c384446a86d8acc57199807521fc90856 Mon Sep 17 00:00:00 2001 From: Sean Parkinson Date: Wed, 27 Jul 2022 12:02:15 +1000 Subject: [PATCH 5/5] Rework --- src/internal.c | 18 +++++++----------- wolfcrypt/src/misc.c | 11 ++++++----- wolfssl/wolfcrypt/misc.h | 3 +-- 3 files changed, 14 insertions(+), 18 deletions(-) diff --git a/src/internal.c b/src/internal.c index 0ec64b148..7b28e0037 100644 --- a/src/internal.c +++ b/src/internal.c @@ -4626,10 +4626,8 @@ int VerifyRsaSign(WOLFSSL* ssl, byte* verifySig, word32 sigSz, int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, RsaKey* key, DerBuffer* keyBufInfo) { - word32 outSzTmp; byte *outTmp; byte mask; - int zero; int ret; #ifdef HAVE_PK_CALLBACKS const byte* keyBuf = NULL; @@ -4678,12 +4676,10 @@ int RsaDec(WOLFSSL* ssl, byte* in, word32 inSz, byte** out, word32* outSz, #endif /* WOLFSSL_ASYNC_CRYPT */ mask = ctMaskGT(ret, 0); - *outSz = 0; - zero = 0; - outSzTmp = (word32)ret; - ctMaskCopy(mask, (byte*)outSz, (byte*)&outSzTmp, (byte*)outSz, sizeof(*outSz)); - ctMaskCopy(mask, (byte*)&ret, (byte*)&zero, (byte*)&ret, sizeof(ret)); - ctMaskCopy(mask, (byte*)out, (byte*)&outTmp, (byte*)out, sizeof(*out)); + *outSz = (word32)(ret & (int)(sword8)mask); + ret &= (int)(sword8)(~mask); + /* Copy pointer */ + ctMaskCopy(mask, (byte*)out, (byte*)&outTmp, sizeof(*out)); WOLFSSL_LEAVE("RsaDec", ret); @@ -34762,7 +34758,7 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], ret = args->lastErr; args->lastErr = 0; /* reset */ - /* On error 'ret' will be negative - top bit set */ + /* On error 'ret' will be negative */ mask = ((unsigned int)ret >> ((sizeof(ret) * 8) - 1)) - 1; @@ -34771,8 +34767,8 @@ static int DefTicketEncCb(WOLFSSL* ssl, byte key_name[WOLFSSL_TICKET_NAME_SZ], ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor; tmpRsa = input + args->idx - VERSION_SZ - SECRET_LEN; - ctMaskCopy(mask, (byte*)&args->output, - (byte*)&args->output, (byte*)&tmpRsa, sizeof(args->output)); + ctMaskCopy(~mask, (byte*)&args->output, (byte*)&tmpRsa, + sizeof(args->output)); if (args->output != NULL) { /* Use random secret on error */ for (i = VERSION_SZ; i < SECRET_LEN; i++) { diff --git a/wolfcrypt/src/misc.c b/wolfcrypt/src/misc.c index 7d534ffde..2c8172247 100644 --- a/wolfcrypt/src/misc.c +++ b/wolfcrypt/src/misc.c @@ -545,14 +545,15 @@ WC_STATIC WC_INLINE byte ctSetLTE(int a, int b) return (byte)(((word32)a - b - 1) >> 31); } -/* Constant time - copy size bytes from left to dst if mask is set, size bytes - * from right to dst if mask is not set */ -WC_STATIC WC_INLINE void ctMaskCopy(byte m, byte* dst, byte* left, byte* right, +/* Constant time - conditionally copy size bytes from src to dst if mask is set + */ +WC_STATIC WC_INLINE void ctMaskCopy(byte mask, byte* dst, byte* src, word16 size) { int i; - for (i = 0; i < size; ++i) - dst[i] = ctMaskSel(m, left[i], right[i]); + for (i = 0; i < size; ++i) { + dst[i] ^= (dst[i] ^ src[i]) & mask; + } } #endif diff --git a/wolfssl/wolfcrypt/misc.h b/wolfssl/wolfcrypt/misc.h index d0231e5ff..f732faeb8 100644 --- a/wolfssl/wolfcrypt/misc.h +++ b/wolfssl/wolfcrypt/misc.h @@ -126,8 +126,7 @@ WOLFSSL_LOCAL byte ctMaskNotEq(int a, int b); WOLFSSL_LOCAL byte ctMaskSel(byte m, byte a, byte b); WOLFSSL_LOCAL int ctMaskSelInt(byte m, int a, int b); WOLFSSL_LOCAL byte ctSetLTE(int a, int b); -WOLFSSL_LOCAL void ctMaskCopy(byte m, byte* dst, byte* left, byte* right, - word16 size); +WOLFSSL_LOCAL void ctMaskCopy(byte mask, byte* dst, byte* src, word16 size); #endif /* NO_INLINE */