Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 698690 Details for
Bug 908257
CVE-2013-1620 nss: TLS CBC padding timing attack [fedora-all]
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
sync. up pem's rsawrapr.c with upstream changes to softoken's rsawrapr.c
0001-sync-up-with-upstream-softokn-changes.patch (text/plain), 12.07 KB, created by
Elio Maldonado Batiz
on 2013-02-18 04:10:08 UTC
(
hide
)
Description:
sync. up pem's rsawrapr.c with upstream changes to softoken's rsawrapr.c
Filename:
MIME Type:
Creator:
Elio Maldonado Batiz
Created:
2013-02-18 04:10:08 UTC
Size:
12.07 KB
patch
obsolete
>From d6dbecfea317a468be12423595e584f43d84d8ec Mon Sep 17 00:00:00 2001 >From: Elio Maldonado <emaldona@redhat.com> >Date: Sat, 9 Feb 2013 17:11:00 -0500 >Subject: [PATCH] Sync up with upstream softokn changes > >- Disable RSA OEP case in FormatBlock, RSA_OAEP support is experimental and in a state of flux >- Numerous change upstream due to the work for TLS/DTLS 'Lucky 13' vulnerability CVE-2013-0169 >- It now compiles with the NSS_3_14_3_BETA1 source >--- > mozilla/security/nss/lib/ckfw/pem/rsawrapr.c | 338 +++++++------------------- > 1 files changed, 82 insertions(+), 256 deletions(-) > >diff --git a/mozilla/security/nss/lib/ckfw/pem/rsawrapr.c b/mozilla/security/nss/lib/ckfw/pem/rsawrapr.c >index 5ac4f39..3780d30 100644 >--- a/mozilla/security/nss/lib/ckfw/pem/rsawrapr.c >+++ b/mozilla/security/nss/lib/ckfw/pem/rsawrapr.c >@@ -46,6 +46,7 @@ > #include "sechash.h" > #include "base.h" > >+#include "lowkeyi.h" > #include "secerr.h" > > #define RSA_BLOCK_MIN_PAD_LEN 8 >@@ -54,9 +55,8 @@ > #define RSA_BLOCK_PRIVATE_PAD_OCTET 0xff > #define RSA_BLOCK_AFTER_PAD_OCTET 0x00 > >-#define OAEP_SALT_LEN 8 >-#define OAEP_PAD_LEN 8 >-#define OAEP_PAD_OCTET 0x00 >+/* Needed for RSA-PSS functions */ >+static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 0 }; > > #define FLAT_BUFSIZE 512 /* bytes to hold flattened SHA1Context. */ > >@@ -78,127 +78,39 @@ pem_PublicModulusLen(NSSLOWKEYPublicKey *pubk) > return 0; > } > >-static SHA1Context *SHA1_CloneContext(SHA1Context * original) >-{ >- SHA1Context *clone = NULL; >- unsigned char *pBuf; >- int sha1ContextSize = SHA1_FlattenSize(original); >- SECStatus frv; >- unsigned char buf[FLAT_BUFSIZE]; >- >- PORT_Assert(sizeof buf >= sha1ContextSize); >- if (sizeof buf >= sha1ContextSize) { >- pBuf = buf; >- } else { >- pBuf = nss_ZAlloc(NULL, sha1ContextSize); >- if (!pBuf) >- goto done; >- } >- >- frv = SHA1_Flatten(original, pBuf); >- if (frv == SECSuccess) { >- clone = SHA1_Resurrect(pBuf, NULL); >- memset(pBuf, 0, sha1ContextSize); >- } >- done: >- if (pBuf != buf) >- nss_ZFreeIf(pBuf); >- return clone; >+/* Constant time comparison of a single byte. >+ * Returns 1 iff a == b, otherwise returns 0. >+ * Note: For ranges of bytes, use constantTimeCompare. >+ */ >+static unsigned char constantTimeEQ8(unsigned char a, unsigned char b) { >+ unsigned char c = ~(a - b | b - a); >+ c >>= 7; >+ return c; > } > >-/* >- * Modify data by XORing it with a special hash of salt. >+/* Constant time comparison of a range of bytes. >+ * Returns 1 iff len bytes of a are identical to len bytes of b, otherwise >+ * returns 0. > */ >-static SECStatus >-oaep_xor_with_h1(unsigned char *data, unsigned int datalen, >- unsigned char *salt, unsigned int saltlen) >-{ >- SHA1Context *sha1cx; >- unsigned char *dp, *dataend; >- unsigned char end_octet; >- >- sha1cx = SHA1_NewContext(); >- if (sha1cx == NULL) { >- return SECFailure; >- } >- >- /* >- * Get a hash of salt started; we will use it several times, >- * adding in a different end octet (x00, x01, x02, ...). >- */ >- SHA1_Begin(sha1cx); >- SHA1_Update(sha1cx, salt, saltlen); >- end_octet = 0; >- >- dp = data; >- dataend = data + datalen; >- >- while (dp < dataend) { >- SHA1Context *sha1cx_h1; >- unsigned int sha1len, sha1off; >- unsigned char sha1[SHA1_LENGTH]; >- >- /* >- * Create hash of (salt || end_octet) >- */ >- sha1cx_h1 = SHA1_CloneContext(sha1cx); >- SHA1_Update(sha1cx_h1, &end_octet, 1); >- SHA1_End(sha1cx_h1, sha1, &sha1len, sizeof(sha1)); >- SHA1_DestroyContext(sha1cx_h1, PR_TRUE); >- PORT_Assert(sha1len == SHA1_LENGTH); >- >- /* >- * XOR that hash with the data. >- * When we have fewer than SHA1_LENGTH octets of data >- * left to xor, use just the low-order ones of the hash. >- */ >- sha1off = 0; >- if ((dataend - dp) < SHA1_LENGTH) >- sha1off = SHA1_LENGTH - (dataend - dp); >- while (sha1off < SHA1_LENGTH) >- *dp++ ^= sha1[sha1off++]; >- >- /* >- * Bump for next hash chunk. >- */ >- end_octet++; >- } >- >- SHA1_DestroyContext(sha1cx, PR_TRUE); >- return SECSuccess; >+static unsigned char constantTimeCompare(const unsigned char *a, >+ const unsigned char *b, >+ unsigned int len) { >+ unsigned char tmp = 0; >+ unsigned int i; >+ for (i = 0; i < len; ++i, ++a, ++b) >+ tmp |= *a ^ *b; >+ return constantTimeEQ8(0x00, tmp); > } > >-/* >- * Modify salt by XORing it with a special hash of data. >+/* Constant time conditional. >+ * Returns a if c is 1, or b if c is 0. The result is undefined if c is >+ * not 0 or 1. > */ >-static SECStatus >-oaep_xor_with_h2(unsigned char *salt, unsigned int saltlen, >- unsigned char *data, unsigned int datalen) >+static unsigned int constantTimeCondition(unsigned int c, >+ unsigned int a, >+ unsigned int b) > { >- unsigned char sha1[SHA1_LENGTH]; >- unsigned char *psalt, *psha1, *saltend; >- SECStatus rv; >- >- /* >- * Create a hash of data. >- */ >- rv = SHA1_HashBuf(sha1, data, datalen); >- if (rv != SECSuccess) { >- return rv; >- } >- >- /* >- * XOR the low-order octets of that hash with salt. >- */ >- PORT_Assert(saltlen <= SHA1_LENGTH); >- saltend = salt + saltlen; >- psalt = salt; >- psha1 = sha1 + SHA1_LENGTH - saltlen; >- while (psalt < saltend) { >- *psalt++ ^= *psha1++; >- } >- >- return SECSuccess; >+ return (~(c - 1) & a) | ((c - 1) & b); > } > > /* >@@ -212,7 +124,7 @@ static unsigned char *rsa_FormatOneBlock(unsigned modulusLen, > unsigned char *block; > unsigned char *bp; > int padLen; >- int i; >+ int i, j; > SECStatus rv; > > block = (unsigned char *) nss_ZAlloc(NULL, modulusLen); >@@ -260,124 +172,58 @@ static unsigned char *rsa_FormatOneBlock(unsigned modulusLen, > */ > case RSA_BlockPublic: > >- /* >- * 0x00 || BT || Pad || 0x00 || ActualData >- * 1 1 padLen 1 data->len >- * Pad is all non-zero random bytes. >- */ >- padLen = modulusLen - data->len - 3; >- PORT_Assert(padLen >= RSA_BLOCK_MIN_PAD_LEN); >- if (padLen < RSA_BLOCK_MIN_PAD_LEN) { >- nss_ZFreeIf(block); >- return NULL; >- } >- for (i = 0; i < padLen; i++) { >- /* Pad with non-zero random data. */ >- do { >- rv = RNG_GenerateGlobalRandomBytes(bp + i, 1); >- } while (rv == SECSuccess >- && bp[i] == RSA_BLOCK_AFTER_PAD_OCTET); >- if (rv != SECSuccess) { >- nss_ZFreeIf(block); >- return NULL; >- } >- } >- bp += padLen; >- *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; >- nsslibc_memcpy(bp, data->data, data->len); >- >- break; >- >- /* >- * Blocks intended for public-key operation, using >- * Optimal Asymmetric Encryption Padding (OAEP). >- */ >- case RSA_BlockOAEP: >- /* >- * 0x00 || BT || Modified2(Salt) || Modified1(PaddedData) >- * 1 1 OAEP_SALT_LEN OAEP_PAD_LEN + data->len [+ N] >- * >- * where: >- * PaddedData is "Pad1 || ActualData [|| Pad2]" >- * Salt is random data. >- * Pad1 is all zeros. >- * Pad2, if present, is random data. >- * (The "modified" fields are all the same length as the original >- * unmodified values; they are just xor'd with other values.) >- * >- * Modified1 is an XOR of PaddedData with a special octet >- * string constructed of iterated hashing of Salt (see below). >- * Modified2 is an XOR of Salt with the low-order octets of >- * the hash of Modified1 (see farther below ;-). >- * >- * Whew! >- */ >- >- >- /* >- * Salt >- */ >- rv = RNG_GenerateGlobalRandomBytes(bp, OAEP_SALT_LEN); >- if (rv != SECSuccess) { >- nss_ZFreeIf(block); >- return NULL; >- } >- bp += OAEP_SALT_LEN; >- >- /* >- * Pad1 >- */ >- nsslibc_memset(bp, OAEP_PAD_OCTET, OAEP_PAD_LEN); >- bp += OAEP_PAD_LEN; >- >- /* >- * Data >- */ >- nsslibc_memcpy(bp, data->data, data->len); >- bp += data->len; >- >- /* >- * Pad2 >- */ >- if (bp < (block + modulusLen)) { >- rv = RNG_GenerateGlobalRandomBytes(bp, >- block - bp + modulusLen); >- if (rv != SECSuccess) { >- nss_ZFreeIf(block); >- return NULL; >- } >- } >- >- /* >- * Now we have the following: >- * 0x00 || BT || Salt || PaddedData >- * (From this point on, "Pad1 || Data [|| Pad2]" is treated >- * as the one entity PaddedData.) >- * >- * We need to turn PaddedData into Modified1. >- */ >- if (oaep_xor_with_h1(block + 2 + OAEP_SALT_LEN, >- modulusLen - 2 - OAEP_SALT_LEN, >- block + 2, OAEP_SALT_LEN) != SECSuccess) { >- nss_ZFreeIf(block); >- return NULL; >- } >- >- /* >- * Now we have: >- * 0x00 || BT || Salt || Modified1(PaddedData) >- * >- * The remaining task is to turn Salt into Modified2. >- */ >- if (oaep_xor_with_h2(block + 2, OAEP_SALT_LEN, >- block + 2 + OAEP_SALT_LEN, >- modulusLen - 2 - OAEP_SALT_LEN) != >- SECSuccess) { >- nss_ZFreeIf(block); >- return NULL; >- } >- >- break; >+ /* >+ * 0x00 || BT || Pad || 0x00 || ActualData >+ * 1 1 padLen 1 data->len >+ * Pad is all non-zero random bytes. >+ * >+ * Build the block left to right. >+ * Fill the entire block from Pad to the end with random bytes. >+ * Use the bytes after Pad as a supply of extra random bytes from >+ * which to find replacements for the zero bytes in Pad. >+ * If we need more than that, refill the bytes after Pad with >+ * new random bytes as necessary. >+ */ >+ padLen = modulusLen - (data->len + 3); >+ PORT_Assert (padLen >= RSA_BLOCK_MIN_PAD_LEN); >+ if (padLen < RSA_BLOCK_MIN_PAD_LEN) { >+ nss_ZFreeIf (block); >+ return NULL; >+ } >+ j = modulusLen - 2; >+ rv = RNG_GenerateGlobalRandomBytes(bp, j); >+ if (rv == SECSuccess) { >+ for (i = 0; i < padLen; ) { >+ unsigned char repl; >+ /* Pad with non-zero random data. */ >+ if (bp[i] != RSA_BLOCK_AFTER_PAD_OCTET) { >+ ++i; >+ continue; >+ } >+ if (j <= padLen) { >+ rv = RNG_GenerateGlobalRandomBytes(bp + padLen, >+ modulusLen - (2 + padLen)); >+ if (rv != SECSuccess) >+ break; >+ j = modulusLen - 2; >+ } >+ do { >+ repl = bp[--j]; >+ } while (repl == RSA_BLOCK_AFTER_PAD_OCTET && j > padLen); >+ if (repl != RSA_BLOCK_AFTER_PAD_OCTET) { >+ bp[i++] = repl; >+ } >+ } >+ } >+ if (rv != SECSuccess) { >+ /*sftk_fatalError = PR_TRUE;*/ >+ nss_ZFreeIf (block); >+ return NULL; >+ } >+ bp += padLen; >+ *bp++ = RSA_BLOCK_AFTER_PAD_OCTET; >+ nsslibc_memcpy(bp, data->data, data->len); >+ break; > > default: > PORT_Assert(0); >@@ -427,26 +273,6 @@ rsa_FormatBlock(SECItem * result, unsigned modulusLen, > > break; > >- case RSA_BlockOAEP: >- /* >- * 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2]) >- * >- * The "2" below is the first octet + the second octet. >- * (The other fields do not contain the clear values, but are >- * the same length as the clear values.) >- */ >- PORT_Assert(data->len <= (modulusLen - (2 + OAEP_SALT_LEN >- + OAEP_PAD_LEN))); >- >- result->data = rsa_FormatOneBlock(modulusLen, blockType, data); >- if (result->data == NULL) { >- result->len = 0; >- return SECFailure; >- } >- result->len = modulusLen; >- >- break; >- > case RSA_BlockRaw: > /* > * Pad || ActualData >-- >1.7.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Flags:
rrelyea
: review-
Actions:
View
|
Diff
Attachments on
bug 908257
: 698690 |
698703