mirror of https://github.com/hak5/openwrt.git
wolfssl: fixes for CVE-2018-16870 & CVE-2019-13628
CVE-2018-16870: medium-severity, new variant of the Bleichenbacher attack to perform downgrade attacks against TLS, which may lead to leakage of sensible data. Backported from 3.15.7. CVE-2019-13628 (currently assigned-only): potential leak of nonce sizes when performing ECDSA signing operations. The leak is considered to be difficult to exploit but it could potentially be used maliciously to perform a lattice based timing attack. Backported from 4.1.0. Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>openwrt-18.06
parent
09bdc14419
commit
2df2b75208
|
@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk
|
||||||
|
|
||||||
PKG_NAME:=wolfssl
|
PKG_NAME:=wolfssl
|
||||||
PKG_VERSION:=3.15.3-stable
|
PKG_VERSION:=3.15.3-stable
|
||||||
PKG_RELEASE:=1
|
PKG_RELEASE:=2
|
||||||
|
|
||||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
|
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).zip
|
||||||
# PKG_SOURCE_URL:=https://www.wolfssl.com/
|
# PKG_SOURCE_URL:=https://www.wolfssl.com/
|
||||||
|
@ -21,7 +21,8 @@ PKG_INSTALL:=1
|
||||||
PKG_USE_MIPS16:=0
|
PKG_USE_MIPS16:=0
|
||||||
PKG_BUILD_PARALLEL:=1
|
PKG_BUILD_PARALLEL:=1
|
||||||
PKG_LICENSE:=GPL-2.0+
|
PKG_LICENSE:=GPL-2.0+
|
||||||
PKG_CPE_ID:=cpe:/a:yassl:cyassl
|
PKG_MAINTAINER:=Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||||
|
PKG_CPE_ID:=cpe:/a:wolfssl:wolfssl
|
||||||
|
|
||||||
PKG_CONFIG_DEPENDS:=\
|
PKG_CONFIG_DEPENDS:=\
|
||||||
CONFIG_WOLFSSL_HAS_AES_CCM CONFIG_WOLFSSL_HAS_AES_GCM \
|
CONFIG_WOLFSSL_HAS_AES_CCM CONFIG_WOLFSSL_HAS_AES_GCM \
|
||||||
|
|
|
@ -0,0 +1,562 @@
|
||||||
|
From 278d54d95de9fa80b4ac9f6dd0f900841114ca8c Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sean Parkinson <sean@wolfssl.com>
|
||||||
|
Date: Mon, 27 Aug 2018 10:16:40 +1000
|
||||||
|
Subject: [PATCH] Make RsaUnPad constant time when Block Type 2 message
|
||||||
|
|
||||||
|
(cherry picked from commit ab03f9291b040269ae21d33b9f01529ed8311728)
|
||||||
|
[cherry-pick changes]
|
||||||
|
Signed-off-by: Eneas U de Queiroz <cotequeiroz@gmail.com>
|
||||||
|
|
||||||
|
--- a/src/internal.c
|
||||||
|
+++ b/src/internal.c
|
||||||
|
@@ -24766,26 +24766,22 @@ static int DoSessionTicket(WOLFSSL* ssl,
|
||||||
|
* indistinguishable from correctly formatted RSA blocks
|
||||||
|
*/
|
||||||
|
|
||||||
|
- ret = args->lastErr;
|
||||||
|
args->lastErr = 0; /* reset */
|
||||||
|
|
||||||
|
/* build PreMasterSecret */
|
||||||
|
ssl->arrays->preMasterSecret[0] = ssl->chVersion.major;
|
||||||
|
ssl->arrays->preMasterSecret[1] = ssl->chVersion.minor;
|
||||||
|
- if (ret == 0 && args->sigSz == SECRET_LEN &&
|
||||||
|
- args->output != NULL) {
|
||||||
|
+ if (args->output != NULL) {
|
||||||
|
XMEMCPY(&ssl->arrays->preMasterSecret[VERSION_SZ],
|
||||||
|
- &args->output[VERSION_SZ],
|
||||||
|
- SECRET_LEN - VERSION_SZ);
|
||||||
|
+ &args->output[VERSION_SZ],
|
||||||
|
+ SECRET_LEN - VERSION_SZ);
|
||||||
|
}
|
||||||
|
- else {
|
||||||
|
- /* preMasterSecret has RNG and version set */
|
||||||
|
- /* return proper length and ignore error */
|
||||||
|
- /* error will be caught as decryption error */
|
||||||
|
- args->sigSz = SECRET_LEN;
|
||||||
|
- ret = 0;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
+ /* preMasterSecret has RNG and version set
|
||||||
|
+ * return proper length and ignore error
|
||||||
|
+ * error will be caught as decryption error
|
||||||
|
+ */
|
||||||
|
+ args->sigSz = SECRET_LEN;
|
||||||
|
+ ret = 0;
|
||||||
|
break;
|
||||||
|
} /* rsa_kea */
|
||||||
|
#endif /* !NO_RSA */
|
||||||
|
--- a/src/tls.c
|
||||||
|
+++ b/src/tls.c
|
||||||
|
@@ -1136,12 +1136,12 @@ static int Hmac_UpdateFinal_CT(Hmac* hma
|
||||||
|
else if (k < maxLen)
|
||||||
|
b = in[k - WOLFSSL_TLS_HMAC_INNER_SZ];
|
||||||
|
|
||||||
|
- b = ctMaskSel(atEoc, b, 0x80);
|
||||||
|
+ b = ctMaskSel(atEoc, 0x80, b);
|
||||||
|
b &= ~pastEoc;
|
||||||
|
b &= ~isOutBlock | isEocBlock;
|
||||||
|
|
||||||
|
if (j >= blockSz - 8) {
|
||||||
|
- b = ctMaskSel(isOutBlock, b, lenBytes[j - (blockSz - 8)]);
|
||||||
|
+ b = ctMaskSel(isOutBlock, lenBytes[j - (blockSz - 8)], b);
|
||||||
|
}
|
||||||
|
|
||||||
|
hashBlock[j] = b;
|
||||||
|
--- a/wolfcrypt/src/integer.c
|
||||||
|
+++ b/wolfcrypt/src/integer.c
|
||||||
|
@@ -321,6 +321,17 @@ int mp_to_unsigned_bin (mp_int * a, unsi
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)
|
||||||
|
+{
|
||||||
|
+ int i, len;
|
||||||
|
+
|
||||||
|
+ len = mp_unsigned_bin_size(a);
|
||||||
|
+
|
||||||
|
+ /* pad front w/ zeros to match length */
|
||||||
|
+ for (i = 0; i < c - len; i++)
|
||||||
|
+ b[i] = 0x00;
|
||||||
|
+ return mp_to_unsigned_bin(a, b + i);
|
||||||
|
+}
|
||||||
|
|
||||||
|
/* creates "a" then copies b into it */
|
||||||
|
int mp_init_copy (mp_int * a, mp_int * b)
|
||||||
|
--- a/wolfcrypt/src/misc.c
|
||||||
|
+++ b/wolfcrypt/src/misc.c
|
||||||
|
@@ -341,10 +341,22 @@ STATIC INLINE byte ctMaskEq(int a, int b
|
||||||
|
return 0 - (a == b);
|
||||||
|
}
|
||||||
|
|
||||||
|
-/* Constant time - select b when mask is set and a otherwise. */
|
||||||
|
+/* Constant time - mask set when a != b. */
|
||||||
|
+STATIC INLINE byte ctMaskNotEq(int a, int b)
|
||||||
|
+{
|
||||||
|
+ return 0 - (a != b);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Constant time - select a when mask is set and b otherwise. */
|
||||||
|
STATIC INLINE byte ctMaskSel(byte m, byte a, byte b)
|
||||||
|
{
|
||||||
|
- return (a & ~m) | (b & m);
|
||||||
|
+ return (b & ~m) | (a & m);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Constant time - select integer a when mask is set and integer b otherwise. */
|
||||||
|
+STATIC INLINE int ctMaskSelInt(byte m, int a, int b)
|
||||||
|
+{
|
||||||
|
+ return (b & (~(int)(char)m)) | (a & ((int)(char)m));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Constant time - bit set when a <= b. */
|
||||||
|
--- a/wolfcrypt/src/rsa.c
|
||||||
|
+++ b/wolfcrypt/src/rsa.c
|
||||||
|
@@ -989,10 +989,8 @@ static int RsaUnPad_OAEP(byte *pkcsBlock
|
||||||
|
ret += pkcsBlock[idx++] ^ 0x01; /* separator value is 0x01 */
|
||||||
|
ret += pkcsBlock[0] ^ 0x00; /* Y, the first value, should be 0 */
|
||||||
|
|
||||||
|
- if (ret != 0) {
|
||||||
|
- WOLFSSL_MSG("RsaUnPad_OAEP: Padding Error");
|
||||||
|
- return BAD_PADDING_E;
|
||||||
|
- }
|
||||||
|
+ /* Return 0 data length on error. */
|
||||||
|
+ idx = ctMaskSelInt(ctMaskEq(ret, 0), idx, pkcsBlockLen);
|
||||||
|
|
||||||
|
/* adjust pointer to correct location in array and return size of M */
|
||||||
|
*output = (byte*)(pkcsBlock + idx);
|
||||||
|
@@ -1078,48 +1076,60 @@ static int RsaUnPad_PSS(byte *pkcsBlock,
|
||||||
|
/* UnPad plaintext, set start to *output, return length of plaintext,
|
||||||
|
* < 0 on error */
|
||||||
|
static int RsaUnPad(const byte *pkcsBlock, unsigned int pkcsBlockLen,
|
||||||
|
- byte **output, byte padValue)
|
||||||
|
+ byte **output, byte padValue)
|
||||||
|
{
|
||||||
|
- word32 maxOutputLen = (pkcsBlockLen > 10) ? (pkcsBlockLen - 10) : 0;
|
||||||
|
- word32 invalid = 0;
|
||||||
|
- word32 i = 1;
|
||||||
|
- word32 outputLen;
|
||||||
|
+ int ret;
|
||||||
|
+ word32 i;
|
||||||
|
+ byte invalid = 0;
|
||||||
|
|
||||||
|
if (output == NULL || pkcsBlockLen == 0) {
|
||||||
|
return BAD_FUNC_ARG;
|
||||||
|
}
|
||||||
|
|
||||||
|
- if (pkcsBlock[0] != 0x0) { /* skip past zero */
|
||||||
|
- invalid = 1;
|
||||||
|
- }
|
||||||
|
- pkcsBlock++; pkcsBlockLen--;
|
||||||
|
+ if (padValue == RSA_BLOCK_TYPE_1) {
|
||||||
|
+ /* First byte must be 0x00 and Second byte, block type, 0x01 */
|
||||||
|
+ if (pkcsBlock[0] != 0 || pkcsBlock[1] != RSA_BLOCK_TYPE_1) {
|
||||||
|
+ WOLFSSL_MSG("RsaUnPad error, invalid formatting");
|
||||||
|
+ return RSA_PAD_E;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- /* Require block type padValue */
|
||||||
|
- invalid = (pkcsBlock[0] != padValue) || invalid;
|
||||||
|
+ /* check the padding until we find the separator */
|
||||||
|
+ for (i = 2; i < pkcsBlockLen && pkcsBlock[i++] == 0xFF; ) { }
|
||||||
|
|
||||||
|
- /* verify the padding until we find the separator */
|
||||||
|
- if (padValue == RSA_BLOCK_TYPE_1) {
|
||||||
|
- while (i<pkcsBlockLen && pkcsBlock[i++] == 0xFF) {/* Null body */}
|
||||||
|
- }
|
||||||
|
- else {
|
||||||
|
- while (i<pkcsBlockLen && pkcsBlock[i++]) {/* Null body */}
|
||||||
|
- }
|
||||||
|
+ /* Minimum of 11 bytes of pre-message data and must have separator. */
|
||||||
|
+ if (i < RSA_MIN_PAD_SZ || pkcsBlock[i-1] != 0) {
|
||||||
|
+ WOLFSSL_MSG("RsaUnPad error, bad formatting");
|
||||||
|
+ return RSA_PAD_E;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
- if (!(i==pkcsBlockLen || pkcsBlock[i-1]==0)) {
|
||||||
|
- WOLFSSL_MSG("RsaUnPad error, bad formatting");
|
||||||
|
- return RSA_PAD_E;
|
||||||
|
+ *output = (byte *)(pkcsBlock + i);
|
||||||
|
+ ret = pkcsBlockLen - i;
|
||||||
|
}
|
||||||
|
+ else {
|
||||||
|
+ word32 j;
|
||||||
|
+ byte pastSep = 0;
|
||||||
|
|
||||||
|
- outputLen = pkcsBlockLen - i;
|
||||||
|
- invalid = (outputLen > maxOutputLen) || invalid;
|
||||||
|
+ /* Decrypted with private key - unpad must be constant time. */
|
||||||
|
+ for (i = 0, j = 2; j < pkcsBlockLen; j++) {
|
||||||
|
+ /* Update i if not passed the separator and at separator. */
|
||||||
|
+ i |= (~pastSep) & ctMaskEq(pkcsBlock[j], 0x00) & (j + 1);
|
||||||
|
+ pastSep |= ctMaskEq(pkcsBlock[j], 0x00);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Minimum of 11 bytes of pre-message data - including leading 0x00. */
|
||||||
|
+ invalid |= ctMaskLT(i, RSA_MIN_PAD_SZ);
|
||||||
|
+ /* Must have seen separator. */
|
||||||
|
+ invalid |= ~pastSep;
|
||||||
|
+ /* First byte must be 0x00. */
|
||||||
|
+ invalid |= ctMaskNotEq(pkcsBlock[0], 0x00);
|
||||||
|
+ /* Check against expected block type: padValue */
|
||||||
|
+ invalid |= ctMaskNotEq(pkcsBlock[1], padValue);
|
||||||
|
|
||||||
|
- if (invalid) {
|
||||||
|
- WOLFSSL_MSG("RsaUnPad error, invalid formatting");
|
||||||
|
- return RSA_PAD_E;
|
||||||
|
+ *output = (byte *)(pkcsBlock + i);
|
||||||
|
+ ret = ((int)~invalid) & (pkcsBlockLen - i);
|
||||||
|
}
|
||||||
|
|
||||||
|
- *output = (byte *)(pkcsBlock + i);
|
||||||
|
- return outputLen;
|
||||||
|
+ return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* helper function to direct unpadding
|
||||||
|
@@ -1249,7 +1259,7 @@ static int wc_RsaFunctionSync(const byte
|
||||||
|
mp_int rnd, rndi;
|
||||||
|
#endif
|
||||||
|
int ret = 0;
|
||||||
|
- word32 keyLen, len;
|
||||||
|
+ word32 keyLen;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef WOLFSSL_HAVE_SP_RSA
|
||||||
|
@@ -1308,6 +1318,7 @@ static int wc_RsaFunctionSync(const byte
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef TEST_UNPAD_CONSTANT_TIME
|
||||||
|
if (mp_read_unsigned_bin(&tmp, (byte*)in, inLen) != MP_OKAY)
|
||||||
|
ERROR_OUT(MP_READ_E);
|
||||||
|
|
||||||
|
@@ -1418,21 +1429,18 @@ static int wc_RsaFunctionSync(const byte
|
||||||
|
ERROR_OUT(RSA_BUFFER_E);
|
||||||
|
}
|
||||||
|
|
||||||
|
- len = mp_unsigned_bin_size(&tmp);
|
||||||
|
-
|
||||||
|
- /* pad front w/ zeros to match key length */
|
||||||
|
- while (len < keyLen) {
|
||||||
|
- *out++ = 0x00;
|
||||||
|
- len++;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
*outLen = keyLen;
|
||||||
|
-
|
||||||
|
- /* convert */
|
||||||
|
- if (mp_to_unsigned_bin(&tmp, out) != MP_OKAY)
|
||||||
|
+ if (mp_to_unsigned_bin_len(&tmp, out, keyLen) != MP_OKAY)
|
||||||
|
ERROR_OUT(MP_TO_E);
|
||||||
|
|
||||||
|
done:
|
||||||
|
+#else
|
||||||
|
+ (void)type;
|
||||||
|
+ (void)key;
|
||||||
|
+ (void)keyLen;
|
||||||
|
+ XMEMCPY(out, in, inLen);
|
||||||
|
+ *outLen = inLen;
|
||||||
|
+#endif
|
||||||
|
mp_clear(&tmp);
|
||||||
|
#ifdef WC_RSA_BLINDING
|
||||||
|
if (type == RSA_PRIVATE_DECRYPT || type == RSA_PRIVATE_ENCRYPT) {
|
||||||
|
@@ -1633,6 +1641,7 @@ int wc_RsaFunction(const byte* in, word3
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
+#ifndef TEST_UNPAD_CONSTANT_TIME
|
||||||
|
#ifndef NO_RSA_BOUNDS_CHECK
|
||||||
|
if (type == RSA_PRIVATE_DECRYPT &&
|
||||||
|
key->state == RSA_STATE_DECRYPT_EXPTMOD) {
|
||||||
|
@@ -1667,6 +1676,7 @@ int wc_RsaFunction(const byte* in, word3
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
#endif /* NO_RSA_BOUNDS_CHECK */
|
||||||
|
+#endif
|
||||||
|
|
||||||
|
#if defined(WOLFSSL_ASYNC_CRYPT) && defined(WC_ASYNC_ENABLE_RSA)
|
||||||
|
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
|
||||||
|
@@ -1880,7 +1890,8 @@ static int RsaPrivateDecryptEx(byte* in,
|
||||||
|
|
||||||
|
/* if not doing this inline then allocate a buffer for it */
|
||||||
|
if (outPtr == NULL) {
|
||||||
|
- key->data = (byte*)XMALLOC(inLen, key->heap, DYNAMIC_TYPE_WOLF_BIGINT);
|
||||||
|
+ key->data = (byte*)XMALLOC(inLen, key->heap,
|
||||||
|
+ DYNAMIC_TYPE_WOLF_BIGINT);
|
||||||
|
key->dataIsAlloc = 1;
|
||||||
|
if (key->data == NULL) {
|
||||||
|
ret = MEMORY_E;
|
||||||
|
@@ -1909,20 +1920,29 @@ static int RsaPrivateDecryptEx(byte* in,
|
||||||
|
ret = wc_RsaUnPad_ex(key->data, key->dataLen, &pad, pad_value, pad_type,
|
||||||
|
hash, mgf, label, labelSz, saltLen,
|
||||||
|
mp_count_bits(&key->n), key->heap);
|
||||||
|
- if (ret > 0 && ret <= (int)outLen && pad != NULL) {
|
||||||
|
+ if (rsa_type == RSA_PUBLIC_DECRYPT && ret > (int)outLen)
|
||||||
|
+ ret = RSA_BUFFER_E;
|
||||||
|
+ else if (ret >= 0 && pad != NULL) {
|
||||||
|
+ char c;
|
||||||
|
+
|
||||||
|
/* only copy output if not inline */
|
||||||
|
if (outPtr == NULL) {
|
||||||
|
- XMEMCPY(out, pad, ret);
|
||||||
|
+ word32 i, j;
|
||||||
|
+ int start = (int)((size_t)pad - (size_t)key->data);
|
||||||
|
+
|
||||||
|
+ for (i = 0, j = 0; j < key->dataLen; j++) {
|
||||||
|
+ out[i] = key->data[j];
|
||||||
|
+ c = ctMaskGTE(j, start);
|
||||||
|
+ c &= ctMaskLT(i, outLen);
|
||||||
|
+ /* 0 - no add, -1 add */
|
||||||
|
+ i += -c;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
- else {
|
||||||
|
+ else
|
||||||
|
*outPtr = pad;
|
||||||
|
- }
|
||||||
|
- }
|
||||||
|
- else if (ret >= 0) {
|
||||||
|
- ret = RSA_BUFFER_E;
|
||||||
|
- }
|
||||||
|
- if (ret < 0) {
|
||||||
|
- break;
|
||||||
|
+
|
||||||
|
+ ret = ctMaskSelInt(ctMaskLTE(ret, outLen), ret, RSA_BUFFER_E);
|
||||||
|
+ ret = ctMaskSelInt(ctMaskNotEq(ret, 0), ret, RSA_BUFFER_E);
|
||||||
|
}
|
||||||
|
|
||||||
|
key->state = RSA_STATE_DECRYPT_RES;
|
||||||
|
@@ -1934,12 +1954,14 @@ static int RsaPrivateDecryptEx(byte* in,
|
||||||
|
defined(HAVE_CAVIUM)
|
||||||
|
if (key->asyncDev.marker == WOLFSSL_ASYNC_MARKER_RSA &&
|
||||||
|
pad_type != WC_RSA_PSS_PAD) {
|
||||||
|
- /* convert result */
|
||||||
|
- byte* dataLen = (byte*)&key->dataLen;
|
||||||
|
- ret = (dataLen[0] << 8) | (dataLen[1]);
|
||||||
|
+ if (ret > 0) {
|
||||||
|
+ /* convert result */
|
||||||
|
+ byte* dataLen = (byte*)&key->dataLen;
|
||||||
|
+ ret = (dataLen[0] << 8) | (dataLen[1]);
|
||||||
|
|
||||||
|
- if (outPtr)
|
||||||
|
- *outPtr = in;
|
||||||
|
+ if (outPtr)
|
||||||
|
+ *outPtr = in;
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
break;
|
||||||
|
--- a/wolfcrypt/src/sp_int.c
|
||||||
|
+++ b/wolfcrypt/src/sp_int.c
|
||||||
|
@@ -286,7 +286,8 @@ int sp_leading_bit(sp_int* a)
|
||||||
|
* The array must be large enough for encoded number - use mp_unsigned_bin_size
|
||||||
|
* to calculate the number of bytes required.
|
||||||
|
*
|
||||||
|
- * a SP integer.
|
||||||
|
+ * a SP integer.
|
||||||
|
+ * out Array to put encoding into.
|
||||||
|
* returns MP_OKAY always.
|
||||||
|
*/
|
||||||
|
int sp_to_unsigned_bin(sp_int* a, byte* out)
|
||||||
|
@@ -305,6 +306,31 @@ int sp_to_unsigned_bin(sp_int* a, byte*
|
||||||
|
return MP_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Convert the big number to an array of bytes in big-endian format.
|
||||||
|
+ * The array must be large enough for encoded number - use mp_unsigned_bin_size
|
||||||
|
+ * to calculate the number of bytes required.
|
||||||
|
+ * Front-pads the output array with zeros make number the size of the array.
|
||||||
|
+ *
|
||||||
|
+ * a SP integer.
|
||||||
|
+ * out Array to put encoding into.
|
||||||
|
+ * outSz Size of the array.
|
||||||
|
+ * returns MP_OKAY always.
|
||||||
|
+ */
|
||||||
|
+int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz)
|
||||||
|
+{
|
||||||
|
+ int i, j, b;
|
||||||
|
+
|
||||||
|
+ j = outSz - 1;
|
||||||
|
+ for (i=0; j>=0; i++) {
|
||||||
|
+ for (b = 0; b < SP_WORD_SIZE; b += 8) {
|
||||||
|
+ out[j--] = a->dp[i] >> b;
|
||||||
|
+ if (j < 0)
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return MP_OKAY;
|
||||||
|
+}
|
||||||
|
/* Ensure the data in the big number is zeroed.
|
||||||
|
*
|
||||||
|
* a SP integer.
|
||||||
|
--- a/wolfcrypt/src/tfm.c
|
||||||
|
+++ b/wolfcrypt/src/tfm.c
|
||||||
|
@@ -1964,6 +1964,48 @@ void fp_to_unsigned_bin(fp_int *a, unsig
|
||||||
|
fp_reverse (b, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
+int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c)
|
||||||
|
+{
|
||||||
|
+#if DIGIT_BIT == 64 || DIGIT_BIT == 32
|
||||||
|
+ int i, j, x;
|
||||||
|
+
|
||||||
|
+ for (x=c-1,j=0,i=0; x >= 0; x--) {
|
||||||
|
+ b[x] = (unsigned char)(a->dp[i] >> j);
|
||||||
|
+ j += 8;
|
||||||
|
+ i += j == DIGIT_BIT;
|
||||||
|
+ j &= DIGIT_BIT - 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return FP_OKAY;
|
||||||
|
+#else
|
||||||
|
+ int x;
|
||||||
|
+#ifndef WOLFSSL_SMALL_STACK
|
||||||
|
+ fp_int t[1];
|
||||||
|
+#else
|
||||||
|
+ fp_int *t;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
+ t = (fp_int*)XMALLOC(sizeof(fp_int), NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
+ if (t == NULL)
|
||||||
|
+ return FP_MEM;
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
+ fp_init_copy(t, a);
|
||||||
|
+
|
||||||
|
+ for (x = 0; x < c; x++) {
|
||||||
|
+ b[x] = (unsigned char) (t->dp[0] & 255);
|
||||||
|
+ fp_div_2d (t, 8, t, NULL);
|
||||||
|
+ }
|
||||||
|
+ fp_reverse (b, x);
|
||||||
|
+
|
||||||
|
+#ifdef WOLFSSL_SMALL_STACK
|
||||||
|
+ XFREE(t, NULL, DYNAMIC_TYPE_TMP_BUFFER);
|
||||||
|
+#endif
|
||||||
|
+ return FP_OKAY;
|
||||||
|
+#endif
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
int fp_unsigned_bin_size(fp_int *a)
|
||||||
|
{
|
||||||
|
int size = fp_count_bits (a);
|
||||||
|
@@ -2435,6 +2477,10 @@ int mp_to_unsigned_bin (mp_int * a, unsi
|
||||||
|
return MP_OKAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
+int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c)
|
||||||
|
+{
|
||||||
|
+ return fp_to_unsigned_bin_len(a, b, c);
|
||||||
|
+}
|
||||||
|
/* reads a unsigned char array, assumes the msb is stored first [big endian] */
|
||||||
|
int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c)
|
||||||
|
{
|
||||||
|
--- a/wolfssl/wolfcrypt/integer.h
|
||||||
|
+++ b/wolfssl/wolfcrypt/integer.h
|
||||||
|
@@ -277,6 +277,7 @@ MP_API int mp_unsigned_bin_size(mp_int
|
||||||
|
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
|
||||||
|
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
|
||||||
|
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
|
||||||
|
+MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
|
||||||
|
MP_API int mp_exptmod (mp_int * G, mp_int * X, mp_int * P, mp_int * Y);
|
||||||
|
/* end functions needed by Rsa */
|
||||||
|
|
||||||
|
--- a/wolfssl/wolfcrypt/misc.h
|
||||||
|
+++ b/wolfssl/wolfcrypt/misc.h
|
||||||
|
@@ -97,7 +97,9 @@ WOLFSSL_LOCAL byte ctMaskGTE(int a, int
|
||||||
|
WOLFSSL_LOCAL byte ctMaskLT(int a, int b);
|
||||||
|
WOLFSSL_LOCAL byte ctMaskLTE(int a, int b);
|
||||||
|
WOLFSSL_LOCAL byte ctMaskEq(int a, int b);
|
||||||
|
+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);
|
||||||
|
|
||||||
|
#endif /* NO_INLINE */
|
||||||
|
--- a/wolfssl/wolfcrypt/sp_int.h
|
||||||
|
+++ b/wolfssl/wolfcrypt/sp_int.h
|
||||||
|
@@ -119,7 +119,8 @@ MP_API int sp_read_radix(sp_int* a, cons
|
||||||
|
MP_API int sp_cmp(sp_int* a, sp_int* b);
|
||||||
|
MP_API int sp_count_bits(sp_int* a);
|
||||||
|
MP_API int sp_leading_bit(sp_int* a);
|
||||||
|
-MP_API int sp_to_unsigned_bin(sp_int* a, byte* in);
|
||||||
|
+MP_API int sp_to_unsigned_bin(sp_int* a, byte* out);
|
||||||
|
+MP_API int sp_to_unsigned_bin_len(sp_int* a, byte* out, int outSz);
|
||||||
|
MP_API void sp_forcezero(sp_int* a);
|
||||||
|
MP_API int sp_copy(sp_int* a, sp_int* b);
|
||||||
|
MP_API int sp_set(sp_int* a, sp_int_digit d);
|
||||||
|
@@ -156,30 +157,31 @@ typedef sp_digit mp_digit;
|
||||||
|
|
||||||
|
#define mp_free(a)
|
||||||
|
|
||||||
|
-#define mp_init sp_init
|
||||||
|
-#define mp_init_multi sp_init_multi
|
||||||
|
-#define mp_clear sp_clear
|
||||||
|
-#define mp_read_unsigned_bin sp_read_unsigned_bin
|
||||||
|
-#define mp_unsigned_bin_size sp_unsigned_bin_size
|
||||||
|
-#define mp_read_radix sp_read_radix
|
||||||
|
-#define mp_cmp sp_cmp
|
||||||
|
-#define mp_count_bits sp_count_bits
|
||||||
|
-#define mp_leading_bit sp_leading_bit
|
||||||
|
-#define mp_to_unsigned_bin sp_to_unsigned_bin
|
||||||
|
-#define mp_forcezero sp_forcezero
|
||||||
|
-#define mp_copy sp_copy
|
||||||
|
-#define mp_set sp_set
|
||||||
|
-#define mp_iszero sp_iszero
|
||||||
|
-#define mp_clamp sp_clamp
|
||||||
|
-#define mp_grow sp_grow
|
||||||
|
-#define mp_sub_d sp_sub_d
|
||||||
|
-#define mp_cmp_d sp_cmp_d
|
||||||
|
-#define mp_mod sp_mod
|
||||||
|
-#define mp_zero sp_zero
|
||||||
|
-#define mp_add_d sp_add_d
|
||||||
|
-#define mp_lshd sp_lshd
|
||||||
|
-#define mp_add sp_add
|
||||||
|
-#define mp_isodd sp_isodd
|
||||||
|
+#define mp_init sp_init
|
||||||
|
+#define mp_init_multi sp_init_multi
|
||||||
|
+#define mp_clear sp_clear
|
||||||
|
+#define mp_read_unsigned_bin sp_read_unsigned_bin
|
||||||
|
+#define mp_unsigned_bin_size sp_unsigned_bin_size
|
||||||
|
+#define mp_read_radix sp_read_radix
|
||||||
|
+#define mp_cmp sp_cmp
|
||||||
|
+#define mp_count_bits sp_count_bits
|
||||||
|
+#define mp_leading_bit sp_leading_bit
|
||||||
|
+#define mp_to_unsigned_bin sp_to_unsigned_bin
|
||||||
|
+#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len
|
||||||
|
+#define mp_forcezero sp_forcezero
|
||||||
|
+#define mp_copy sp_copy
|
||||||
|
+#define mp_set sp_set
|
||||||
|
+#define mp_iszero sp_iszero
|
||||||
|
+#define mp_clamp sp_clamp
|
||||||
|
+#define mp_grow sp_grow
|
||||||
|
+#define mp_sub_d sp_sub_d
|
||||||
|
+#define mp_cmp_d sp_cmp_d
|
||||||
|
+#define mp_mod sp_mod
|
||||||
|
+#define mp_zero sp_zero
|
||||||
|
+#define mp_add_d sp_add_d
|
||||||
|
+#define mp_lshd sp_lshd
|
||||||
|
+#define mp_add sp_add
|
||||||
|
+#define mp_isodd sp_isodd
|
||||||
|
|
||||||
|
#define MP_INT_DEFINED
|
||||||
|
|
||||||
|
--- a/wolfssl/wolfcrypt/tfm.h
|
||||||
|
+++ b/wolfssl/wolfcrypt/tfm.h
|
||||||
|
@@ -563,6 +563,7 @@ int fp_leading_bit(fp_int *a);
|
||||||
|
int fp_unsigned_bin_size(fp_int *a);
|
||||||
|
void fp_read_unsigned_bin(fp_int *a, const unsigned char *b, int c);
|
||||||
|
void fp_to_unsigned_bin(fp_int *a, unsigned char *b);
|
||||||
|
+int fp_to_unsigned_bin_len(fp_int *a, unsigned char *b, int c);
|
||||||
|
int fp_to_unsigned_bin_at_pos(int x, fp_int *t, unsigned char *b);
|
||||||
|
|
||||||
|
/*int fp_signed_bin_size(fp_int *a);*/
|
||||||
|
@@ -686,6 +687,7 @@ MP_API int mp_unsigned_bin_size(mp_int
|
||||||
|
MP_API int mp_read_unsigned_bin (mp_int * a, const unsigned char *b, int c);
|
||||||
|
MP_API int mp_to_unsigned_bin_at_pos(int x, mp_int *t, unsigned char *b);
|
||||||
|
MP_API int mp_to_unsigned_bin (mp_int * a, unsigned char *b);
|
||||||
|
+MP_API int mp_to_unsigned_bin_len(mp_int * a, unsigned char *b, int c);
|
||||||
|
|
||||||
|
MP_API int mp_sub_d(fp_int *a, fp_digit b, fp_int *c);
|
||||||
|
MP_API int mp_copy(fp_int* a, fp_int* b);
|
|
@ -0,0 +1,98 @@
|
||||||
|
From ba4d612892bf6e3aae9cca7edce2a6d6b43e3e22 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Sean Parkinson <sean@wolfssl.com>
|
||||||
|
Date: Wed, 17 Jul 2019 08:26:02 +1000
|
||||||
|
Subject: [PATCH] Improve nonce use in ECC mulmod
|
||||||
|
|
||||||
|
(cherry picked from commit 483f6a5acd9808b405306661c121aa6407464dc2)
|
||||||
|
|
||||||
|
--- a/wolfcrypt/src/ecc.c
|
||||||
|
+++ b/wolfcrypt/src/ecc.c
|
||||||
|
@@ -2039,7 +2039,7 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
|
||||||
|
#define M_POINTS 8
|
||||||
|
int first = 1, bitbuf = 0, bitcpy = 0, j;
|
||||||
|
#else
|
||||||
|
- #define M_POINTS 3
|
||||||
|
+ #define M_POINTS 4
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ecc_point *tG, *M[M_POINTS];
|
||||||
|
@@ -2253,7 +2253,9 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
|
||||||
|
mode = 0;
|
||||||
|
bitcnt = 1;
|
||||||
|
buf = 0;
|
||||||
|
- digidx = get_digit_count(k) - 1;
|
||||||
|
+ digidx = get_digit_count(modulus) - 1;
|
||||||
|
+ /* The order MAY be 1 bit longer than the modulus. */
|
||||||
|
+ digidx += (modulus->dp[digidx] >> (DIGIT_BIT-1));
|
||||||
|
|
||||||
|
/* perform ops */
|
||||||
|
if (err == MP_OKAY) {
|
||||||
|
@@ -2272,25 +2274,53 @@ int wc_ecc_mulmod_ex(mp_int* k, ecc_poin
|
||||||
|
i = (buf >> (DIGIT_BIT - 1)) & 1;
|
||||||
|
buf <<= 1;
|
||||||
|
|
||||||
|
- if (mode == 0 && i == 0) {
|
||||||
|
+ if (mode == 0) {
|
||||||
|
+ mode = i;
|
||||||
|
/* timing resistant - dummy operations */
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
- err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
|
||||||
|
+ err = ecc_projective_add_point(M[1], M[2], M[2], a, modulus,
|
||||||
|
mp);
|
||||||
|
+#ifdef WC_NO_CACHE_RESISTANT
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
- err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
|
||||||
|
- if (err == MP_OKAY)
|
||||||
|
- continue;
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- if (mode == 0 && i == 1) {
|
||||||
|
- mode = 1;
|
||||||
|
- /* timing resistant - dummy operations */
|
||||||
|
- if (err == MP_OKAY)
|
||||||
|
- err = ecc_projective_add_point(M[0], M[1], M[2], a, modulus,
|
||||||
|
- mp);
|
||||||
|
- if (err == MP_OKAY)
|
||||||
|
- err = ecc_projective_dbl_point(M[1], M[2], a, modulus, mp);
|
||||||
|
+ err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
|
||||||
|
+#else
|
||||||
|
+ /* instead of using M[i] for double, which leaks key bit to cache
|
||||||
|
+ * monitor, use M[2] as temp, make sure address calc is constant,
|
||||||
|
+ * keep M[0] and M[1] in cache */
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy((mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->x & wc_off_on_addr[i])),
|
||||||
|
+ M[2]->x);
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy((mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->y & wc_off_on_addr[i])),
|
||||||
|
+ M[2]->y);
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy((mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->z & wc_off_on_addr[i])),
|
||||||
|
+ M[2]->z);
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = ecc_projective_dbl_point(M[2], M[3], a, modulus, mp);
|
||||||
|
+ /* copy M[2] back to M[i] */
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy(M[2]->x,
|
||||||
|
+ (mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->x & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->x & wc_off_on_addr[i])) );
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy(M[2]->y,
|
||||||
|
+ (mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->y & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->y & wc_off_on_addr[i])) );
|
||||||
|
+ if (err == MP_OKAY)
|
||||||
|
+ err = mp_copy(M[2]->z,
|
||||||
|
+ (mp_int*)
|
||||||
|
+ ( ((wolfssl_word)M[0]->z & wc_off_on_addr[i^1]) +
|
||||||
|
+ ((wolfssl_word)M[1]->z & wc_off_on_addr[i])) );
|
||||||
|
+#endif
|
||||||
|
if (err == MP_OKAY)
|
||||||
|
continue;
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
--- a/configure.ac
|
--- a/configure.ac
|
||||||
+++ b/configure.ac
|
+++ b/configure.ac
|
||||||
@@ -4140,7 +4140,6 @@ AC_CONFIG_FILES([support/wolfssl.pc])
|
@@ -4198,7 +4198,6 @@ AC_CONFIG_FILES([stamp-h], [echo timesta
|
||||||
AC_CONFIG_FILES([rpm/spec])
|
AC_CONFIG_FILES([Makefile wolfssl/version.h wolfssl/options.h cyassl/options.h support/wolfssl.pc rpm/spec])
|
||||||
|
|
||||||
AX_CREATE_GENERIC_CONFIG
|
AX_CREATE_GENERIC_CONFIG
|
||||||
-AX_AM_JOBSERVER([yes])
|
-AX_AM_JOBSERVER([yes])
|
||||||
|
|
Loading…
Reference in New Issue