Bug 839141 - Upgrade Mozilla to NSS 3.14.3, starting with Beta1, r=ekr
authorKai Engert <kaie@kuix.de>
Sun, 10 Feb 2013 01:11:00 +0100
changeset 121452 aab96936a1776d482efc4b1248221847ef3ae76f
parent 121451 f8e8b2be32e653a1cab82f7a5385eb3ec31179c6
child 121453 29dd80c95b7dc9e26b547bd90444789f474ebe14
push id24285
push userryanvm@gmail.com
push dateSun, 10 Feb 2013 01:48:41 +0000
treeherdermozilla-central@29dd80c95b7d [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersekr
bugs839141
milestone21.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 839141 - Upgrade Mozilla to NSS 3.14.3, starting with Beta1, r=ekr
security/nss/TAG-INFO
security/nss/TAG-INFO-CKBI
security/nss/lib/freebl/blapi.h
security/nss/lib/freebl/ecl/ecp_aff.c
security/nss/lib/freebl/hmacct.c
security/nss/lib/freebl/hmacct.h
security/nss/lib/freebl/ldvector.c
security/nss/lib/freebl/loader.c
security/nss/lib/freebl/loader.h
security/nss/lib/freebl/manifest.mn
security/nss/lib/freebl/md5.c
security/nss/lib/freebl/rawhash.c
security/nss/lib/freebl/sha512.c
security/nss/lib/freebl/sha_fast.c
security/nss/lib/freebl/sha_fast.h
security/nss/lib/nss/nss.def
security/nss/lib/nss/nss.h
security/nss/lib/pk11wrap/pk11obj.c
security/nss/lib/pk11wrap/pk11pub.h
security/nss/lib/pkcs7/p7decode.c
security/nss/lib/pkcs7/secpkcs7.h
security/nss/lib/smime/smime.def
security/nss/lib/softoken/manifest.mn
security/nss/lib/softoken/pkcs11.c
security/nss/lib/softoken/pkcs11c.c
security/nss/lib/softoken/pkcs11i.h
security/nss/lib/softoken/rsawrapr.c
security/nss/lib/softoken/sdb.c
security/nss/lib/softoken/sftkhmac.c
security/nss/lib/softoken/softkver.h
security/nss/lib/softoken/softoken.h
security/nss/lib/softoken/softoknt.h
security/nss/lib/ssl/ssl3con.c
security/nss/lib/util/hasht.h
security/nss/lib/util/nssutil.h
security/nss/lib/util/pkcs11n.h
security/nss/tests/ssl/ssl.sh
--- a/security/nss/TAG-INFO
+++ b/security/nss/TAG-INFO
@@ -1,1 +1,1 @@
-NSS_3_14_2_RTM
+NSS_3_14_3_BETA1
--- a/security/nss/TAG-INFO-CKBI
+++ b/security/nss/TAG-INFO-CKBI
@@ -1,1 +1,1 @@
-NSS_3_14_2_RTM
+NSS_3_14_3_BETA1
--- a/security/nss/lib/freebl/blapi.h
+++ b/security/nss/lib/freebl/blapi.h
@@ -1,15 +1,15 @@
 /*
  * crypto.h - public data structures and prototypes for the crypto library
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: blapi.h,v 1.49 2012/10/11 00:10:26 rrelyea%redhat.com Exp $ */
+/* $Id: blapi.h,v 1.50 2013/02/05 18:10:42 wtc%google.com Exp $ */
 
 #ifndef _BLAPI_H_
 #define _BLAPI_H_
 
 #include "blapit.h"
 #include "hasht.h"
 #include "alghmac.h"
 
@@ -870,16 +870,28 @@ extern void MD5_Update(MD5Context *cx,
 **	"digestLen" where the digest length (16) is stored
 **	"maxDigestLen" the maximum amount of data that can ever be
 **	   stored in "digest"
 */
 extern void MD5_End(MD5Context *cx, unsigned char *digest,
 		    unsigned int *digestLen, unsigned int maxDigestLen);
 
 /*
+** Export the raw state of the MD5 hash without appending the standard padding
+** and length bytes. Produce the digested results in "digest"
+**	"cx" the context
+**	"digest" where the 16 bytes of digest data are stored
+**	"digestLen" where the digest length (16) is stored (optional)
+**	"maxDigestLen" the maximum amount of data that can ever be
+**	   stored in "digest"
+*/
+extern void MD5_EndRaw(MD5Context *cx, unsigned char *digest,
+		       unsigned int *digestLen, unsigned int maxDigestLen);
+
+/*
  * Return the the size of a buffer needed to flatten the MD5 Context into
  *    "cx" the context
  *  returns size;
  */
 extern unsigned int MD5_FlattenSize(MD5Context *cx);
 
 /*
  * Flatten the MD5 Context into a buffer:
@@ -1026,16 +1038,28 @@ extern void SHA1_Update(SHA1Context *cx,
 **	"digestLen" where the digest length (20) is stored
 **	"maxDigestLen" the maximum amount of data that can ever be
 **	   stored in "digest"
 */
 extern void SHA1_End(SHA1Context *cx, unsigned char *digest,
 		     unsigned int *digestLen, unsigned int maxDigestLen);
 
 /*
+** Export the current state of the SHA-1 hash without appending the standard
+** padding and length. Produce the digested results in "digest"
+**	"cx" the context
+**	"digest" where the 16 bytes of digest data are stored
+**	"digestLen" where the digest length (20) is stored (optional)
+**	"maxDigestLen" the maximum amount of data that can ever be
+**	   stored in "digest"
+*/
+extern void SHA1_EndRaw(SHA1Context *cx, unsigned char *digest,
+			unsigned int *digestLen, unsigned int maxDigestLen);
+
+/*
 ** trace the intermediate state info of the SHA1 hash.
 */
 extern void SHA1_TraceState(SHA1Context *cx);
 
 /*
  * Return the the size of a buffer needed to flatten the SHA-1 Context into
  *    "cx" the context
  *  returns size;
@@ -1063,16 +1087,18 @@ extern void SHA1_Clone(SHA1Context *dest
 
 extern SHA224Context *SHA224_NewContext(void);
 extern void SHA224_DestroyContext(SHA224Context *cx, PRBool freeit);
 extern void SHA224_Begin(SHA224Context *cx);
 extern void SHA224_Update(SHA224Context *cx, const unsigned char *input,
 			unsigned int inputLen);
 extern void SHA224_End(SHA224Context *cx, unsigned char *digest,
 		     unsigned int *digestLen, unsigned int maxDigestLen);
+extern void SHA224_EndRaw(SHA224Context *cx, unsigned char *digest,
+			  unsigned int *digestLen, unsigned int maxDigestLen);
 extern SECStatus SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
 			      uint32 src_length);
 extern SECStatus SHA224_Hash(unsigned char *dest, const char *src);
 extern void SHA224_TraceState(SHA224Context *cx);
 extern unsigned int SHA224_FlattenSize(SHA224Context *cx);
 extern SECStatus SHA224_Flatten(SHA224Context *cx,unsigned char *space);
 extern SHA224Context * SHA224_Resurrect(unsigned char *space, void *arg);
 extern void SHA224_Clone(SHA224Context *dest, SHA224Context *src);
@@ -1081,32 +1107,36 @@ extern void SHA224_Clone(SHA224Context *
 
 extern SHA256Context *SHA256_NewContext(void);
 extern void SHA256_DestroyContext(SHA256Context *cx, PRBool freeit);
 extern void SHA256_Begin(SHA256Context *cx);
 extern void SHA256_Update(SHA256Context *cx, const unsigned char *input,
 			unsigned int inputLen);
 extern void SHA256_End(SHA256Context *cx, unsigned char *digest,
 		     unsigned int *digestLen, unsigned int maxDigestLen);
+extern void SHA256_EndRaw(SHA256Context *cx, unsigned char *digest,
+			  unsigned int *digestLen, unsigned int maxDigestLen);
 extern SECStatus SHA256_HashBuf(unsigned char *dest, const unsigned char *src,
 			      uint32 src_length);
 extern SECStatus SHA256_Hash(unsigned char *dest, const char *src);
 extern void SHA256_TraceState(SHA256Context *cx);
 extern unsigned int SHA256_FlattenSize(SHA256Context *cx);
 extern SECStatus SHA256_Flatten(SHA256Context *cx,unsigned char *space);
 extern SHA256Context * SHA256_Resurrect(unsigned char *space, void *arg);
 extern void SHA256_Clone(SHA256Context *dest, SHA256Context *src);
 
 /******************************************/
 
 extern SHA512Context *SHA512_NewContext(void);
 extern void SHA512_DestroyContext(SHA512Context *cx, PRBool freeit);
 extern void SHA512_Begin(SHA512Context *cx);
 extern void SHA512_Update(SHA512Context *cx, const unsigned char *input,
 			unsigned int inputLen);
+extern void SHA512_EndRaw(SHA512Context *cx, unsigned char *digest,
+			  unsigned int *digestLen, unsigned int maxDigestLen);
 extern void SHA512_End(SHA512Context *cx, unsigned char *digest,
 		     unsigned int *digestLen, unsigned int maxDigestLen);
 extern SECStatus SHA512_HashBuf(unsigned char *dest, const unsigned char *src,
 			      uint32 src_length);
 extern SECStatus SHA512_Hash(unsigned char *dest, const char *src);
 extern void SHA512_TraceState(SHA512Context *cx);
 extern unsigned int SHA512_FlattenSize(SHA512Context *cx);
 extern SECStatus SHA512_Flatten(SHA512Context *cx,unsigned char *space);
@@ -1117,16 +1147,18 @@ extern void SHA512_Clone(SHA512Context *
 
 extern SHA384Context *SHA384_NewContext(void);
 extern void SHA384_DestroyContext(SHA384Context *cx, PRBool freeit);
 extern void SHA384_Begin(SHA384Context *cx);
 extern void SHA384_Update(SHA384Context *cx, const unsigned char *input,
 			unsigned int inputLen);
 extern void SHA384_End(SHA384Context *cx, unsigned char *digest,
 		     unsigned int *digestLen, unsigned int maxDigestLen);
+extern void SHA384_EndRaw(SHA384Context *cx, unsigned char *digest,
+			  unsigned int *digestLen, unsigned int maxDigestLen);
 extern SECStatus SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
 			      uint32 src_length);
 extern SECStatus SHA384_Hash(unsigned char *dest, const char *src);
 extern void SHA384_TraceState(SHA384Context *cx);
 extern unsigned int SHA384_FlattenSize(SHA384Context *cx);
 extern SECStatus SHA384_Flatten(SHA384Context *cx,unsigned char *space);
 extern SHA384Context * SHA384_Resurrect(unsigned char *space, void *arg);
 extern void SHA384_Clone(SHA384Context *dest, SHA384Context *src);
--- a/security/nss/lib/freebl/ecl/ecp_aff.c
+++ b/security/nss/lib/freebl/ecl/ecp_aff.c
@@ -280,21 +280,20 @@ ec_GFp_validate_point(const mp_int *px, 
 		group->meth->field_enc(px, &pxt, group->meth);
 		group->meth->field_enc(py, &pyt, group->meth);
 	} else {
 		mp_copy(px, &pxt);
 		mp_copy(py, &pyt);
 	}
 	/* left-hand side: y^2  */
 	MP_CHECKOK( group->meth->field_sqr(&pyt, &accl, group->meth) );
-	/* right-hand side: x^3 + a*x + b */
+	/* right-hand side: x^3 + a*x + b = (x^2 + a)*x + b by Horner's rule */
 	MP_CHECKOK( group->meth->field_sqr(&pxt, &tmp, group->meth) );
-	MP_CHECKOK( group->meth->field_mul(&pxt, &tmp, &accr, group->meth) );
-	MP_CHECKOK( group->meth->field_mul(&group->curvea, &pxt, &tmp, group->meth) );
-	MP_CHECKOK( group->meth->field_add(&tmp, &accr, &accr, group->meth) );
+	MP_CHECKOK( group->meth->field_add(&tmp, &group->curvea, &tmp, group->meth) );
+	MP_CHECKOK( group->meth->field_mul(&tmp, &pxt, &accr, group->meth) );
 	MP_CHECKOK( group->meth->field_add(&accr, &group->curveb, &accr, group->meth) );
 	/* check LHS - RHS == 0 */
 	MP_CHECKOK( group->meth->field_sub(&accl, &accr, &accr, group->meth) );
 	if (mp_cmp_z(&accr) != 0) {
 		res = MP_NO;
 		goto CLEANUP;
 	}
     /* 4: Verify that the order of the curve times the publicValue
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/hmacct.c
@@ -0,0 +1,336 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifdef FREEBL_NO_DEPEND
+#include "stubs.h"
+#endif
+
+#include "secport.h"
+#include "hasht.h"
+#include "blapit.h"
+#include "hmacct.h"
+#include "secerr.h"
+
+/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length
+ * field. (SHA-384/512 have 128-bit length.) */
+#define MAX_HASH_BIT_COUNT_BYTES 16
+
+/* Some utility functions are needed:
+ *
+ * These macros return the given value with the MSB copied to all the other
+ * bits. They use the fact that an arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to replace
+ * them with something else on odd CPUs.
+ *
+ * Note: the argument to these macros must be an unsigned int.
+ * */
+#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned int)( (int)(x) >> (sizeof(int)*8-1) ) )
+#define DUPLICATE_MSB_TO_ALL_8(x) ( (unsigned char)(DUPLICATE_MSB_TO_ALL(x)) )
+
+/* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b <
+ * MAX_UINT/2. */
+static unsigned char
+constantTimeGE(unsigned int a, unsigned int b)
+{
+    a -= b;
+    return DUPLICATE_MSB_TO_ALL(~a);
+}
+
+/* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
+static unsigned char
+constantTimeEQ8(unsigned char a, unsigned char b)
+{
+    unsigned int c = a ^ b;
+    c--;
+    return DUPLICATE_MSB_TO_ALL_8(c);
+}
+
+/* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|,
+ * where |dataLen| includes both the authenticated bytes and the MAC tag from
+ * the sender. |dataLen| must be >= the length of the MAC tag.
+ *
+ * |dataTotalLen| is >= |dataLen| and also accounts for any padding bytes
+ * that may follow the sender's MAC. (Only a single block of padding may
+ * follow in SSLv3, or up to 255 bytes in TLS.)
+ *
+ * Since the results of decryption are secret information (otherwise a
+ * padding-oracle is created), this function is constant-time with respect to
+ * |dataLen|.
+ *
+ * |header| contains either the 13-byte TLS header (containing the sequence
+ * number, record type etc), or it contains the SSLv3 header with the SSLv3
+ * padding bytes etc. */
+static SECStatus
+MAC(unsigned char *mdOut,
+    unsigned int *mdOutLen,
+    unsigned int mdOutMax,
+    const SECHashObject *hashObj,
+    const unsigned char *macSecret,
+    unsigned int macSecretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *data,
+    unsigned int dataLen,
+    unsigned int dataTotalLen,
+    unsigned char isSSLv3)
+{
+    void *mdState = hashObj->create();
+    const unsigned int mdSize = hashObj->length;
+    const unsigned int mdBlockSize = hashObj->blocklength;
+    /* mdLengthSize is the number of bytes in the length field that terminates
+     * the hash.
+     *
+     * This assumes that hash functions with a 64 byte block size use a 64-bit
+     * length, and otherwise they use a 128-bit length. This is true of {MD5,
+     * SHA*} (which are all of the hash functions specified for use with TLS
+     * today). */
+    const unsigned int mdLengthSize = mdBlockSize == 64 ? 8 : 16;
+
+    const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40;
+
+    /* varianceBlocks is the number of blocks of the hash that we have to
+     * calculate in constant time because they could be altered by the
+     * padding value.
+     *
+     * In SSLv3, the padding must be minimal so the end of the plaintext
+     * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that
+     * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash
+     * termination (0x80 + 64-bit length) don't fit in the final block, we
+     * say that the final two blocks can vary based on the padding.
+     *
+     * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not
+     * required to be minimal. Therefore we say that the final six blocks
+     * can vary based on the padding.
+     *
+     * Later in the function, if the message is short and there obviously
+     * cannot be this many blocks then varianceBlocks can be reduced. */
+    unsigned int varianceBlocks = isSSLv3 ? 2 : 6;
+    /* From now on we're dealing with the MAC, which conceptually has 13
+     * bytes of `header' before the start of the data (TLS) or 71/75 bytes
+     * (SSLv3) */
+    const unsigned int len = dataTotalLen + headerLen;
+    /* maxMACBytes contains the maximum bytes of bytes in the MAC, including
+     * |header|, assuming that there's no padding. */
+    const unsigned int maxMACBytes = len - mdSize - 1;
+    /* numBlocks is the maximum number of hash blocks. */
+    const unsigned int numBlocks =
+	(maxMACBytes + 1 + mdLengthSize + mdBlockSize - 1) / mdBlockSize;
+    /* macEndOffset is the index just past the end of the data to be
+     * MACed. */
+    const unsigned int macEndOffset = dataLen + headerLen - mdSize;
+    /* c is the index of the 0x80 byte in the final hash block that
+     * contains application data. */
+    const unsigned int c = macEndOffset % mdBlockSize;
+    /* indexA is the hash block number that contains the 0x80 terminating
+     * value. */
+    const unsigned int indexA = macEndOffset / mdBlockSize;
+    /* indexB is the hash block number that contains the 64-bit hash
+     * length, in bits. */
+    const unsigned int indexB = (macEndOffset + mdLengthSize) / mdBlockSize;
+    /* bits is the hash-length in bits. It includes the additional hash
+     * block for the masked HMAC key, or whole of |header| in the case of
+     * SSLv3. */
+    unsigned int bits;
+    /* In order to calculate the MAC in constant time we have to handle
+     * the final blocks specially because the padding value could cause the
+     * end to appear somewhere in the final |varianceBlocks| blocks and we
+     * can't leak where. However, |numStartingBlocks| worth of data can
+     * be hashed right away because no padding value can affect whether
+     * they are plaintext. */
+    unsigned int numStartingBlocks = 0;
+    /* k is the starting byte offset into the conceptual header||data where
+     * we start processing. */
+    unsigned int k = 0;
+    unsigned char lengthBytes[MAX_HASH_BIT_COUNT_BYTES];
+    /* hmacPad is the masked HMAC key. */
+    unsigned char hmacPad[HASH_BLOCK_LENGTH_MAX];
+    unsigned char firstBlock[HASH_BLOCK_LENGTH_MAX];
+    unsigned char macOut[HASH_LENGTH_MAX];
+    unsigned i, j;
+
+    /* For SSLv3, if we're going to have any starting blocks then we need
+     * at least two because the header is larger than a single block. */
+    if (numBlocks > varianceBlocks + (isSSLv3 ? 1 : 0)) {
+	numStartingBlocks = numBlocks - varianceBlocks;
+	k = mdBlockSize*numStartingBlocks;
+    }
+
+    bits = 8*macEndOffset;
+    hashObj->begin(mdState);
+    if (!isSSLv3) {
+	/* Compute the initial HMAC block. For SSLv3, the padding and
+	 * secret bytes are included in |header| because they take more
+	 * than a single block. */
+	bits += 8*mdBlockSize;
+	memset(hmacPad, 0, mdBlockSize);
+	PORT_Assert(macSecretLen <= sizeof(hmacPad));
+	memcpy(hmacPad, macSecret, macSecretLen);
+	for (i = 0; i < mdBlockSize; i++)
+	    hmacPad[i] ^= 0x36;
+	hashObj->update(mdState, hmacPad, mdBlockSize);
+    }
+
+    j = 0;
+    memset(lengthBytes, 0, sizeof(lengthBytes));
+    if (mdLengthSize == 16) {
+	j = 8;
+    }
+    if (hashObj->type == HASH_AlgMD5) {
+	/* MD5 appends a little-endian length. */
+	for (i = 0; i < 4; i++) {
+	    lengthBytes[i+j] = bits >> (8*i);
+	}
+    } else {
+	/* All other TLS hash functions use a big-endian length. */
+	for (i = 0; i < 4; i++) {
+	    lengthBytes[4+i+j] = bits >> (8*(3-i));
+	}
+    }
+
+    if (k > 0) {
+	if (isSSLv3) {
+	    /* The SSLv3 header is larger than a single block.
+	     * overhang is the number of bytes beyond a single
+	     * block that the header consumes: either 7 bytes
+	     * (SHA1) or 11 bytes (MD5). */
+	    const unsigned int overhang = headerLen-mdBlockSize;
+	    hashObj->update(mdState, header, mdBlockSize);
+	    memcpy(firstBlock, header + mdBlockSize, overhang);
+	    memcpy(firstBlock + overhang, data, mdBlockSize-overhang);
+	    hashObj->update(mdState, firstBlock, mdBlockSize);
+	    for (i = 1; i < k/mdBlockSize - 1; i++) {
+		hashObj->update(mdState, data + mdBlockSize*i - overhang,
+				mdBlockSize);
+	    }
+	} else {
+	    /* k is a multiple of mdBlockSize. */
+	    memcpy(firstBlock, header, 13);
+	    memcpy(firstBlock+13, data, mdBlockSize-13);
+	    hashObj->update(mdState, firstBlock, mdBlockSize);
+	    for (i = 1; i < k/mdBlockSize; i++) {
+		hashObj->update(mdState, data + mdBlockSize*i - 13,
+				mdBlockSize);
+	    }
+	}
+    }
+
+    memset(macOut, 0, sizeof(macOut));
+
+    /* We now process the final hash blocks. For each block, we construct
+     * it in constant time. If i == indexA then we'll include the 0x80
+     * bytes and zero pad etc. For each block we selectively copy it, in
+     * constant time, to |macOut|. */
+    for (i = numStartingBlocks; i <= numStartingBlocks+varianceBlocks; i++) {
+	unsigned char block[HASH_BLOCK_LENGTH_MAX];
+	unsigned char isBlockA = constantTimeEQ8(i, indexA);
+	unsigned char isBlockB = constantTimeEQ8(i, indexB);
+	for (j = 0; j < mdBlockSize; j++) {
+	    unsigned char isPastC = isBlockA & constantTimeGE(j, c);
+	    unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c+1);
+	    unsigned char b = 0;
+	    if (k < headerLen) {
+		b = header[k];
+	    } else if (k < dataTotalLen + headerLen) {
+		b = data[k-headerLen];
+	    }
+	    k++;
+
+	    /* If this is the block containing the end of the
+	     * application data, and we are at the offset for the
+	     * 0x80 value, then overwrite b with 0x80. */
+	    b = (b&~isPastC) | (0x80&isPastC);
+	    /* If this the the block containing the end of the
+	     * application data and we're past the 0x80 value then
+	     * just write zero. */
+	    b = b&~isPastCPlus1;
+	    /* If this is indexB (the final block), but not
+	     * indexA (the end of the data), then the 64-bit
+	     * length didn't fit into indexA and we're having to
+	     * add an extra block of zeros. */
+	    b &= ~isBlockB | isBlockA;
+
+	    /* The final bytes of one of the blocks contains the length. */
+	    if (j >= mdBlockSize - mdLengthSize) {
+		/* If this is indexB, write a length byte. */
+		b = (b&~isBlockB) |
+		    (isBlockB&lengthBytes[j-(mdBlockSize-mdLengthSize)]);
+	    }
+	    block[j] = b;
+	}
+
+	hashObj->update(mdState, block, mdBlockSize);
+	hashObj->end_raw(mdState, block, NULL, mdSize);
+	/* If this is indexB, copy the hash value to |macOut|. */
+	for (j = 0; j < mdSize; j++) {
+	    macOut[j] |= block[j]&isBlockB;
+	}
+    }
+
+    hashObj->begin(mdState);
+
+    if (isSSLv3) {
+	/* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */
+	for (i = 0; i < sslv3PadLen; i++)
+	    hmacPad[i] = 0x5c;
+
+	hashObj->update(mdState, macSecret, macSecretLen);
+	hashObj->update(mdState, hmacPad, sslv3PadLen);
+	hashObj->update(mdState, macOut, mdSize);
+    } else {
+	/* Complete the HMAC in the standard manner. */
+	for (i = 0; i < mdBlockSize; i++)
+	    hmacPad[i] ^= 0x6a;
+
+	hashObj->update(mdState, hmacPad, mdBlockSize);
+	hashObj->update(mdState, macOut, mdSize);
+    }
+
+    hashObj->end(mdState, mdOut, mdOutLen, mdOutMax);
+    hashObj->destroy(mdState, PR_TRUE);
+
+    return SECSuccess;
+}
+
+SECStatus
+HMAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen)
+{
+    if (hashObj->end_raw == NULL)
+	return SECFailure;
+    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
+	       header, headerLen, body, bodyLen, bodyTotalLen,
+	       0 /* not SSLv3 */);
+}
+
+SECStatus
+SSLv3_MAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen)
+{
+    if (hashObj->end_raw == NULL)
+	return SECFailure;
+    return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen,
+	       header, headerLen, body, bodyLen, bodyTotalLen,
+	       1 /* SSLv3 */);
+}
+
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/freebl/hmacct.h
@@ -0,0 +1,38 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef _ALGHMACCT_H_
+#define _ALGHMACCT_H_
+
+SEC_BEGIN_PROTOS
+
+extern SECStatus HMAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen);
+
+extern SECStatus SSLv3_MAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen);
+
+SEC_END_PROTOS
+
+#endif
--- a/security/nss/lib/freebl/ldvector.c
+++ b/security/nss/lib/freebl/ldvector.c
@@ -1,22 +1,23 @@
 /*
  * ldvector.c - platform dependent DSO containing freebl implementation.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: ldvector.c,v 1.32 2012/06/28 17:55:05 rrelyea%redhat.com Exp $ */
+/* $Id: ldvector.c,v 1.33 2013/02/05 18:10:42 wtc%google.com Exp $ */
 
 #ifdef FREEBL_NO_DEPEND
 extern int FREEBL_InitStubs(void);
 #endif
 
 #include "loader.h"
 #include "alghmac.h"
+#include "hmacct.h"
 
 
 static const struct FREEBLVectorStr vector = 
 {
 
     sizeof vector,
     FREEBL_VERSION,
 
@@ -253,19 +254,24 @@ static const struct FREEBLVectorStr vect
     SHA224_Flatten,
     SHA224_Resurrect,
     SHA224_Clone,
     BLAPI_SHVerifyFile,
 
     /* End of Version 3.013 */
 
     PQG_ParamGenV2,
-    PRNGTEST_RunHealthTests
+    PRNGTEST_RunHealthTests,
 
     /* End of Version 3.014 */
+
+    HMAC_ConstantTime,
+    SSLv3_MAC_ConstantTime
+
+    /* End of Version 3.015 */
 };
 
 const FREEBLVector * 
 FREEBL_GetVector(void)
 {
     extern const char __nss_freebl_rcsid[];
     extern const char __nss_freebl_sccsid[];
 
--- a/security/nss/lib/freebl/loader.c
+++ b/security/nss/lib/freebl/loader.c
@@ -1,15 +1,15 @@
 /*
  * loader.c - load platform dependent DSO containing freebl implementation.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: loader.c,v 1.58 2012/12/13 22:47:15 wtc%google.com Exp $ */
+/* $Id: loader.c,v 1.60 2013/02/06 22:20:22 wtc%google.com Exp $ */
 
 #include "loader.h"
 #include "prmem.h"
 #include "prerror.h"
 #include "prinit.h"
 #include "prenv.h"
 
 static const char* default_name =
@@ -1853,8 +1853,56 @@ PQG_ParamGenV2( unsigned int L, unsigned
 
 SECStatus
 PRNGTEST_RunHealthTests(void)
 {
   if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
       return SECFailure;
   return vector->p_PRNGTEST_RunHealthTests();
 }
+
+SECStatus
+SSLv3_MAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen)
+{
+  if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+      return SECFailure;
+  return (vector->p_SSLv3_MAC_ConstantTime)(
+      result, resultLen, maxResultLen,
+      hashObj,
+      secret, secretLen,
+      header, headerLen,
+      body, bodyLen, bodyTotalLen);
+}
+
+SECStatus
+HMAC_ConstantTime(
+    unsigned char *result,
+    unsigned int *resultLen,
+    unsigned int maxResultLen,
+    const SECHashObject *hashObj,
+    const unsigned char *secret,
+    unsigned int secretLen,
+    const unsigned char *header,
+    unsigned int headerLen,
+    const unsigned char *body,
+    unsigned int bodyLen,
+    unsigned int bodyTotalLen)
+{
+  if (!vector && PR_SUCCESS != freebl_RunLoaderOnce())
+      return SECFailure;
+  return (vector->p_HMAC_ConstantTime)(
+      result, resultLen, maxResultLen,
+      hashObj,
+      secret, secretLen,
+      header, headerLen,
+      body, bodyLen, bodyTotalLen);
+}
--- a/security/nss/lib/freebl/loader.h
+++ b/security/nss/lib/freebl/loader.h
@@ -1,22 +1,22 @@
 /*
  * loader.h - load platform dependent DSO containing freebl implementation.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: loader.h,v 1.38 2012/06/28 17:55:05 rrelyea%redhat.com Exp $ */
+/* $Id: loader.h,v 1.39 2013/02/05 18:10:42 wtc%google.com Exp $ */
 
 #ifndef _LOADER_H_
 #define _LOADER_H_ 1
 
 #include "blapi.h"
 
-#define FREEBL_VERSION 0x030E
+#define FREEBL_VERSION 0x030F
 
 struct FREEBLVectorStr {
 
   unsigned short length;  /* of this struct in bytes */
   unsigned short version; /* of this struct. */
 
   RSAPrivateKey * (* p_RSA_NewKey)(int         keySizeInBits,
 				 SECItem *   publicExponent);
@@ -564,17 +564,45 @@ struct FREEBLVectorStr {
   /* Version 3.013 came to here */
 
  SECStatus (* p_PQG_ParamGenV2)( unsigned int L, unsigned int N,
                                 unsigned int seedBytes, 
                                 PQGParams **pParams, PQGVerify **pVfy); 
  SECStatus (*p_PRNGTEST_RunHealthTests)(void);
 
   /* Version 3.014 came to here */
-};
+
+ SECStatus (* p_HMAC_ConstantTime)(
+     unsigned char *result,
+     unsigned int *resultLen,
+     unsigned int maxResultLen,
+     const SECHashObject *hashObj,
+     const unsigned char *secret,
+     unsigned int secretLen,
+     const unsigned char *header,
+     unsigned int headerLen,
+     const unsigned char *body,
+     unsigned int bodyLen,
+     unsigned int bodyTotalLen);
+
+ SECStatus (* p_SSLv3_MAC_ConstantTime)(
+     unsigned char *result,
+     unsigned int *resultLen,
+     unsigned int maxResultLen,
+     const SECHashObject *hashObj,
+     const unsigned char *secret,
+     unsigned int secretLen,
+     const unsigned char *header,
+     unsigned int headerLen,
+     const unsigned char *body,
+     unsigned int bodyLen,
+     unsigned int bodyTotalLen);
+
+  /* Version 3.015 came to here */
+ };
 
 typedef struct FREEBLVectorStr FREEBLVector;
 
 SEC_BEGIN_PROTOS
 
 typedef const FREEBLVector * FREEBLGetVectorFn(void);
 
 extern FREEBLGetVectorFn FREEBL_GetVector;
--- a/security/nss/lib/freebl/manifest.mn
+++ b/security/nss/lib/freebl/manifest.mn
@@ -51,16 +51,17 @@ EXPORTS = \
 	shsign.h \
 	ecl-exp.h \
 	$(LOWHASH_EXPORTS) \
 	$(NULL)
 
 PRIVATE_EXPORTS = \
 	alghmac.h \
 	blapi.h \
+	hmacct.h \
 	secmpi.h \
 	secrng.h \
 	ec.h \
 	ecl.h \
 	ecl-curve.h \
 	$(NULL)
 
 MPI_HDRS = mpi-config.h mpi.h mpi-priv.h mplogic.h mpprime.h logtab.h mp_gf2m.h
@@ -97,16 +98,17 @@ CSRCS = \
 	arcfour.c \
 	arcfive.c \
 	desblapi.c \
 	des.c \
 	drbg.c \
 	cts.c \
 	ctr.c \
 	gcm.c \
+	hmacct.c \
 	rijndael.c \
 	aeskeywrap.c \
 	camellia.c \
 	dh.c \
 	ec.c \
 	pqg.c \
 	dsa.c \
 	rsa.c \
--- a/security/nss/lib/freebl/md5.c
+++ b/security/nss/lib/freebl/md5.c
@@ -518,26 +518,53 @@ MD5_End(MD5Context *cx, unsigned char *d
 
 	/* Final call to compress. */
 #ifndef IS_LITTLE_ENDIAN
 	md5_prep_state_le(cx);
 #endif
 	md5_compress(cx, cx->u.w);
 
 	/* Copy the resulting values out of the chain variables into return buf. */
-	*digestLen = MD5_HASH_LEN;
+	if (digestLen)
+		*digestLen = MD5_HASH_LEN;
 #ifndef IS_LITTLE_ENDIAN
 	cx->cv[0] = lendian(cx->cv[0]);
 	cx->cv[1] = lendian(cx->cv[1]);
 	cx->cv[2] = lendian(cx->cv[2]);
 	cx->cv[3] = lendian(cx->cv[3]);
 #endif
 	memcpy(digest, cx->cv, MD5_HASH_LEN);
 }
 
+void
+MD5_EndRaw(MD5Context *cx, unsigned char *digest,
+           unsigned int *digestLen, unsigned int maxDigestLen)
+{
+#ifndef IS_LITTLE_ENDIAN
+	PRUint32 tmp;
+#endif
+	PRUint32 cv[4];
+
+	if (maxDigestLen < MD5_HASH_LEN) {
+		PORT_SetError(SEC_ERROR_INVALID_ARGS);
+		return;
+	}
+
+	memcpy(cv, cx->cv, sizeof(cv));
+#ifndef IS_LITTLE_ENDIAN
+	cv[0] = lendian(cv[0]);
+	cv[1] = lendian(cv[1]);
+	cv[2] = lendian(cv[2]);
+	cv[3] = lendian(cv[3]);
+#endif
+	memcpy(digest, cv, MD5_HASH_LEN);
+	if (digestLen)
+		*digestLen = MD5_HASH_LEN;
+}
+
 unsigned int 
 MD5_FlattenSize(MD5Context *cx)
 {
 	return sizeof(*cx);
 }
 
 SECStatus 
 MD5_Flatten(MD5Context *cx, unsigned char *space)
--- a/security/nss/lib/freebl/rawhash.c
+++ b/security/nss/lib/freebl/rawhash.c
@@ -53,91 +53,105 @@ const SECHashObject SECRawHashObjects[] 
     (void * (*)(void)) null_hash_new_context,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) null_hash_destroy_context,
     (void (*)(void *)) null_hash_begin,
     (void (*)(void *, const unsigned char *, unsigned int)) null_hash_update,
     (void (*)(void *, unsigned char *, unsigned int *,
 	      unsigned int)) null_hash_end,
     0,
-    HASH_AlgNULL
+    HASH_AlgNULL,
+    (void (*)(void *, unsigned char *, unsigned int *,
+	      unsigned int)) null_hash_end
   },
   { MD2_LENGTH,
     (void * (*)(void)) MD2_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) MD2_DestroyContext,
     (void (*)(void *)) MD2_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) MD2_Update,
     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD2_End,
     MD2_BLOCK_LENGTH,
-    HASH_AlgMD2
+    HASH_AlgMD2,
+    NULL /* end_raw */
   },
   { MD5_LENGTH,
     (void * (*)(void)) MD5_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) MD5_DestroyContext,
     (void (*)(void *)) MD5_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) MD5_Update,
     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_End,
     MD5_BLOCK_LENGTH,
-    HASH_AlgMD5
+    HASH_AlgMD5,
+    (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) MD5_EndRaw
   },
   { SHA1_LENGTH,
     (void * (*)(void)) SHA1_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) SHA1_DestroyContext,
     (void (*)(void *)) SHA1_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) SHA1_Update,
     (void (*)(void *, unsigned char *, unsigned int *, unsigned int)) SHA1_End,
     SHA1_BLOCK_LENGTH,
-    HASH_AlgSHA1
+    HASH_AlgSHA1,
+    (void (*)(void *, unsigned char *, unsigned int *, unsigned int))
+	SHA1_EndRaw
   },
   { SHA256_LENGTH,
     (void * (*)(void)) SHA256_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) SHA256_DestroyContext,
     (void (*)(void *)) SHA256_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) SHA256_Update,
     (void (*)(void *, unsigned char *, unsigned int *,
 	      unsigned int)) SHA256_End,
     SHA256_BLOCK_LENGTH,
-    HASH_AlgSHA256
+    HASH_AlgSHA256,
+    (void (*)(void *, unsigned char *, unsigned int *,
+	      unsigned int)) SHA256_EndRaw
   },
   { SHA384_LENGTH,
     (void * (*)(void)) SHA384_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) SHA384_DestroyContext,
     (void (*)(void *)) SHA384_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) SHA384_Update,
     (void (*)(void *, unsigned char *, unsigned int *,
 	      unsigned int)) SHA384_End,
     SHA384_BLOCK_LENGTH,
-    HASH_AlgSHA384
+    HASH_AlgSHA384,
+    (void (*)(void *, unsigned char *, unsigned int *,
+	      unsigned int)) SHA384_EndRaw
   },
   { SHA512_LENGTH,
     (void * (*)(void)) SHA512_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) SHA512_DestroyContext,
     (void (*)(void *)) SHA512_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) SHA512_Update,
     (void (*)(void *, unsigned char *, unsigned int *,
 	      unsigned int)) SHA512_End,
     SHA512_BLOCK_LENGTH,
-    HASH_AlgSHA512
+    HASH_AlgSHA512,
+    (void (*)(void *, unsigned char *, unsigned int *,
+	      unsigned int)) SHA512_EndRaw
   },
   { SHA224_LENGTH,
     (void * (*)(void)) SHA224_NewContext,
     (void * (*)(void *)) null_hash_clone_context,
     (void (*)(void *, PRBool)) SHA224_DestroyContext,
     (void (*)(void *)) SHA224_Begin,
     (void (*)(void *, const unsigned char *, unsigned int)) SHA224_Update,
     (void (*)(void *, unsigned char *, unsigned int *,
 	      unsigned int)) SHA224_End,
     SHA224_BLOCK_LENGTH,
-    HASH_AlgSHA224
+    HASH_AlgSHA224,
+    (void (*)(void *, unsigned char *, unsigned int *,
+	      unsigned int)) SHA224_EndRaw
   },
 };
 
 const SECHashObject *
 HASH_GetRawHashObject(HASH_HashType hashType)
 {
     if (hashType < HASH_AlgNULL || hashType >= HASH_AlgTOTAL) {
 	PORT_SetError(SEC_ERROR_INVALID_ARGS);
--- a/security/nss/lib/freebl/sha512.c
+++ b/security/nss/lib/freebl/sha512.c
@@ -1,15 +1,15 @@
 /*
  * sha512.c - implementation of SHA224, SHA256, SHA384 and SHA512
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: sha512.c,v 1.21 2012/07/27 20:00:39 wtc%google.com Exp $ */
+/* $Id: sha512.c,v 1.23 2013/02/06 00:41:13 wtc%google.com Exp $ */
 
 #ifdef FREEBL_NO_DEPEND
 #include "stubs.h"
 #endif
 
 #include "prcpucfg.h"
 #if defined(NSS_X86) || defined(SHA_NO_LONG_LONG)
 #define NOUNROLL512 1
@@ -457,16 +457,45 @@ SHA256_End(SHA256Context *ctx, unsigned 
     BYTESWAP4(H[7]);
 #endif
     padLen = PR_MIN(SHA256_LENGTH, maxDigestLen);
     memcpy(digest, H, padLen);
     if (digestLen)
 	*digestLen = padLen;
 }
 
+void
+SHA256_EndRaw(SHA256Context *ctx, unsigned char *digest,
+	      unsigned int *digestLen, unsigned int maxDigestLen)
+{
+    PRUint32 h[8];
+    unsigned int len;
+#ifdef SWAP4MASK
+    PRUint32 t1;
+#endif
+
+    memcpy(h, ctx->h, sizeof(h));
+
+#if defined(IS_LITTLE_ENDIAN)
+    BYTESWAP4(h[0]);
+    BYTESWAP4(h[1]);
+    BYTESWAP4(h[2]);
+    BYTESWAP4(h[3]);
+    BYTESWAP4(h[4]);
+    BYTESWAP4(h[5]);
+    BYTESWAP4(h[6]);
+    BYTESWAP4(h[7]);
+#endif
+
+    len = PR_MIN(SHA256_LENGTH, maxDigestLen);
+    memcpy(digest, h, len);
+    if (digestLen)
+	*digestLen = len;
+}
+
 SECStatus 
 SHA256_HashBuf(unsigned char *dest, const unsigned char *src, 
                uint32 src_length)
 {
     SHA256Context ctx;
     unsigned int outLen;
 
     SHA256_Begin(&ctx);
@@ -551,16 +580,24 @@ SHA224_Update(SHA224Context *ctx, const 
 void
 SHA224_End(SHA256Context *ctx, unsigned char *digest,
            unsigned int *digestLen, unsigned int maxDigestLen)
 {
     unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
     SHA256_End(ctx, digest, digestLen, maxLen);
 }
 
+void
+SHA224_EndRaw(SHA256Context *ctx, unsigned char *digest,
+	      unsigned int *digestLen, unsigned int maxDigestLen)
+{
+    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA224_LENGTH);
+    SHA256_EndRaw(ctx, digest, digestLen, maxLen);
+}
+
 SECStatus 
 SHA224_HashBuf(unsigned char *dest, const unsigned char *src,
                uint32 src_length)
 {
     SHA256Context ctx;
     unsigned int outLen;
 
     SHA224_Begin(&ctx);
@@ -1223,16 +1260,46 @@ SHA512_End(SHA512Context *ctx, unsigned 
     BYTESWAP8(H[7]);
 #endif
     padLen = PR_MIN(SHA512_LENGTH, maxDigestLen);
     memcpy(digest, H, padLen);
     if (digestLen)
 	*digestLen = padLen;
 }
 
+void
+SHA512_EndRaw(SHA512Context *ctx, unsigned char *digest,
+              unsigned int *digestLen, unsigned int maxDigestLen)
+{
+#if defined(HAVE_LONG_LONG)
+    PRUint64 t1;
+#else
+    PRUint32 t1;
+#endif
+    PRUint64 h[8];
+    unsigned int len;
+
+    memcpy(h, ctx->h, sizeof(h));
+
+#if defined(IS_LITTLE_ENDIAN)
+    BYTESWAP8(h[0]);
+    BYTESWAP8(h[1]);
+    BYTESWAP8(h[2]);
+    BYTESWAP8(h[3]);
+    BYTESWAP8(h[4]);
+    BYTESWAP8(h[5]);
+    BYTESWAP8(h[6]);
+    BYTESWAP8(h[7]);
+#endif
+    len = PR_MIN(SHA512_LENGTH, maxDigestLen);
+    memcpy(digest, h, len);
+    if (digestLen)
+	*digestLen = len;
+}
+
 SECStatus 
 SHA512_HashBuf(unsigned char *dest, const unsigned char *src, 
                uint32 src_length)
 {
     SHA512Context ctx;
     unsigned int outLen;
 
     SHA512_Begin(&ctx);
@@ -1331,16 +1398,24 @@ SHA384_Update(SHA384Context *ctx, const 
 void 
 SHA384_End(SHA384Context *ctx, unsigned char *digest,
 		 unsigned int *digestLen, unsigned int maxDigestLen)
 {
     unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
     SHA512_End(ctx, digest, digestLen, maxLen);
 }
 
+void
+SHA384_EndRaw(SHA384Context *ctx, unsigned char *digest,
+	      unsigned int *digestLen, unsigned int maxDigestLen)
+{
+    unsigned int maxLen = SHA_MIN(maxDigestLen, SHA384_LENGTH);
+    SHA512_EndRaw(ctx, digest, digestLen, maxLen);
+}
+
 SECStatus 
 SHA384_HashBuf(unsigned char *dest, const unsigned char *src,
 			  uint32 src_length)
 {
     SHA512Context ctx;
     unsigned int outLen;
 
     SHA384_Begin(&ctx);
--- a/security/nss/lib/freebl/sha_fast.c
+++ b/security/nss/lib/freebl/sha_fast.c
@@ -143,16 +143,17 @@ SHA1_Update(SHA1Context *ctx, const unsi
  *  SHA: Generate hash value from context
  */
 void 
 SHA1_End(SHA1Context *ctx, unsigned char *hashout,
          unsigned int *pDigestLen, unsigned int maxDigestLen)
 {
   register PRUint64 size;
   register PRUint32 lenB;
+  PRUint32 tmpbuf[5];
 
   static const unsigned char bulk_pad[64] = { 0x80,0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
           0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0  };
 #define tmp lenB
 
   PORT_Assert (maxDigestLen >= SHA1_LENGTH);
 
@@ -169,22 +170,38 @@ SHA1_End(SHA1Context *ctx, unsigned char
   ctx->W[14] = SHA_HTONL((PRUint32)(size >> 32));
   ctx->W[15] = SHA_HTONL((PRUint32)size);
   shaCompress(&ctx->H[H2X], ctx->W);
 
   /*
    *  Output hash
    */
   SHA_STORE_RESULT;
-  *pDigestLen = SHA1_LENGTH;
+  if (pDigestLen) {
+    *pDigestLen = SHA1_LENGTH;
+  }
+#undef tmp
+}
 
+void
+SHA1_EndRaw(SHA1Context *ctx, unsigned char *hashout,
+            unsigned int *pDigestLen, unsigned int maxDigestLen)
+{
+#if defined(SHA_NEED_TMP_VARIABLE)
+  register PRUint32 tmp;
+#endif
+  PRUint32 tmpbuf[5];
+  PORT_Assert (maxDigestLen >= SHA1_LENGTH);
+
+  SHA_STORE_RESULT;
+  if (pDigestLen)
+    *pDigestLen = SHA1_LENGTH;
 }
 
 #undef B
-#undef tmp
 /*
  *  SHA: Compression function, unrolled.
  *
  * Some operations in shaCompress are done as 5 groups of 16 operations.
  * Others are done as 4 groups of 20 operations.
  * The code below shows that structure.
  *
  * The functions that compute the new values of the 5 state variables
--- a/security/nss/lib/freebl/sha_fast.h
+++ b/security/nss/lib/freebl/sha_fast.h
@@ -142,22 +142,22 @@ static __inline__ PRUint32 swap4b(PRUint
 #define SHA_STORE_RESULT \
   if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
     SHA_STORE(0); \
     SHA_STORE(1); \
     SHA_STORE(2); \
     SHA_STORE(3); \
     SHA_STORE(4); \
   } else { \
-    ctx->u.w[0] = SHA_HTONL(ctx->H[0]); \
-    ctx->u.w[1] = SHA_HTONL(ctx->H[1]); \
-    ctx->u.w[2] = SHA_HTONL(ctx->H[2]); \
-    ctx->u.w[3] = SHA_HTONL(ctx->H[3]); \
-    ctx->u.w[4] = SHA_HTONL(ctx->H[4]); \
-    memcpy(hashout, ctx->u.w, SHA1_LENGTH); \
+    tmpbuf[0] = SHA_HTONL(ctx->H[0]); \
+    tmpbuf[1] = SHA_HTONL(ctx->H[1]); \
+    tmpbuf[2] = SHA_HTONL(ctx->H[2]); \
+    tmpbuf[3] = SHA_HTONL(ctx->H[3]); \
+    tmpbuf[4] = SHA_HTONL(ctx->H[4]); \
+    memcpy(hashout, tmpbuf, SHA1_LENGTH); \
   }
 
 #else
 #define SHA_STORE_RESULT \
   if (!((ptrdiff_t)hashout % sizeof(PRUint32))) { \
     SHA_STORE(0); \
     SHA_STORE(1); \
     SHA_STORE(2); \
--- a/security/nss/lib/nss/nss.def
+++ b/security/nss/lib/nss/nss.def
@@ -1016,8 +1016,14 @@ PK11_PQG_ParamGenV2;
 CERT_CreateEncodedOCSPErrorResponse;
 CERT_CreateEncodedOCSPSuccessResponse;
 CERT_CreateOCSPSingleResponseGood;
 CERT_CreateOCSPSingleResponseUnknown;
 CERT_CreateOCSPSingleResponseRevoked;
 ;+    local:
 ;+       *;
 ;+};
+;+NSS_3.14.3 { 	# NSS 3.14.3 release
+;+    global:
+PK11_SignWithSymKey;
+;+    local:
+;+       *;
+;+};
--- a/security/nss/lib/nss/nss.h
+++ b/security/nss/lib/nss/nss.h
@@ -1,15 +1,15 @@
 /*
  * NSS utility functions
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: nss.h,v 1.102 2013/01/31 22:47:08 kaie%kuix.de Exp $ */
+/* $Id: nss.h,v 1.103 2013/01/31 22:59:44 kaie%kuix.de Exp $ */
 
 #ifndef __nss_h_
 #define __nss_h_
 
 /* The private macro _NSS_ECC_STRING is for NSS internal use only. */
 #ifdef NSS_ENABLE_ECC
 #ifdef NSS_ECC_MORE_THAN_SUITE_B
 #define _NSS_ECC_STRING " Extended ECC"
@@ -29,22 +29,22 @@
 
 /*
  * NSS's major version, minor version, patch level, build number, and whether
  * this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define NSS_VERSION  "3.14.2.0" _NSS_ECC_STRING _NSS_CUSTOMIZED
+#define NSS_VERSION  "3.14.3.0" _NSS_ECC_STRING _NSS_CUSTOMIZED " Beta"
 #define NSS_VMAJOR   3
 #define NSS_VMINOR   14
-#define NSS_VPATCH   2
+#define NSS_VPATCH   3
 #define NSS_VBUILD   0
-#define NSS_BETA     PR_FALSE
+#define NSS_BETA     PR_TRUE
 
 #ifndef RC_INVOKED
 
 #include "seccomon.h"
 
 typedef struct NSSInitParametersStr NSSInitParameters;
 
 /*
--- a/security/nss/lib/pk11wrap/pk11obj.c
+++ b/security/nss/lib/pk11wrap/pk11obj.c
@@ -773,16 +773,61 @@ PK11_Sign(SECKEYPrivateKey *key, SECItem
     if (crv != CKR_OK) {
 	PORT_SetError( PK11_MapError(crv) );
 	return SECFailure;
     }
     return SECSuccess;
 }
 
 /*
+ * sign data with a MAC key.
+ */
+SECStatus
+PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
+		    SECItem *param, SECItem *sig, const SECItem *data)
+{
+    PK11SlotInfo *slot = symKey->slot;
+    CK_MECHANISM mech = {0, NULL, 0 };
+    PRBool owner = PR_TRUE;
+    CK_SESSION_HANDLE session;
+    PRBool haslock = PR_FALSE;
+    CK_ULONG len;
+    CK_RV crv;
+
+    mech.mechanism = mechanism;
+    if (param) {
+	mech.pParameter = param->data;
+	mech.ulParameterLen = param->len;
+    }
+
+    session = pk11_GetNewSession(slot,&owner);
+    haslock = (!owner || !(slot->isThreadSafe));
+    if (haslock) PK11_EnterSlotMonitor(slot);
+    crv = PK11_GETTAB(slot)->C_SignInit(session,&mech,symKey->objectID);
+    if (crv != CKR_OK) {
+	if (haslock) PK11_ExitSlotMonitor(slot);
+	pk11_CloseSession(slot,session,owner);
+	PORT_SetError( PK11_MapError(crv) );
+	return SECFailure;
+    }
+
+    len = sig->len;
+    crv = PK11_GETTAB(slot)->C_Sign(session,data->data,
+					data->len, sig->data, &len);
+    if (haslock) PK11_ExitSlotMonitor(slot);
+    pk11_CloseSession(slot,session,owner);
+    sig->len = len;
+    if (crv != CKR_OK) {
+	PORT_SetError( PK11_MapError(crv) );
+	return SECFailure;
+    }
+    return SECSuccess;
+}
+
+/*
  * Now SSL 2.0 uses raw RSA stuff. These next to functions *must* use
  * RSA keys, or they'll fail. We do the checks up front. If anyone comes
  * up with a meaning for rawdecrypt for any other public key operation,
  * then we need to move this check into some of PK11_PubDecrypt callers,
  * (namely SSL 2.0).
  */
 static SECStatus
 pk11_PrivDecryptRaw(SECKEYPrivateKey *key, unsigned char *data, 
--- a/security/nss/lib/pk11wrap/pk11pub.h
+++ b/security/nss/lib/pk11wrap/pk11pub.h
@@ -655,16 +655,18 @@ CERTSignedCrl* PK11_ImportCRL(PK11SlotIn
  *
  * Return 0 or -1 on failure.  (XXX Should we fix it to always return
  * -1 on failure?)
  */
 int PK11_SignatureLen(SECKEYPrivateKey *key);
 PK11SlotInfo * PK11_GetSlotFromPrivateKey(SECKEYPrivateKey *key);
 SECStatus PK11_Sign(SECKEYPrivateKey *key, SECItem *sig,
 		    const SECItem *hash);
+SECStatus PK11_SignWithSymKey(PK11SymKey *symKey, CK_MECHANISM_TYPE mechanism,
+		    SECItem *param, SECItem *sig, const SECItem *data);
 SECStatus PK11_VerifyRecover(SECKEYPublicKey *key, const SECItem *sig,
 			     SECItem *dsig, void * wincx);
 SECStatus PK11_Verify(SECKEYPublicKey *key, const SECItem *sig,
 		      const SECItem *hash, void *wincx);
 
 
 
 /**********************************************************************
--- a/security/nss/lib/pkcs7/p7decode.c
+++ b/security/nss/lib/pkcs7/p7decode.c
@@ -1276,18 +1276,17 @@ SEC_PKCS7ContentIsSigned(SEC_PKCS7Conten
  * there should be NO authenticatedAttributes (signerinfo->authAttr should
  * be NULL).
  */
 static PRBool
 sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
 			   SECCertUsage certusage,
 			   const SECItem *detached_digest,
 			   HASH_HashType digest_type,
-			   PRBool keepcerts,
-			   PRTime atTime)
+			   PRBool keepcerts)
 {
     SECAlgorithmID **digestalgs, *bulkid;
     const SECItem *digest;
     SECItem **digests;
     SECItem **rawcerts;
     CERTSignedCrl **crls;
     SEC_PKCS7SignerInfo **signerinfos, *signerinfo;
     CERTCertificate *cert, **certs;
@@ -1295,18 +1294,17 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
     CERTCertDBHandle *certdb, *defaultdb; 
     SECOidTag encTag,digestTag;
     HASH_HashType found_type;
     int i, certcount;
     SECKEYPublicKey *publickey;
     SECItem *content_type;
     PK11SymKey *sigkey;
     SECItem *encoded_stime;
-    PRTime stime;
-    PRTime verificationTime;
+    int64 stime;
     SECStatus rv;
 
     /*
      * Everything needed in order to "goto done" safely.
      */
     goodsig = PR_FALSE;
     certcount = 0;
     cert = NULL;
@@ -1433,20 +1431,18 @@ sec_pkcs7_verify_signature(SEC_PKCS7Cont
     /*
      * XXX  This uses the signing time, if available.  Additionally, we
      * might want to, if there is no signing time, get the message time
      * from the mail header itself, and use that.  That would require
      * a change to our interface though, and for S/MIME callers to pass
      * in a time (and for non-S/MIME callers to pass in nothing, or
      * maybe make them pass in the current time, always?).
      */
-    verificationTime = atTime ? atTime
-			      : (encoded_stime ? stime : PR_Now());
     if (CERT_VerifyCert (certdb, cert, PR_TRUE, certusage,
-			 verificationTime,
+			 encoded_stime != NULL ? stime : PR_Now(),
 			 cinfo->pwfn_arg, NULL) != SECSuccess)
 	{
 	/*
 	 * XXX Give the user an option to check the signature anyway?
 	 * If we want to do this, need to give a way to leave and display
 	 * some dialog and get the answer and come back through (or do
 	 * the rest of what we do below elsewhere, maybe by putting it
 	 * in a function that we call below and could call from a dialog
@@ -1756,17 +1752,17 @@ done:
  *	into our local database.
  */
 PRBool
 SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
 			 SECCertUsage certusage,
 			 PRBool keepcerts)
 {
     return sec_pkcs7_verify_signature (cinfo, certusage,
-				       NULL, HASH_AlgNULL, keepcerts, 0);
+				       NULL, HASH_AlgNULL, keepcerts);
 }
 
 /*
  * SEC_PKCS7VerifyDetachedSignature
  *	Look at a PKCS7 contentInfo and check if the signature matches
  *	a passed-in digest (calculated, supposedly, from detached contents).
  *	The verification checks that the signing cert is valid and trusted
  *	for the purpose specified by "certusage".
@@ -1778,44 +1774,19 @@ PRBool
 SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
 				 SECCertUsage certusage,
 				 const SECItem *detached_digest,
 				 HASH_HashType digest_type,
 				 PRBool keepcerts)
 {
     return sec_pkcs7_verify_signature (cinfo, certusage,
 				       detached_digest, digest_type,
-				       keepcerts, 0);
+				       keepcerts);
 }
 
-/*
- * SEC_PKCS7VerifyDetachedSignatureAtTime
- *      Look at a PKCS7 contentInfo and check if the signature matches
- *      a passed-in digest (calculated, supposedly, from detached contents).
- *      The verification checks that the signing cert is valid and trusted
- *      for the purpose specified by "certusage" at time "atTime"
- *      if "atTime" is non-zero, or at the current time (as returned by
- *      PR_Now) otherwise.
- */
-PRBool
-SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-				       SECCertUsage certusage,
-				       const SECItem *detached_digest,
-				       HASH_HashType digest_type,
-				       PRBool keepcerts,
-				       PRTime atTime)
-{
-    if (!atTime) {
-	atTime = PR_Now();
-    }
-
-    return sec_pkcs7_verify_signature (cinfo, certusage,
-				       detached_digest, digest_type,
-				       keepcerts, atTime);
-}
 
 /*
  * Return the asked-for portion of the name of the signer of a PKCS7
  * signed object.
  *
  * Returns a pointer to allocated memory, which must be freed.
  * A NULL return value is an error.
  */
@@ -1868,17 +1839,17 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7
      */
     if (signercert == NULL) {
 	/*
 	 * The cert usage does not matter in this case, because we do not
 	 * actually care about the verification itself, but we have to pick
 	 * some valid usage to pass in.
 	 */
 	(void) sec_pkcs7_verify_signature (cinfo, certUsageEmailSigner,
-					   NULL, HASH_AlgNULL, PR_FALSE, 0);
+					   NULL, HASH_AlgNULL, PR_FALSE);
 	signercert = signerinfos[0]->cert;
 	if (signercert == NULL)
 	    return NULL;
     }
 
     switch (selector) {
       case sec_common_name:
 	container = CERT_GetCommonName (&signercert->subject);
--- a/security/nss/lib/pkcs7/secpkcs7.h
+++ b/security/nss/lib/pkcs7/secpkcs7.h
@@ -128,33 +128,16 @@ extern PRBool SEC_PKCS7VerifySignature(S
  *	into our local database.
  */
 extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
 					       SECCertUsage certusage,
 					       const SECItem *detached_digest,
 					       HASH_HashType digest_type,
 					       PRBool keepcerts);
 
-
-/*
- * SEC_PKCS7VerifyDetachedSignatureAtTime
- *      Look at a PKCS7 contentInfo and check if the signature matches
- *      a passed-in digest (calculated, supposedly, from detached contents).
- *      The verification checks that the signing cert is valid and trusted
- *      for the purpose specified by "certusage" at time "atTime"
- *      if "atTime" is non-zero, or at the current time (as returned by
- *      PR_Now) otherwise.
- */
-extern PRBool SEC_PKCS7VerifyDetachedSignatureAtTime(SEC_PKCS7ContentInfo *cinfo,
-						     SECCertUsage certusage,
-						     const SECItem *detached_digest,
-						     HASH_HashType digest_type,
-						     PRBool keepcerts,
-						     PRTime atTime);
-
 /*
  * SEC_PKCS7GetSignerCommonName, SEC_PKCS7GetSignerEmailAddress
  *      The passed-in contentInfo is espected to be Signed, and these
  *      functions return the specified portion of the full signer name.
  *
  *      Returns a pointer to allocated memory, which must be freed.
  *      A NULL return value is an error.
  */
--- a/security/nss/lib/smime/smime.def
+++ b/security/nss/lib/smime/smime.def
@@ -262,14 +262,8 @@ NSS_Get_NSS_PointerToCMSGenericWrapperDa
 ;+       *;
 ;+};
 ;+NSS_3.13 {    # NSS 3.13 release
 ;+    global:
 NSSSMIME_GetVersion;
 ;+    local:
 ;+       *;
 ;+};
-;+NSS_3.14.3 {    # NSS 3.14.3 release
-;+    global:
-SEC_PKCS7VerifyDetachedSignatureAtTime;
-;+    local:
-;+       *;
-;+};
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -42,16 +42,17 @@ CSRCS = \
 	lowpbe.c   \
 	padbuf.c   \
 	pkcs11.c   \
 	pkcs11c.c  \
 	pkcs11u.c  \
 	rsawrapr.c  \
 	sdb.c  \
 	sftkdb.c  \
+	sftkhmac.c  \
 	sftkpars.c  \
 	sftkpwd.c  \
 	softkver.c  \
 	tlsprf.c   \
 	jpakesftk.c \
 	$(NULL)
 
 ifdef SQLITE_UNSAFE_THREADS
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -483,17 +483,20 @@ static const struct mechanismList mechan
      {CKM_NSS_JPAKE_ROUND1_SHA512,      {0, 0, CKF_GENERATE}, PR_TRUE},
      {CKM_NSS_JPAKE_ROUND2_SHA1,        {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_ROUND2_SHA256,      {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_ROUND2_SHA384,      {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_ROUND2_SHA512,      {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_FINAL_SHA1,         {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_FINAL_SHA256,       {0, 0, CKF_DERIVE}, PR_TRUE},
      {CKM_NSS_JPAKE_FINAL_SHA384,       {0, 0, CKF_DERIVE}, PR_TRUE},
-     {CKM_NSS_JPAKE_FINAL_SHA512,       {0, 0, CKF_DERIVE}, PR_TRUE}
+     {CKM_NSS_JPAKE_FINAL_SHA512,       {0, 0, CKF_DERIVE}, PR_TRUE},
+     /* -------------------- Constant Time TLS MACs ----------------------- */
+     {CKM_NSS_HMAC_CONSTANT_TIME,       {0, 0, CKF_DIGEST}, PR_TRUE},
+     {CKM_NSS_SSL3_MAC_CONSTANT_TIME,   {0, 0, CKF_DIGEST}, PR_TRUE}
 };
 static const CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
 
 /* sigh global so fipstokn can read it */
 PRBool nsc_init = PR_FALSE;
 
 #if defined(CHECK_FORK_PTHREAD) || defined(CHECK_FORK_MIXED)
 
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -452,16 +452,34 @@ sftk_aes_mode(CK_MECHANISM_TYPE mechanis
     case CKM_AES_CTR:
 	return NSS_AES_CTR;
     case CKM_AES_GCM:
 	return NSS_AES_GCM;
     }
     return -1;
 }
 
+static SECStatus
+sftk_EncryptOAEP(SFTKOAEPEncryptInfo *info, unsigned char *output,
+                 unsigned int *outputLen, unsigned int maxLen,
+                 unsigned char *input, unsigned int inputLen)
+{
+    return RSA_EncryptOAEP(info->params, info->key, output, outputLen,
+                           maxLen, input, inputLen);
+}
+
+static SECStatus
+sftk_DecryptOAEP(SFTKOAEPDecryptInfo *info, unsigned char *output,
+                 unsigned int *outputLen, unsigned int maxLen,
+                 unsigned char *input, unsigned int inputLen)
+{
+    return RSA_DecryptOAEP(info->params, info->key, output, outputLen,
+                           maxLen, input, inputLen);
+}
+
 /** NSC_CryptInit initializes an encryption/Decryption operation.
  *
  * Always called by NSC_EncryptInit, NSC_DecryptInit, NSC_WrapKey,NSC_UnwrapKey.
  * Called by NSC_SignInit, NSC_VerifyInit (via sftk_InitCBCMac) only for block
  *  ciphers MAC'ing.
  */
 static CK_RV
 sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
@@ -508,36 +526,87 @@ sftk_CryptInit(CK_SESSION_HANDLE hSessio
 	    crv = CKR_KEY_TYPE_INCONSISTENT;
 	    break;
 	}
 	context->multi = PR_FALSE;
 	context->rsa = PR_TRUE;
 	if (isEncrypt) {
 	    NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
 	    if (pubKey == NULL) {
+	        crv = CKR_KEY_HANDLE_INVALID;
 		break;
 	    }
 	    context->maxLen = nsslowkey_PublicModulusLen(pubKey);
 	    context->cipherInfo =  (void *)pubKey;
 	    context->update = (SFTKCipher) 
 		(pMechanism->mechanism == CKM_RSA_X_509
 					? RSA_EncryptRaw : RSA_EncryptBlock);
 	} else {
 	    NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
 	    if (privKey == NULL) {
+	        crv = CKR_KEY_HANDLE_INVALID;
 		break;
 	    }
 	    context->maxLen = nsslowkey_PrivateModulusLen(privKey);
 	    context->cipherInfo =  (void *)privKey;
 	    context->update = (SFTKCipher) 
 		(pMechanism->mechanism == CKM_RSA_X_509
 					? RSA_DecryptRaw : RSA_DecryptBlock);
 	}
 	context->destroy = sftk_Null;
 	break;
+/* XXX: Disabled until unit tests land.
+    case CKM_RSA_PKCS_OAEP:
+	if (key_type != CKK_RSA) {
+	    crv = CKR_KEY_TYPE_INCONSISTENT;
+	    break;
+	}
+	context->multi = PR_FALSE;
+	context->rsa = PR_TRUE;
+	if (pMechanism->ulParameterLen != sizeof(CK_RSA_PKCS_OAEP_PARAMS)) {
+	    crv = CKR_MECHANISM_PARAM_INVALID;
+	    break;
+	}
+	/\* XXX: Need Parameter validation here *\/
+	if (isEncrypt) {
+	    SFTKOAEPEncryptInfo *info = PORT_New(SFTKOAEPEncryptInfo);
+	    if (info == NULL) {
+	        crv = CKR_HOST_MEMORY;
+	        break;
+	    }
+	    info->params = pMechanism->pParameter;
+	    info->key = sftk_GetPubKey(key, CKK_RSA, &crv);
+	    if (info->key == NULL) {
+	        PORT_Free(info);
+	        crv = CKR_KEY_HANDLE_INVALID;
+	        break;
+	    }
+	    context->update = (SFTKCipher) sftk_EncryptOAEP;
+	    context->maxLen = nsslowkey_PublicModulusLen(info->key);
+	    context->cipherInfo = info;
+	} else {
+	    SFTKOAEPDecryptInfo *info = PORT_New(SFTKOAEPDecryptInfo);
+	    if (info == NULL) {
+	        crv = CKR_HOST_MEMORY;
+	        break;
+	    }
+	    info->params = pMechanism->pParameter;
+	    info->key = sftk_GetPrivKey(key, CKK_RSA, &crv);
+	    if (info->key == NULL) {
+	        PORT_Free(info);
+	        crv = CKR_KEY_HANDLE_INVALID;
+	        break;
+	    }
+	    context->update = (SFTKCipher) sftk_DecryptOAEP;
+	    context->maxLen = nsslowkey_PrivateModulusLen(info->key);
+	    context->cipherInfo = info;
+	}
+	context->destroy = (SFTKDestroy) sftk_Space;
+	break;
+*/
     case CKM_RC2_CBC_PAD:
 	context->doPad = PR_TRUE;
 	/* fall thru */
     case CKM_RC2_ECB:
     case CKM_RC2_CBC:
 	context->blockSize = 8;
 	if (key_type != CKK_RC2) {
 	    crv = CKR_KEY_TYPE_INCONSISTENT;
@@ -1455,27 +1524,35 @@ sftk_doSub ## mmm(SFTKSessionContext *co
 DOSUB(MD2)
 DOSUB(MD5)
 DOSUB(SHA1)
 DOSUB(SHA224)
 DOSUB(SHA256)
 DOSUB(SHA384)
 DOSUB(SHA512)
 
-/*
- * HMAC General copies only a portion of the result. This update routine likes
- * the final HMAC output with the signature.
- */
 static SECStatus
-sftk_HMACCopy(CK_ULONG *copyLen,unsigned char *sig,unsigned int *sigLen,
-		unsigned int maxLen,unsigned char *hash, unsigned int hashLen)
+sftk_SignCopy(
+	CK_ULONG *copyLen,
+	void *out, unsigned int *outLength,
+	unsigned int maxLength,
+	const unsigned char *hashResult,
+	unsigned int hashResultLength)
 {
-    if (maxLen < *copyLen) return SECFailure;
-    PORT_Memcpy(sig,hash,*copyLen);
-    *sigLen = *copyLen;
+    unsigned int toCopy = *copyLen;
+    if (toCopy > maxLength) {
+	toCopy = maxLength;
+    }
+    if (toCopy > hashResultLength) {
+	toCopy = hashResultLength;
+    }
+    memcpy(out, hashResult, toCopy);
+    if (outLength) {
+	*outLength = toCopy;
+    }
     return SECSuccess;
 }
 
 /* Verify is just a compare for HMAC */
 static SECStatus
 sftk_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
 				unsigned char *hash, unsigned int hashLen)
 {
@@ -1514,24 +1591,24 @@ sftk_doHMACInit(SFTKSessionContext *cont
 	    return CKR_KEY_SIZE_RANGE;
 	}
 	return CKR_HOST_MEMORY;
     }
     context->hashUpdate = (SFTKHash) HMAC_Update;
     context->end = (SFTKEnd) HMAC_Finish;
 
     context->hashdestroy = (SFTKDestroy) HMAC_Destroy;
-    intpointer = (CK_ULONG *) PORT_Alloc(sizeof(CK_ULONG));
+    intpointer = PORT_New(CK_ULONG);
     if (intpointer == NULL) {
 	return CKR_HOST_MEMORY;
     }
     *intpointer = mac_size;
-    context->cipherInfo = (void *) intpointer;
+    context->cipherInfo = intpointer;
     context->destroy = (SFTKDestroy) sftk_Space;
-    context->update = (SFTKCipher) sftk_HMACCopy;
+    context->update = (SFTKCipher) sftk_SignCopy;
     context->verify = (SFTKVerify) sftk_HMACCmp;
     context->maxLen = hashObj->length;
     HMAC_Begin(HMACcontext);
     return CKR_OK;
 }
 
 /*
  *  SSL Macing support. SSL Macs are inited, then update with the base
@@ -2167,16 +2244,75 @@ finish_rsa:
 	break;
     case CKM_SSL3_SHA1_MAC:
 	crv = sftk_doSSLMACInit(context,SEC_OID_SHA1,key,
 					*(CK_ULONG *)pMechanism->pParameter);
 	break;
     case CKM_TLS_PRF_GENERAL:
 	crv = sftk_TLSPRFInit(context, key, key_type);
 	break;
+
+    case CKM_NSS_HMAC_CONSTANT_TIME: {
+	sftk_MACConstantTimeCtx *ctx =
+	    sftk_HMACConstantTime_New(pMechanism,key);
+	CK_ULONG *intpointer;
+
+	if (ctx == NULL) {
+	    crv = CKR_ARGUMENTS_BAD;
+	    break;
+	}
+	intpointer = PORT_New(CK_ULONG);
+	if (intpointer == NULL) {
+	    crv = CKR_HOST_MEMORY;
+	    break;
+	}
+	*intpointer = ctx->hash->length;
+
+	context->cipherInfo    = intpointer;
+	context->hashInfo      = ctx;
+	context->currentMech   = pMechanism->mechanism;
+	context->hashUpdate    = sftk_HMACConstantTime_Update;
+	context->hashdestroy   = sftk_MACConstantTime_DestroyContext;
+	context->end           = sftk_MACConstantTime_EndHash;
+	context->update        = sftk_SignCopy;
+	context->destroy       = sftk_Space;
+	context->maxLen        = 64;
+	context->multi         = PR_TRUE;
+	break;
+    }
+
+    case CKM_NSS_SSL3_MAC_CONSTANT_TIME: {
+	sftk_MACConstantTimeCtx *ctx =
+	    sftk_SSLv3MACConstantTime_New(pMechanism,key);
+	CK_ULONG *intpointer;
+
+	if (ctx == NULL) {
+	    crv = CKR_ARGUMENTS_BAD;
+	    break;
+	}
+	intpointer = PORT_New(CK_ULONG);
+	if (intpointer == NULL) {
+	    crv = CKR_HOST_MEMORY;
+	    break;
+	}
+	*intpointer = ctx->hash->length;
+
+	context->cipherInfo    = intpointer;
+	context->hashInfo      = ctx;
+	context->currentMech   = pMechanism->mechanism;
+	context->hashUpdate    = sftk_SSLv3MACConstantTime_Update;
+	context->hashdestroy   = sftk_MACConstantTime_DestroyContext;
+	context->end           = sftk_MACConstantTime_EndHash;
+	context->update        = sftk_SignCopy;
+	context->destroy       = sftk_Space;
+	context->maxLen        = 64;
+	context->multi         = PR_TRUE;
+	break;
+    }
+
     default:
 	crv = CKR_MECHANISM_INVALID;
 	break;
     }
 
     if (crv != CKR_OK) {
 	if (info) PORT_Free(info);
         sftk_FreeContext(context);
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -96,16 +96,18 @@ typedef struct SFTKObjectStr SFTKObject;
 typedef struct SFTKSessionObjectStr SFTKSessionObject;
 typedef struct SFTKTokenObjectStr SFTKTokenObject;
 typedef struct SFTKSessionStr SFTKSession;
 typedef struct SFTKSlotStr SFTKSlot;
 typedef struct SFTKSessionContextStr SFTKSessionContext;
 typedef struct SFTKSearchResultsStr SFTKSearchResults;
 typedef struct SFTKHashVerifyInfoStr SFTKHashVerifyInfo;
 typedef struct SFTKHashSignInfoStr SFTKHashSignInfo;
+typedef struct SFTKOAEPEncryptInfoStr SFTKOAEPEncryptInfo;
+typedef struct SFTKOAEPDecryptInfoStr SFTKOAEPDecryptInfo;
 typedef struct SFTKSSLMACInfoStr SFTKSSLMACInfo;
 typedef struct SFTKItemTemplateStr SFTKItemTemplate;
 
 /* define function pointer typdefs for pointer tables */
 typedef void (*SFTKDestroy)(void *, PRBool);
 typedef void (*SFTKBegin)(void *);
 typedef SECStatus (*SFTKCipher)(void *,void *,unsigned int *,unsigned int,
 					void *, unsigned int);
@@ -367,16 +369,29 @@ struct SFTKHashVerifyInfoStr {
 };
 
 struct SFTKHashSignInfoStr {
     SECOidTag   	hashOid;
     void		*params;
     NSSLOWKEYPrivateKey	*key;
 };
 
+/**
+ * Contexts for RSA-OAEP
+ */
+struct SFTKOAEPEncryptInfoStr {
+    CK_RSA_PKCS_OAEP_PARAMS *params;
+    NSSLOWKEYPublicKey *key;
+};
+
+struct SFTKOAEPDecryptInfoStr {
+    CK_RSA_PKCS_OAEP_PARAMS *params;
+    NSSLOWKEYPrivateKey *key;
+};
+
 /* context for the Final SSLMAC message */
 struct SFTKSSLMACInfoStr {
     void 		*hashContext;
     SFTKBegin		begin;
     SFTKHash		update;
     SFTKEnd		end;
     CK_ULONG		macSize;
     int			padSize;
@@ -688,16 +703,38 @@ extern
 CK_RV jpake_Round2(HASH_HashType hashType,
                    CK_NSS_JPAKERound2Params * params,
                    SFTKObject * sourceKey, SFTKObject * key);
 extern
 CK_RV jpake_Final(HASH_HashType hashType,
                   const CK_NSS_JPAKEFinalParams * params,
                   SFTKObject * sourceKey, SFTKObject * key);
 
+/* Constant time MAC functions (hmacct.c) */
+
+struct sftk_MACConstantTimeCtxStr {
+    const SECHashObject *hash;
+    unsigned char mac[64];
+    unsigned char secret[64];
+    unsigned int headerLength;
+    unsigned int secretLength;
+    unsigned int totalLength;
+    unsigned char header[75];
+};
+typedef struct sftk_MACConstantTimeCtxStr sftk_MACConstantTimeCtx;
+sftk_MACConstantTimeCtx* sftk_HMACConstantTime_New(
+	CK_MECHANISM_PTR mech, SFTKObject *key);
+sftk_MACConstantTimeCtx* sftk_SSLv3MACConstantTime_New(
+	CK_MECHANISM_PTR mech, SFTKObject *key);
+void sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len);
+void sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len);
+void sftk_MACConstantTime_EndHash(
+	void *pctx, void *out, unsigned int *outLength, unsigned int maxLength);
+void sftk_MACConstantTime_DestroyContext(void *pctx, PRBool);
+
 /****************************************
  * implement TLS Pseudo Random Function (PRF)
  */
 
 extern CK_RV
 sftk_TLSPRFInit(SFTKSessionContext *context, 
 		  SFTKObject *        key, 
 		  CK_KEY_TYPE         key_type);
--- a/security/nss/lib/softoken/rsawrapr.c
+++ b/security/nss/lib/softoken/rsawrapr.c
@@ -1,160 +1,65 @@
 /*
  * PKCS#1 encoding and decoding functions.
  * This file is believed to contain no code licensed from other parties.
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: rsawrapr.c,v 1.21 2012/06/26 22:27:31 rrelyea%redhat.com Exp $ */
+/* $Id: rsawrapr.c,v 1.22 2013/02/05 02:19:52 ryan.sleevi%gmail.com Exp $ */
 
 #include "blapi.h"
 #include "softoken.h"
 
 #include "lowkeyi.h"
 #include "secerr.h"
 
 #define RSA_BLOCK_MIN_PAD_LEN		8
 #define RSA_BLOCK_FIRST_OCTET		0x00
 #define RSA_BLOCK_PRIVATE0_PAD_OCTET	0x00
 #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
-
-#define FLAT_BUFSIZE 512	/* bytes to hold flattened SHA1Context. */
-
 /* Needed for RSA-PSS functions */
 static const unsigned char eightZeros[] = { 0, 0, 0, 0, 0, 0, 0, 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 = PORT_Alloc(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)
-    	PORT_Free(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);
 }
 
 /*
  * Format one block of data for public/private key encryption using
  * the rules defined in PKCS #1.
  */
 static unsigned char *
 rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
@@ -260,107 +165,16 @@ rsa_FormatOneBlock(unsigned modulusLen, 
 	    PORT_Free (block);
 	    return NULL;
 	}
 	bp += padLen;
 	*bp++ = RSA_BLOCK_AFTER_PAD_OCTET;
 	PORT_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) {
-	    sftk_fatalError = PR_TRUE;
-	    PORT_Free (block);
-	    return NULL;
-	}
-	bp += OAEP_SALT_LEN;
-
-	/*
-	 * Pad1
-	 */
-	PORT_Memset (bp, OAEP_PAD_OCTET, OAEP_PAD_LEN);
-	bp += OAEP_PAD_LEN;
-
-	/*
-	 * Data
-	 */
-	PORT_Memcpy (bp, data->data, data->len);
-	bp += data->len;
-
-	/*
-	 * Pad2
-	 */
-	if (bp < (block + modulusLen)) {
-	    rv = RNG_GenerateGlobalRandomBytes(bp, block - bp + modulusLen);
-	    if (rv != SECSuccess) {
-		sftk_fatalError = PR_TRUE;
-		PORT_Free (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) {
-	    PORT_Free (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) {
-	    PORT_Free (block);
-	    return NULL;
-	}
-
-	break;
-
       default:
 	PORT_Assert (0);
 	PORT_Free (block);
 	return NULL;
     }
 
     return block;
 }
@@ -398,36 +212,16 @@ rsa_FormatBlock(SECItem *result, unsigne
 	if (result->data == NULL) {
 	    result->len = 0;
 	    return SECFailure;
 	}
 	result->len = 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
 	 * Pad is zeros. The application is responsible for recovering
 	 * the actual data.
 	 */
 	if (data->len > modulusLen ) {
 	    return SECFailure;
@@ -954,16 +748,276 @@ MGF1(HASH_HashType hashAlg, unsigned cha
         }
     }
     (*hash->destroy)(hashContext, PR_TRUE);
 
     return SECSuccess;
 }
 
 /*
+ * Decodes an EME-OAEP encoded block, validating the encoding in constant
+ * time.
+ * Described in RFC 3447, section 7.1.2.
+ * input contains the encoded block, after decryption.
+ * label is the optional value L that was associated with the message.
+ * On success, the original message and message length will be stored in
+ * output and outputLen.
+ */
+static SECStatus
+eme_oaep_decode(unsigned char *output, unsigned int *outputLen,
+                unsigned int maxOutputLen,
+                const unsigned char *input, unsigned int inputLen,
+                HASH_HashType hashAlg, HASH_HashType maskHashAlg,
+                const unsigned char *label, unsigned int labelLen)
+{
+    const SECHashObject *hash;
+    void *hashContext;
+    SECStatus rv = SECFailure;
+    unsigned char labelHash[HASH_LENGTH_MAX];
+    unsigned int i, maskLen, paddingOffset;
+    unsigned char *mask = NULL, *tmpOutput = NULL;
+    unsigned char isGood, foundPaddingEnd;
+
+    hash = HASH_GetRawHashObject(hashAlg);
+
+    /* 1.c */
+    if (inputLen < (hash->length * 2) + 2) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
+    /* Step 3.a - Generate lHash */
+    hashContext = (*hash->create)();
+    if (hashContext == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return SECFailure;
+    }
+    (*hash->begin)(hashContext);
+    if (labelLen > 0)
+        (*hash->update)(hashContext, label, labelLen);
+    (*hash->end)(hashContext, labelHash, &i, sizeof(labelHash));
+    (*hash->destroy)(hashContext, PR_TRUE);
+
+    tmpOutput = (unsigned char*)PORT_Alloc(inputLen);
+    if (tmpOutput == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto done;
+    }
+
+    maskLen = inputLen - hash->length - 1;
+    mask = (unsigned char*)PORT_Alloc(maskLen);
+    if (mask == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        goto done;
+    }
+
+    PORT_Memcpy(tmpOutput, input, inputLen);
+
+    /* 3.c - Generate seedMask */
+    MGF1(maskHashAlg, mask, hash->length, &tmpOutput[1 + hash->length],
+         inputLen - hash->length - 1);
+    /* 3.d - Unmask seed */
+    for (i = 0; i < hash->length; ++i)
+        tmpOutput[1 + i] ^= mask[i];
+
+    /* 3.e - Generate dbMask */
+    MGF1(maskHashAlg, mask, maskLen, &tmpOutput[1], hash->length);
+    /* 3.f - Unmask DB */
+    for (i = 0; i < maskLen; ++i)
+        tmpOutput[1 + hash->length + i] ^= mask[i];
+
+    /* 3.g - Compare Y, lHash, and PS in constant time
+     * Warning: This code is timing dependent and must not disclose which of
+     * these were invalid.
+     */
+    paddingOffset = 0;
+    isGood = 1;
+    foundPaddingEnd = 0;
+
+    /* Compare Y */
+    isGood &= constantTimeEQ8(0x00, tmpOutput[0]);
+
+    /* Compare lHash and lHash' */
+    isGood &= constantTimeCompare(&labelHash[0],
+                                  &tmpOutput[1 + hash->length],
+                                  hash->length);
+
+    /* Compare that the padding is zero or more zero octets, followed by a
+     * 0x01 octet */
+    for (i = 1 + (hash->length * 2); i < inputLen; ++i) {
+        unsigned char isZero = constantTimeEQ8(0x00, tmpOutput[i]);
+        unsigned char isOne = constantTimeEQ8(0x01, tmpOutput[i]);
+        /* non-constant time equivalent:
+         * if (tmpOutput[i] == 0x01 && !foundPaddingEnd)
+         *     paddingOffset = i;
+         */
+        paddingOffset = constantTimeCondition(isOne & ~foundPaddingEnd, i,
+                                              paddingOffset);
+        /* non-constant time equivalent:
+         * if (tmpOutput[i] == 0x01)
+         *    foundPaddingEnd = true;
+         *
+         * Note: This may yield false positives, as it will be set whenever
+         * a 0x01 byte is encountered. If there was bad padding (eg:
+         * 0x03 0x02 0x01), foundPaddingEnd will still be set to true, and
+         * paddingOffset will still be set to 2.
+         */
+        foundPaddingEnd = constantTimeCondition(isOne, 1, foundPaddingEnd);
+        /* non-constant time equivalent:
+         * if (tmpOutput[i] != 0x00 && tmpOutput[i] != 0x01 &&
+         *     !foundPaddingEnd) {
+         *    isGood = false;
+         * }
+         *
+         * Note: This may yield false positives, as a message (and padding)
+         * that is entirely zeros will result in isGood still being true. Thus
+         * it's necessary to check foundPaddingEnd is positive below.
+         */
+        isGood = constantTimeCondition(~foundPaddingEnd & ~isZero, 0, isGood);
+    }
+
+    /* While both isGood and foundPaddingEnd may have false positives, they
+     * cannot BOTH have false positives. If both are not true, then an invalid
+     * message was received. Note, this comparison must still be done in constant
+     * time so as not to leak either condition.
+     */
+    if (!(isGood & foundPaddingEnd)) {
+        PORT_SetError(SEC_ERROR_BAD_DATA);
+        goto done;
+    }
+
+    /* End timing dependent code */
+
+    ++paddingOffset; /* Skip the 0x01 following the end of PS */
+
+    *outputLen = inputLen - paddingOffset;
+    if (*outputLen > maxOutputLen) {
+        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+        goto done;
+    }
+
+    if (*outputLen)
+        PORT_Memcpy(output, &tmpOutput[paddingOffset], *outputLen);
+    rv = SECSuccess;
+
+done:
+    if (mask)
+        PORT_ZFree(mask, maskLen);
+    if (tmpOutput)
+        PORT_ZFree(tmpOutput, inputLen);
+    return rv;
+}
+
+/*
+ * Generate an EME-OAEP encoded block for encryption
+ * Described in RFC 3447, section 7.1.1
+ * We use input instead of M for the message to be encrypted
+ * label is the optional value L to be associated with the message.
+ */
+static SECStatus
+eme_oaep_encode(unsigned char *em, unsigned int emLen,
+                const unsigned char *input, unsigned int inputLen,
+                HASH_HashType hashAlg, HASH_HashType maskHashAlg,
+                const unsigned char *label, unsigned int labelLen)
+{
+    const SECHashObject *hash;
+    void *hashContext;
+    SECStatus rv;
+    unsigned char *mask;
+    unsigned int reservedLen, dbMaskLen, i;
+
+    hash = HASH_GetRawHashObject(hashAlg);
+
+    /* Step 1.b */
+    reservedLen = (2 * hash->length) + 2;
+    if (emLen < reservedLen || inputLen > (emLen - reservedLen)) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+
+    /*
+     * From RFC 3447, Section 7.1
+     *                      +----------+---------+-------+
+     *                 DB = |  lHash   |    PS   |   M   |
+     *                      +----------+---------+-------+
+     *                                     |
+     *           +----------+              V
+     *           |   seed   |--> MGF ---> xor
+     *           +----------+              |
+     *                 |                   |
+     *        +--+     V                   |
+     *        |00|    xor <----- MGF <-----|
+     *        +--+     |                   |
+     *          |      |                   |
+     *          V      V                   V
+     *        +--+----------+----------------------------+
+     *  EM =  |00|maskedSeed|          maskedDB          |
+     *        +--+----------+----------------------------+
+     *
+     * We use mask to hold the result of the MGF functions, and all other
+     * values are generated in their final resting place.
+     */
+    *em = 0x00;
+
+    /* Step 2.a - Generate lHash */
+    hashContext = (*hash->create)();
+    if (hashContext == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return SECFailure;
+    }
+    (*hash->begin)(hashContext);
+    if (labelLen > 0)
+        (*hash->update)(hashContext, label, labelLen);
+    (*hash->end)(hashContext, &em[1 + hash->length], &i, hash->length);
+    (*hash->destroy)(hashContext, PR_TRUE);
+
+    /* Step 2.b - Generate PS */
+    if (emLen - reservedLen - inputLen > 0) {
+        PORT_Memset(em + 1 + (hash->length * 2), 0x00,
+                    emLen - reservedLen - inputLen);
+    }
+
+    /* Step 2.c. - Generate DB
+     * DB = lHash || PS || 0x01 || M
+     * Note that PS and lHash have already been placed into em at their
+     * appropriate offsets. This just copies M into place
+     */
+    em[emLen - inputLen - 1] = 0x01;
+    if (inputLen)
+        PORT_Memcpy(em + emLen - inputLen, input, inputLen);
+
+    /* Step 2.d - Generate seed */
+    rv = RNG_GenerateGlobalRandomBytes(em + 1, hash->length);
+    if (rv != SECSuccess) {
+        return rv;
+    }
+
+    /* Step 2.e - Generate dbMask*/
+    dbMaskLen = emLen - hash->length - 1;
+    mask = (unsigned char*)PORT_Alloc(dbMaskLen);
+    if (mask == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return SECFailure;
+    }
+    MGF1(maskHashAlg, mask, dbMaskLen, em + 1, hash->length);
+    /* Step 2.f - Compute maskedDB*/
+    for (i = 0; i < dbMaskLen; ++i)
+        em[1 + hash->length + i] ^= mask[i];
+
+    /* Step 2.g - Generate seedMask */
+    MGF1(maskHashAlg, mask, hash->length, &em[1 + hash->length], dbMaskLen);
+    /* Step 2.h - Compute maskedSeed */
+    for (i = 0; i < hash->length; ++i)
+        em[1 + i] ^= mask[i];
+
+    PORT_ZFree(mask, dbMaskLen);
+    return SECSuccess;
+}
+
+/*
  * Encode a RSA-PSS signature.
  * Described in RFC 3447, section 9.1.1.
  * We use mHash instead of M as input.
  * emBits from the RFC is just modBits - 1, see section 8.1.1.
  * We only support MGF1 as the MGF.
  *
  * NOTE: this code assumes modBits is a multiple of 8.
  */
@@ -1003,17 +1057,17 @@ emsa_pss_encode(unsigned char *em, unsig
     (*hash->begin)(hash_context);
     (*hash->update)(hash_context, eightZeros, 8);
     (*hash->update)(hash_context, mHash, hash->length);
     (*hash->update)(hash_context, &em[dbMaskLen - sLen], sLen);
     (*hash->end)(hash_context, &em[dbMaskLen], &i, hash->length);
     (*hash->destroy)(hash_context, PR_TRUE);
 
     /* Step 7 + 8 */
-    memset(em, 0, dbMaskLen - sLen - 1);
+    PORT_Memset(em, 0, dbMaskLen - sLen - 1);
     em[dbMaskLen - sLen - 1] = 0x01;
 
     /* Step 9 */
     dbMask = (unsigned char *)PORT_Alloc(dbMaskLen);
     if (dbMask == NULL) {
 	PORT_SetError(SEC_ERROR_NO_MEMORY);
 	return SECFailure;
     }
@@ -1246,8 +1300,150 @@ RSA_SignPSS(CK_RSA_PKCS_PSS_PARAMS *pss_
 	sftk_fatalError = PR_TRUE;
     }
     *output_len = modulus_len;
 
 done:
     PORT_Free(pss_encoded);
     return rv;
 }
+
+/* MGF1 is the only supported MGF. */
+SECStatus
+RSA_EncryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
+                NSSLOWKEYPublicKey *key,
+                unsigned char *output, unsigned int *outputLen,
+                unsigned int maxOutputLen,
+                const unsigned char *input, unsigned int inputLen)
+{
+    SECStatus rv = SECFailure;
+    unsigned int modulusLen = nsslowkey_PublicModulusLen(key);
+    unsigned char *oaepEncoded = NULL;
+    unsigned char *sourceData = NULL;
+    unsigned int sourceDataLen = 0;
+
+    HASH_HashType hashAlg;
+    HASH_HashType maskHashAlg;
+
+    if (maxOutputLen < modulusLen) {
+        PORT_SetError(SEC_ERROR_OUTPUT_LEN);
+        return SECFailure;
+    }
+    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+    if (key->keyType != NSSLOWKEYRSAKey) {
+        PORT_SetError(SEC_ERROR_INVALID_KEY);
+        return SECFailure;
+    }
+
+    hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
+    maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
+    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+
+    /* The PKCS#11 source parameter is the "source" of the label parameter.
+     * The only defined source is explicitly specified, in which case, the
+     * label is an optional byte string in pSourceData. If ulSourceDataLen is
+     * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
+     */
+    if (oaepParams->source != CKZ_DATA_SPECIFIED) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+    sourceData = (unsigned char*)oaepParams->pSourceData;
+    sourceDataLen = oaepParams->ulSourceDataLen;
+    if ((sourceDataLen == 0 && sourceData != NULL) ||
+        (sourceDataLen > 0 && sourceData == NULL)) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+
+    oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
+    if (oaepEncoded == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return SECFailure;
+    }
+    rv = eme_oaep_encode(oaepEncoded, modulusLen, input, inputLen,
+                         hashAlg, maskHashAlg, sourceData, sourceDataLen);
+    if (rv != SECSuccess)
+        goto done;
+
+    rv = RSA_PublicKeyOp(&key->u.rsa, output, oaepEncoded);
+    if (rv != SECSuccess)
+        goto done;
+    *outputLen = modulusLen;
+
+done:
+    PORT_Free(oaepEncoded);
+    return rv;
+}
+
+/* MGF1 is the only supported MGF. */
+SECStatus
+RSA_DecryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
+                NSSLOWKEYPrivateKey *key,
+                unsigned char *output, unsigned int *outputLen,
+                unsigned int maxOutputLen,
+                const unsigned char *input, unsigned int inputLen)
+{
+    SECStatus rv = SECFailure;
+    unsigned int modulusLen = nsslowkey_PrivateModulusLen(key);
+    unsigned char *oaepEncoded = NULL;
+    unsigned char *sourceData = NULL;
+    unsigned int sourceDataLen = 0;
+
+    HASH_HashType hashAlg = GetHashTypeFromMechanism(oaepParams->hashAlg);
+    HASH_HashType maskHashAlg = GetHashTypeFromMechanism(oaepParams->mgf);
+
+    if ((hashAlg == HASH_AlgNULL) || (maskHashAlg == HASH_AlgNULL)) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+
+    if (inputLen != modulusLen) {
+        PORT_SetError(SEC_ERROR_INPUT_LEN);
+        return SECFailure;
+    }
+    PORT_Assert(key->keyType == NSSLOWKEYRSAKey);
+    if (key->keyType != NSSLOWKEYRSAKey) {
+        PORT_SetError(SEC_ERROR_INVALID_KEY);
+        return SECFailure;
+    }
+
+    /* The PKCS#11 source parameter is the "source" of the label parameter.
+     * The only defined source is explicitly specified, in which case, the
+     * label is an optional byte string in pSourceData. If ulSourceDataLen is
+     * zero, then pSourceData MUST be NULL - otherwise, it must be non-NULL.
+     */
+    if (oaepParams->source != CKZ_DATA_SPECIFIED) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+    sourceData = (unsigned char*)oaepParams->pSourceData;
+    sourceDataLen = oaepParams->ulSourceDataLen;
+    if ((sourceDataLen == 0 && sourceData != NULL) ||
+        (sourceDataLen > 0 && sourceData == NULL)) {
+        PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+        return SECFailure;
+    }
+
+    oaepEncoded = (unsigned char *)PORT_Alloc(modulusLen);
+    if (oaepEncoded == NULL) {
+        PORT_SetError(SEC_ERROR_NO_MEMORY);
+        return SECFailure;
+    }
+
+    rv = RSA_PrivateKeyOpDoubleChecked(&key->u.rsa, oaepEncoded, input);
+    if (rv != SECSuccess && PORT_GetError() == SEC_ERROR_LIBRARY_FAILURE) {
+        sftk_fatalError = PR_TRUE;
+        goto done;
+    }
+
+    rv = eme_oaep_decode(output, outputLen, maxOutputLen, oaepEncoded,
+                         modulusLen, hashAlg, maskHashAlg, sourceData,
+                         sourceDataLen);
+
+done:
+    if (oaepEncoded)
+        PORT_ZFree(oaepEncoded, modulusLen);
+    return rv;
+}
--- a/security/nss/lib/softoken/sdb.c
+++ b/security/nss/lib/softoken/sdb.c
@@ -249,16 +249,21 @@ sdb_getFallbackTempDir(void)
     if (zDir == NULL)
         return NULL;
     return PORT_Strdup(zDir);
 }
 #else
 #error "sdb_getFallbackTempDir not implemented"
 #endif
 
+#ifndef SQLITE_FCNTL_TEMPFILENAME
+/* SQLITE_FCNTL_TEMPFILENAME was added in SQLite 3.7.15 */
+#define SQLITE_FCNTL_TEMPFILENAME 16
+#endif
+
 static char *
 sdb_getTempDir(sqlite3 *sqlDB)
 {
     int sqlrv;
     char *result = NULL;
     char *tempName = NULL;
     char *foundSeparator = NULL;
 
new file mode 100644
--- /dev/null
+++ b/security/nss/lib/softoken/sftkhmac.c
@@ -0,0 +1,192 @@
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "seccomon.h"
+#include "secerr.h"
+#include "blapi.h"
+#include "pkcs11i.h"
+#include "softoken.h"
+#include "hmacct.h"
+
+/* MACMechanismToHash converts a PKCS#11 MAC mechanism into a freebl hash
+ * type. */
+static HASH_HashType
+MACMechanismToHash(CK_MECHANISM_TYPE mech)
+{
+    switch (mech) {
+	case CKM_MD5_HMAC:
+	case CKM_SSL3_MD5_MAC:
+	    return HASH_AlgMD5;
+	case CKM_SHA_1_HMAC:
+	case CKM_SSL3_SHA1_MAC:
+	    return HASH_AlgSHA1;
+	case CKM_SHA224_HMAC:
+	    return HASH_AlgSHA224;
+	case CKM_SHA256_HMAC:
+	    return HASH_AlgSHA256;
+	case CKM_SHA384_HMAC:
+	    return HASH_AlgSHA384;
+	case CKM_SHA512_HMAC:
+	    return HASH_AlgSHA512;
+    }
+    return HASH_AlgNULL;
+}
+
+static sftk_MACConstantTimeCtx *
+SetupMAC(CK_MECHANISM_PTR mech, SFTKObject *key)
+{
+    CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
+	(CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
+    sftk_MACConstantTimeCtx *ctx;
+    HASH_HashType alg;
+    SFTKAttribute *keyval;
+    unsigned char secret[sizeof(ctx->secret)];
+    unsigned int secretLength;
+
+    if (mech->ulParameterLen != sizeof(CK_NSS_MAC_CONSTANT_TIME_PARAMS)) {
+	return NULL;
+    }
+
+    alg = MACMechanismToHash(params->macAlg);
+    if (alg == HASH_AlgNULL) {
+	return NULL;
+    }
+
+    keyval = sftk_FindAttribute(key,CKA_VALUE);
+    if (keyval == NULL) {
+	return NULL;
+    }
+    secretLength = keyval->attrib.ulValueLen;
+    if (secretLength > sizeof(secret)) {
+	sftk_FreeAttribute(keyval);
+	return NULL;
+    }
+    memcpy(secret, keyval->attrib.pValue, secretLength);
+    sftk_FreeAttribute(keyval);
+
+    ctx = PORT_Alloc(sizeof(sftk_MACConstantTimeCtx));
+    if (!ctx) {
+	return NULL;
+    }
+
+    memcpy(ctx->secret, secret, secretLength);
+    ctx->secretLength = secretLength;
+    ctx->hash = HASH_GetRawHashObject(alg);
+    ctx->totalLength = params->ulBodyTotalLen;
+
+    return ctx;
+}
+
+sftk_MACConstantTimeCtx *
+sftk_HMACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
+{
+    CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
+	(CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
+    sftk_MACConstantTimeCtx *ctx;
+
+    if (params->ulHeaderLen > sizeof(ctx->header)) {
+	return NULL;
+    }
+    ctx = SetupMAC(mech, key);
+    if (!ctx) {
+	return NULL;
+    }
+
+    ctx->headerLength = params->ulHeaderLen;
+    memcpy(ctx->header, params->pHeader, params->ulHeaderLen);
+    return ctx;
+}
+
+sftk_MACConstantTimeCtx *
+sftk_SSLv3MACConstantTime_New(CK_MECHANISM_PTR mech, SFTKObject *key)
+{
+    CK_NSS_MAC_CONSTANT_TIME_PARAMS *params =
+	(CK_NSS_MAC_CONSTANT_TIME_PARAMS *) mech->pParameter;
+    unsigned int padLength = 40, j;
+    sftk_MACConstantTimeCtx *ctx;
+
+    if (params->macAlg != CKM_SSL3_MD5_MAC &&
+	params->macAlg != CKM_SSL3_SHA1_MAC) {
+	return NULL;
+    }
+    ctx = SetupMAC(mech, key);
+    if (!ctx) {
+	return NULL;
+    }
+
+    if (params->macAlg == CKM_SSL3_MD5_MAC) {
+	padLength = 48;
+    }
+
+    ctx->headerLength =
+	ctx->secretLength +
+	padLength +
+	params->ulHeaderLen;
+
+    if (ctx->headerLength > sizeof(ctx->header)) {
+	goto loser;
+    }
+
+    j = 0;
+    memcpy(&ctx->header[j], ctx->secret, ctx->secretLength);
+    j += ctx->secretLength;
+    memset(&ctx->header[j], 0x36, padLength);
+    j += padLength;
+    memcpy(&ctx->header[j], params->pHeader, params->ulHeaderLen);
+
+    return ctx;
+
+loser:
+    PORT_Free(ctx);
+    return NULL;
+}
+
+void
+sftk_HMACConstantTime_Update(void *pctx, void *data, unsigned int len)
+{
+    sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+    SECStatus rv = HMAC_ConstantTime(
+	ctx->mac, NULL, sizeof(ctx->mac),
+	ctx->hash,
+	ctx->secret, ctx->secretLength,
+	ctx->header, ctx->headerLength,
+	data, len,
+	ctx->totalLength);
+    PORT_Assert(rv == SECSuccess);
+}
+
+void
+sftk_SSLv3MACConstantTime_Update(void *pctx, void *data, unsigned int len)
+{
+    sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+    SECStatus rv = SSLv3_MAC_ConstantTime(
+	ctx->mac, NULL, sizeof(ctx->mac),
+	ctx->hash,
+	ctx->secret, ctx->secretLength,
+	ctx->header, ctx->headerLength,
+	data, len,
+	ctx->totalLength);
+    PORT_Assert(rv == SECSuccess);
+}
+
+void
+sftk_MACConstantTime_EndHash(void *pctx, void *out, unsigned int *outLength,
+			     unsigned int maxLength)
+{
+    const sftk_MACConstantTimeCtx *ctx = (sftk_MACConstantTimeCtx *) pctx;
+    unsigned int toCopy = ctx->hash->length;
+    if (toCopy > maxLength) {
+	toCopy = maxLength;
+    }
+    memcpy(out, ctx->mac, toCopy);
+    if (outLength) {
+	*outLength = toCopy;
+    }
+}
+
+void
+sftk_MACConstantTime_DestroyContext(void *pctx, PRBool free)
+{
+    PORT_Free(pctx);
+}
--- a/security/nss/lib/softoken/softkver.h
+++ b/security/nss/lib/softoken/softkver.h
@@ -20,16 +20,16 @@
 
 /*
  * Softoken's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <ECC>][ <Beta>]"
  */
-#define SOFTOKEN_VERSION  "3.14.2.0" SOFTOKEN_ECC_STRING
+#define SOFTOKEN_VERSION  "3.14.3.0" SOFTOKEN_ECC_STRING " Beta"
 #define SOFTOKEN_VMAJOR   3
 #define SOFTOKEN_VMINOR   14
-#define SOFTOKEN_VPATCH   2
+#define SOFTOKEN_VPATCH   3
 #define SOFTOKEN_VBUILD   0
-#define SOFTOKEN_BETA     PR_FALSE
+#define SOFTOKEN_BETA     PR_TRUE
 
 #endif /* _SOFTKVER_H_ */
--- a/security/nss/lib/softoken/softoken.h
+++ b/security/nss/lib/softoken/softoken.h
@@ -1,25 +1,25 @@
 /*
  * softoken.h - private data structures and prototypes for the softoken lib
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: softoken.h,v 1.28 2012/04/25 14:50:10 gerv%gerv.net Exp $ */
+/* $Id: softoken.h,v 1.29 2013/02/05 02:19:52 ryan.sleevi%gmail.com Exp $ */
 
 #ifndef _SOFTOKEN_H_
 #define _SOFTOKEN_H_
 
 #include "blapi.h"
 #include "lowkeyti.h"
 #include "softoknt.h"
 #include "secoidt.h"
 
-#include "pkcs11t.h"     /* CK_RV Required for sftk_fipsPowerUpSelfTest(). */
+#include "pkcs11t.h"
 
 SEC_BEGIN_PROTOS
 
 /*
 ** RSA encryption/decryption. When encrypting/decrypting the output
 ** buffer must be at least the size of the public key modulus.
 */
 
@@ -89,16 +89,30 @@ extern
 SECStatus RSA_EncryptBlock(NSSLOWKEYPublicKey *key, unsigned char *output,
 			   unsigned int *outputLen, unsigned int maxOutputLen,
 			   unsigned char *input, unsigned int inputLen);
 extern
 SECStatus RSA_DecryptBlock(NSSLOWKEYPrivateKey *key, unsigned char *output,
 			   unsigned int *outputLen, unsigned int maxOutputLen,
 			   unsigned char *input, unsigned int inputLen);
 
+extern
+SECStatus RSA_EncryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
+                          NSSLOWKEYPublicKey *key,
+                          unsigned char *output, unsigned int *outputLen,
+                          unsigned int maxOutputLen,
+                          const unsigned char *input, unsigned int inputLen);
+
+extern
+SECStatus RSA_DecryptOAEP(CK_RSA_PKCS_OAEP_PARAMS *oaepParams,
+                          NSSLOWKEYPrivateKey *key,
+                          unsigned char *output, unsigned int *outputLen,
+                          unsigned int maxOutputLen,
+                          const unsigned char *input, unsigned int inputLen);
+
 /*
  * added to make pkcs #11 happy
  *   RAW is RSA_X_509
  */
 extern
 SECStatus RSA_SignRaw( NSSLOWKEYPrivateKey *key, unsigned char *output,
 			 unsigned int *output_len, unsigned int maxOutputLen,
 			 unsigned char *input, unsigned int input_len);
--- a/security/nss/lib/softoken/softoknt.h
+++ b/security/nss/lib/softoken/softoknt.h
@@ -1,33 +1,30 @@
 /*
  * softoknt.h - public data structures for the software token library
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: softoknt.h,v 1.7 2012/04/25 14:50:10 gerv%gerv.net Exp $ */
+/* $Id: softoknt.h,v 1.8 2013/02/05 02:19:52 ryan.sleevi%gmail.com Exp $ */
 
 #ifndef _SOFTOKNT_H_
 #define _SOFTOKNT_H_
 
 /*
  * RSA block types
  *
  * The actual values are important -- they are fixed, *not* arbitrary.
  * The explicit value assignments are not needed (because C would give
  * us those same values anyway) but are included as a reminder...
  */
 typedef enum {
     RSA_BlockPrivate0 = 0,	/* unused, really */
     RSA_BlockPrivate = 1,	/* pad for a private-key operation */
     RSA_BlockPublic = 2,	/* pad for a public-key operation */
-    RSA_BlockOAEP = 3,		/* use OAEP padding */
-				/* XXX is this only for a public-key
-				   operation? If so, add "Public" */
     RSA_BlockRaw = 4,		/* simply justify the block appropriately */
     RSA_BlockTotal
 } RSA_BlockType;
 
 #define NSS_SOFTOKEN_DEFAULT_CHUNKSIZE   2048
 
 /*
  * FIPS 140-2 auditing
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -1,16 +1,16 @@
 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
 /*
  * SSL3 Protocol
  *
  * This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: ssl3con.c,v 1.197 2013/01/18 19:31:42 bsmith%mozilla.com Exp $ */
+/* $Id: ssl3con.c,v 1.201 2013/02/07 01:29:19 wtc%google.com Exp $ */
 
 /* TODO(ekr): Implement HelloVerifyRequest on server side. OK for now. */
 
 #include "cert.h"
 #include "ssl.h"
 #include "cryptohi.h"	/* for DSAU_ stuff */
 #include "keyhi.h"
 #include "secder.h"
@@ -1839,17 +1839,16 @@ static const unsigned char mac_pad_2 [60
     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
     0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c, 0x5c,
     0x5c, 0x5c, 0x5c, 0x5c
 };
 
 /* Called from: ssl3_SendRecord()
-**		ssl3_HandleRecord()
 ** Caller must already hold the SpecReadLock. (wish we could assert that!)
 */
 static SECStatus
 ssl3_ComputeRecordMAC(
     ssl3CipherSpec *   spec,
     PRBool             useServerMacKey,
     PRBool             isDTLS,
     SSL3ContentType    type,
@@ -2021,16 +2020,138 @@ ssl3_ComputeRecordMAC(
 
     if (rv != SECSuccess) {
     	rv = SECFailure;
 	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
     }
     return rv;
 }
 
+/* Called from: ssl3_HandleRecord()
+ * Caller must already hold the SpecReadLock. (wish we could assert that!)
+ *
+ * On entry:
+ *   originalLen >= inputLen >= MAC size
+*/
+static SECStatus
+ssl3_ComputeRecordMACConstantTime(
+    ssl3CipherSpec *   spec,
+    PRBool             useServerMacKey,
+    PRBool             isDTLS,
+    SSL3ContentType    type,
+    SSL3ProtocolVersion version,
+    SSL3SequenceNumber seq_num,
+    const SSL3Opaque * input,
+    int                inputLen,
+    int                originalLen,
+    unsigned char *    outbuf,
+    unsigned int *     outLen)
+{
+    CK_MECHANISM_TYPE            macType;
+    CK_NSS_MAC_CONSTANT_TIME_PARAMS params;
+    SECItem                      param, inputItem, outputItem;
+    SECStatus                    rv;
+    unsigned char                header[13];
+    PK11SymKey *                 key;
+    int                          recordLength;
+
+    PORT_Assert(inputLen >= spec->mac_size);
+    PORT_Assert(originalLen >= inputLen);
+
+    if (spec->bypassCiphers) {
+	/* This function doesn't support PKCS#11 bypass. We fallback on the
+	 * non-constant time version. */
+	goto fallback;
+    }
+
+    if (spec->mac_def->mac == mac_null) {
+	*outLen = 0;
+	return SECSuccess;
+    }
+
+    header[0] = (unsigned char)(seq_num.high >> 24);
+    header[1] = (unsigned char)(seq_num.high >> 16);
+    header[2] = (unsigned char)(seq_num.high >>  8);
+    header[3] = (unsigned char)(seq_num.high >>  0);
+    header[4] = (unsigned char)(seq_num.low  >> 24);
+    header[5] = (unsigned char)(seq_num.low  >> 16);
+    header[6] = (unsigned char)(seq_num.low  >>  8);
+    header[7] = (unsigned char)(seq_num.low  >>  0);
+    header[8] = type;
+
+    macType = CKM_NSS_HMAC_CONSTANT_TIME;
+    recordLength = inputLen - spec->mac_size;
+    if (spec->version <= SSL_LIBRARY_VERSION_3_0) {
+	macType = CKM_NSS_SSL3_MAC_CONSTANT_TIME;
+	header[9] = recordLength >> 8;
+	header[10] = recordLength;
+	params.ulHeaderLen = 11;
+    } else {
+	if (isDTLS) {
+	    SSL3ProtocolVersion dtls_version;
+
+	    dtls_version = dtls_TLSVersionToDTLSVersion(version);
+	    header[9] = dtls_version >> 8;
+	    header[10] = dtls_version;
+	} else {
+	    header[9] = version >> 8;
+	    header[10] = version;
+	}
+	header[11] = recordLength >> 8;
+	header[12] = recordLength;
+	params.ulHeaderLen = 13;
+    }
+
+    params.macAlg = spec->mac_def->mmech;
+    params.ulBodyTotalLen = originalLen;
+    params.pHeader = header;
+
+    param.data = (unsigned char*) &params;
+    param.len = sizeof(params);
+    param.type = 0;
+
+    inputItem.data = (unsigned char *) input;
+    inputItem.len = inputLen;
+    inputItem.type = 0;
+
+    outputItem.data = outbuf;
+    outputItem.len = *outLen;
+    outputItem.type = 0;
+
+    key = spec->server.write_mac_key;
+    if (!useServerMacKey) {
+	key = spec->client.write_mac_key;
+    }
+
+    rv = PK11_SignWithSymKey(key, macType, &param, &outputItem, &inputItem);
+    if (rv != SECSuccess) {
+	if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) {
+	    goto fallback;
+	}
+
+	*outLen = 0;
+	rv = SECFailure;
+	ssl_MapLowLevelError(SSL_ERROR_MAC_COMPUTATION_FAILURE);
+	return rv;
+    }
+
+    PORT_Assert(outputItem.len == (unsigned)spec->mac_size);
+    *outLen = outputItem.len;
+
+    return rv;
+
+fallback:
+    /* ssl3_ComputeRecordMAC expects the MAC to have been removed from the
+     * length already. */
+    inputLen -= spec->mac_size;
+    return ssl3_ComputeRecordMAC(spec, useServerMacKey, isDTLS, type,
+				 version, seq_num, input, inputLen,
+				 outbuf, outLen);
+}
+
 static PRBool
 ssl3_ClientAuthTokenPresent(sslSessionID *sid) {
     PK11SlotInfo *slot = NULL;
     PRBool isPresent = PR_TRUE;
 
     /* we only care if we are doing client auth */
     if (!sid || !sid->u.ssl3.clAuthValid) {
 	return PR_TRUE;
@@ -9529,16 +9650,196 @@ ssl3_HandleHandshake(sslSocket *ss, sslB
 	}
     }	/* end loop */
 
     origBuf->len = 0;	/* So ssl3_GatherAppDataRecord will keep looping. */
     buf->buf = NULL;	/* not a leak. */
     return SECSuccess;
 }
 
+/* These macros return the given value with the MSB copied to all the other
+ * bits. They use the fact that arithmetic shift shifts-in the sign bit.
+ * However, this is not ensured by the C standard so you may need to replace
+ * them with something else for odd compilers. */
+#define DUPLICATE_MSB_TO_ALL(x) ( (unsigned)( (int)(x) >> (sizeof(int)*8-1) ) )
+#define DUPLICATE_MSB_TO_ALL_8(x) ((unsigned char)(DUPLICATE_MSB_TO_ALL(x)))
+
+/* SECStatusToMask returns, in constant time, a mask value of all ones if
+ * rv == SECSuccess.  Otherwise it returns zero. */
+static unsigned int
+SECStatusToMask(SECStatus rv)
+{
+    unsigned int good;
+    /* rv ^ SECSuccess is zero iff rv == SECSuccess. Subtracting one results
+     * in the MSB being set to one iff it was zero before. */
+    good = rv ^ SECSuccess;
+    good--;
+    return DUPLICATE_MSB_TO_ALL(good);
+}
+
+/* ssl_ConstantTimeGE returns 0xff if a>=b and 0x00 otherwise. */
+static unsigned char
+ssl_ConstantTimeGE(unsigned int a, unsigned int b)
+{
+    a -= b;
+    return DUPLICATE_MSB_TO_ALL(~a);
+}
+
+/* ssl_ConstantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */
+static unsigned char
+ssl_ConstantTimeEQ8(unsigned char a, unsigned char b)
+{
+    unsigned int c = a ^ b;
+    c--;
+    return DUPLICATE_MSB_TO_ALL_8(c);
+}
+
+static SECStatus
+ssl_RemoveSSLv3CBCPadding(sslBuffer *plaintext,
+			  unsigned int blockSize,
+			  unsigned int macSize)
+{
+    unsigned int paddingLength, good, t;
+    const unsigned int overhead = 1 /* padding length byte */ + macSize;
+
+    /* These lengths are all public so we can test them in non-constant
+     * time. */
+    if (overhead > plaintext->len) {
+	return SECFailure;
+    }
+
+    paddingLength = plaintext->buf[plaintext->len-1];
+    /* SSLv3 padding bytes are random and cannot be checked. */
+    t = plaintext->len;
+    t -= paddingLength+overhead;
+    /* If len >= padding_length+overhead then the MSB of t is zero. */
+    good = DUPLICATE_MSB_TO_ALL(~t);
+    /* SSLv3 requires that the padding is minimal. */
+    t = blockSize - (paddingLength+1);
+    good &= DUPLICATE_MSB_TO_ALL(~t);
+    plaintext->len -= good & (paddingLength+1);
+    return (good & SECSuccess) | (~good & SECFailure);
+}
+
+static SECStatus
+ssl_RemoveTLSCBCPadding(sslBuffer *plaintext, unsigned int macSize)
+{
+    unsigned int paddingLength, good, t, toCheck, i;
+    const unsigned int overhead = 1 /* padding length byte */ + macSize;
+
+    /* These lengths are all public so we can test them in non-constant
+     * time. */
+    if (overhead > plaintext->len) {
+	return SECFailure;
+    }
+
+    paddingLength = plaintext->buf[plaintext->len-1];
+    t = plaintext->len;
+    t -= paddingLength+overhead;
+    /* If len >= paddingLength+overhead then the MSB of t is zero. */
+    good = DUPLICATE_MSB_TO_ALL(~t);
+
+    /* The padding consists of a length byte at the end of the record and then
+     * that many bytes of padding, all with the same value as the length byte.
+     * Thus, with the length byte included, there are paddingLength+1 bytes of
+     * padding.
+     *
+     * We can't check just |paddingLength+1| bytes because that leaks
+     * decrypted information. Therefore we always have to check the maximum
+     * amount of padding possible. (Again, the length of the record is
+     * public information so we can use it.) */
+    toCheck = 255; /* maximum amount of padding. */
+    if (toCheck > plaintext->len-1) {
+	toCheck = plaintext->len-1;
+    }
+
+    for (i = 0; i < toCheck; i++) {
+	unsigned int t = paddingLength - i;
+	/* If i <= paddingLength then the MSB of t is zero and mask is
+	 * 0xff.  Otherwise, mask is 0. */
+	unsigned char mask = DUPLICATE_MSB_TO_ALL(~t);
+	unsigned char b = plaintext->buf[plaintext->len-1-i];
+	/* The final |paddingLength+1| bytes should all have the value
+	 * |paddingLength|. Therefore the XOR should be zero. */
+	good &= ~(mask&(paddingLength ^ b));
+    }
+
+    /* If any of the final |paddingLength+1| bytes had the wrong value,
+     * one or more of the lower eight bits of |good| will be cleared. We
+     * AND the bottom 8 bits together and duplicate the result to all the
+     * bits. */
+    good &= good >> 4;
+    good &= good >> 2;
+    good &= good >> 1;
+    good <<= sizeof(good)*8-1;
+    good = DUPLICATE_MSB_TO_ALL(good);
+
+    plaintext->len -= good & (paddingLength+1);
+    return (good & SECSuccess) | (~good & SECFailure);
+}
+
+/* On entry:
+ *   originalLength >= macSize
+ *   macSize <= MAX_MAC_LENGTH
+ *   plaintext->len >= macSize
+ */
+static void
+ssl_CBCExtractMAC(sslBuffer *plaintext,
+		  unsigned int originalLength,
+		  SSL3Opaque* out,
+		  unsigned int macSize)
+{
+    unsigned char rotatedMac[MAX_MAC_LENGTH];
+    /* macEnd is the index of |plaintext->buf| just after the end of the
+     * MAC. */
+    unsigned macEnd = plaintext->len;
+    unsigned macStart = macEnd - macSize;
+    /* scanStart contains the number of bytes that we can ignore because
+     * the MAC's position can only vary by 255 bytes. */
+    unsigned scanStart = 0;
+    unsigned i, j, divSpoiler;
+    unsigned char rotateOffset;
+
+    if (originalLength > macSize + 255 + 1)
+	scanStart = originalLength - (macSize + 255 + 1);
+
+    /* divSpoiler contains a multiple of macSize that is used to cause the
+     * modulo operation to be constant time. Without this, the time varies
+     * based on the amount of padding when running on Intel chips at least.
+     *
+     * The aim of right-shifting macSize is so that the compiler doesn't
+     * figure out that it can remove divSpoiler as that would require it
+     * to prove that macSize is always even, which I hope is beyond it. */
+    divSpoiler = macSize >> 1;
+    divSpoiler <<= (sizeof(divSpoiler)-1)*8;
+    rotateOffset = (divSpoiler + macStart - scanStart) % macSize;
+
+    memset(rotatedMac, 0, macSize);
+    for (i = scanStart; i < originalLength;) {
+	for (j = 0; j < macSize && i < originalLength; i++, j++) {
+	    unsigned char macStarted = ssl_ConstantTimeGE(i, macStart);
+	    unsigned char macEnded = ssl_ConstantTimeGE(i, macEnd);
+	    unsigned char b = 0;
+	    b = plaintext->buf[i];
+	    rotatedMac[j] |= b & macStarted & ~macEnded;
+	}
+    }
+
+    /* Now rotate the MAC. If we knew that the MAC fit into a CPU cache line
+     * we could line-align |rotatedMac| and rotate in place. */
+    memset(out, 0, macSize);
+    for (i = 0; i < macSize; i++) {
+	unsigned char offset =
+	    (divSpoiler + macSize - rotateOffset + i) % macSize;
+	for (j = 0; j < macSize; j++) {
+	    out[j] |= rotatedMac[i] & ssl_ConstantTimeEQ8(j, offset);
+	}
+    }
+}
+
 /* if cText is non-null, then decipher, check MAC, and decompress the
  * SSL record from cText->buf (typically gs->inbuf)
  * into databuf (typically gs->buf), and any previous contents of databuf
  * is lost.  Then handle databuf according to its SSL record type,
  * unless it's an application record.
  *
  * If cText is NULL, then the ciphertext has previously been deciphered and
  * checked, and is already sitting in databuf.  It is processed as an SSL
@@ -9558,25 +9859,28 @@ ssl3_HandleHandshake(sslSocket *ss, sslB
  */
 SECStatus
 ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
 {
     const ssl3BulkCipherDef *cipher_def;
     ssl3CipherSpec *     crSpec;
     SECStatus            rv;
     unsigned int         hashBytes = MAX_MAC_LENGTH + 1;
-    unsigned int         padding_length;
     PRBool               isTLS;
-    PRBool               padIsBad = PR_FALSE;
     SSL3ContentType      rType;
     SSL3Opaque           hash[MAX_MAC_LENGTH];
+    SSL3Opaque           givenHashBuf[MAX_MAC_LENGTH];
+    SSL3Opaque          *givenHash;
     sslBuffer           *plaintext;
     sslBuffer            temp_buf;
     PRUint64             dtls_seq_num;
     unsigned int         ivLen = 0;
+    unsigned int         originalLen = 0;
+    unsigned int         good;
+    unsigned int         minLength;
 
     PORT_Assert( ss->opt.noLocks || ssl_HaveRecvBufLock(ss) );
 
     if (!ss->ssl3.initialized) {
 	ssl_GetSSL3HandshakeLock(ss);
 	rv = ssl3_InitState(ss);
 	ssl_ReleaseSSL3HandshakeLock(ss);
 	if (rv != SECSuccess) {
@@ -9634,16 +9938,40 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip
 	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, rejecting "
 		     "potentially replayed packet", SSL_GETPID(), ss->fd));
 	    /* Silently drop the packet */
             databuf->len = 0; /* Needed to ensure data not left around */
 	    return SECSuccess;
 	}
     }
 
+    good = (unsigned)-1;
+    minLength = crSpec->mac_size;
+    if (cipher_def->type == type_block) {
+	/* CBC records have a padding length byte at the end. */
+	minLength++;
+	if (crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
+	    /* With >= TLS 1.1, CBC records have an explicit IV. */
+	    minLength += cipher_def->iv_size;
+	}
+    }
+
+    /* We can perform this test in variable time because the record's total
+     * length and the ciphersuite are both public knowledge. */
+    if (cText->buf->len < minLength) {
+	SSL_DBG(("%d: SSL3[%d]: HandleRecord, record too small.",
+		 SSL_GETPID(), ss->fd));
+	/* must not hold spec lock when calling SSL3_SendAlert. */
+	ssl_ReleaseSpecReadLock(ss);
+	SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
+	/* always log mac error, in case attacker can read server logs. */
+	PORT_SetError(SSL_ERROR_BAD_MAC_READ);
+	return SECFailure;
+    }
+
     if (cipher_def->type == type_block &&
 	crSpec->version >= SSL_LIBRARY_VERSION_TLS_1_1) {
 	/* Consume the per-record explicit IV. RFC 4346 Section 6.2.3.2 states
 	 * "The receiver decrypts the entire GenericBlockCipher structure and
 	 * then discards the first cipher block corresponding to the IV
 	 * component." Instead, we decrypt the first cipher block and then
 	 * discard it before decrypting the rest.
 	 */
@@ -9651,42 +9979,27 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip
 	int decoded;
 
 	ivLen = cipher_def->iv_size;
 	if (ivLen < 8 || ivLen > sizeof(iv)) {
 	    ssl_ReleaseSpecReadLock(ss);
 	    PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
 	    return SECFailure;
 	}
-	if (ivLen > cText->buf->len) {
-	    SSL_DBG(("%d: SSL3[%d]: HandleRecord, IV length check failed",
-		     SSL_GETPID(), ss->fd));
-	    /* must not hold spec lock when calling SSL3_SendAlert. */
-	    ssl_ReleaseSpecReadLock(ss);
-	    SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
-	    /* always log mac error, in case attacker can read server logs. */
-	    PORT_SetError(SSL_ERROR_BAD_MAC_READ);
-	    return SECFailure;
-	}
 
 	PRINT_BUF(80, (ss, "IV (ciphertext):", cText->buf->buf, ivLen));
 
 	/* The decryption result is garbage, but since we just throw away
 	 * the block it doesn't matter.  The decryption of the next block
 	 * depends only on the ciphertext of the IV block.
 	 */
 	rv = crSpec->decode(crSpec->decodeContext, iv, &decoded,
 			    sizeof(iv), cText->buf->buf, ivLen);
 
-	if (rv != SECSuccess) {
-	    /* All decryption failures must be treated like a bad record
-	     * MAC; see RFC 5246 (TLS 1.2). 
-	     */
-	    padIsBad = PR_TRUE;
-	}
+	good &= SECStatusToMask(rv);
     }
 
     /* If we will be decompressing the buffer we need to decrypt somewhere
      * other than into databuf */
     if (crSpec->decompressor) {
 	temp_buf.buf = NULL;
 	temp_buf.space = 0;
 	plaintext = &temp_buf;
@@ -9718,64 +10031,80 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Cip
 	PORT_SetError(SSL_ERROR_RX_RECORD_TOO_LONG);
 	return SECFailure;
     }
 
     /* decrypt from cText buf to plaintext. */
     rv = crSpec->decode(
 	crSpec->decodeContext, plaintext->buf, (int *)&plaintext->len,
 	plaintext->space, cText->buf->buf + ivLen, cText->buf->len - ivLen);
+    good &= SECStatusToMask(rv);
 
     PRINT_BUF(80, (ss, "cleartext:", plaintext->buf, plaintext->len));
-    if (rv != SECSuccess) {
-        /* All decryption failures must be treated like a bad record
-         * MAC; see RFC 5246 (TLS 1.2). 
-         */
-        padIsBad = PR_TRUE;
-    }
+
+    originalLen = plaintext->len;
 
     /* If it's a block cipher, check and strip the padding. */
-    if (cipher_def->type == type_block && !padIsBad) {
-        PRUint8 * pPaddingLen = plaintext->buf + plaintext->len - 1;
-	padding_length = *pPaddingLen;
-	/* TLS permits padding to exceed the block size, up to 255 bytes. */
-	if (padding_length + 1 + crSpec->mac_size > plaintext->len)
-	    padIsBad = PR_TRUE;
-	else {
-            plaintext->len -= padding_length + 1;
-            /* In TLS all padding bytes must be equal to the padding length. */
-            if (isTLS) {
-                PRUint8 *p;
-                for (p = pPaddingLen - padding_length; p < pPaddingLen; ++p) {
-                    padIsBad |= *p ^ padding_length;
-                }
-            }
-        }
-    }
-
-    /* Remove the MAC. */
-    if (plaintext->len >= crSpec->mac_size)
-	plaintext->len -= crSpec->mac_size;
-    else
-    	padIsBad = PR_TRUE;	/* really macIsBad */
+    if (cipher_def->type == type_block) {
+	const unsigned int blockSize = cipher_def->iv_size;
+	const unsigned int macSize = crSpec->mac_size;
+
+	if (crSpec->version <= SSL_LIBRARY_VERSION_3_0) {
+	    good &= SECStatusToMask(ssl_RemoveSSLv3CBCPadding(
+			plaintext, blockSize, macSize));
+	} else {
+	    good &= SECStatusToMask(ssl_RemoveTLSCBCPadding(
+			plaintext, macSize));
+	}
+    }
 
     /* compute the MAC */
     rType = cText->type;
-    rv = ssl3_ComputeRecordMAC( crSpec, (PRBool)(!ss->sec.isServer),
-        IS_DTLS(ss), rType, cText->version,
-        IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
-	plaintext->buf, plaintext->len, hash, &hashBytes);
-    if (rv != SECSuccess) {
-        padIsBad = PR_TRUE;     /* really macIsBad */
-    }
-
-    /* Check the MAC */
-    if (hashBytes != (unsigned)crSpec->mac_size || padIsBad || 
-	NSS_SecureMemcmp(plaintext->buf + plaintext->len, hash,
-	                 crSpec->mac_size) != 0) {
+    if (cipher_def->type == type_block) {
+	rv = ssl3_ComputeRecordMACConstantTime(
+	    crSpec, (PRBool)(!ss->sec.isServer),
+	    IS_DTLS(ss), rType, cText->version,
+	    IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+	    plaintext->buf, plaintext->len, originalLen,
+	    hash, &hashBytes);
+
+	ssl_CBCExtractMAC(plaintext, originalLen, givenHashBuf,
+			  crSpec->mac_size);
+	givenHash = givenHashBuf;
+
+	/* plaintext->len will always have enough space to remove the MAC
+	 * because in ssl_Remove{SSLv3|TLS}CBCPadding we only adjust
+	 * plaintext->len if the result has enough space for the MAC and we
+	 * tested the unadjusted size against minLength, above. */
+	plaintext->len -= crSpec->mac_size;
+    } else {
+	/* This is safe because we checked the minLength above. */
+	plaintext->len -= crSpec->mac_size;
+
+	rv = ssl3_ComputeRecordMAC(
+	    crSpec, (PRBool)(!ss->sec.isServer),
+	    IS_DTLS(ss), rType, cText->version,
+	    IS_DTLS(ss) ? cText->seq_num : crSpec->read_seq_num,
+	    plaintext->buf, plaintext->len,
+	    hash, &hashBytes);
+
+	/* We can read the MAC directly from the record because its location is
+	 * public when a stream cipher is used. */
+	givenHash = plaintext->buf + plaintext->len;
+    }
+
+    good &= SECStatusToMask(rv);
+
+    if (hashBytes != (unsigned)crSpec->mac_size ||
+	NSS_SecureMemcmp(givenHash, hash, crSpec->mac_size) != 0) {
+	/* We're allowed to leak whether or not the MAC check was correct */
+	good = 0;
+    }
+
+    if (good == 0) {
 	/* must not hold spec lock when calling SSL3_SendAlert. */
 	ssl_ReleaseSpecReadLock(ss);
 
 	SSL_DBG(("%d: SSL3[%d]: mac check failed", SSL_GETPID(), ss->fd));
 
 	if (!IS_DTLS(ss)) {
 	    SSL3_SendAlert(ss, alert_fatal, bad_record_mac);
 	    /* always log mac error, in case attacker can read server logs. */
--- a/security/nss/lib/util/hasht.h
+++ b/security/nss/lib/util/hasht.h
@@ -1,12 +1,12 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-/* $Id: hasht.h,v 1.10 2012/06/26 22:27:33 rrelyea%redhat.com Exp $ */
+/* $Id: hasht.h,v 1.11 2013/02/05 18:10:46 wtc%google.com Exp $ */
 
 #ifndef _HASHT_H_
 #define _HASHT_H_
 
 /* Opaque objects */
 typedef struct SECHashObjectStr SECHashObject;
 typedef struct HASHContextStr HASHContext;
 
@@ -46,16 +46,17 @@ struct SECHashObjectStr {
     void * (*create)(void);
     void * (*clone)(void *);
     void (*destroy)(void *, PRBool);
     void (*begin)(void *);
     void (*update)(void *, const unsigned char *, unsigned int);
     void (*end)(void *, unsigned char *, unsigned int *, unsigned int);
     unsigned int blocklength;  /* hash input block size (in bytes) */
     HASH_HashType type;
+    void (*end_raw)(void *, unsigned char *, unsigned int *, unsigned int);
 };
 
 struct HASHContextStr {
     const struct SECHashObjectStr *hashobj;
     void *hash_context;
 };
 
 #endif /* _HASHT_H_ */
--- a/security/nss/lib/util/nssutil.h
+++ b/security/nss/lib/util/nssutil.h
@@ -14,22 +14,22 @@
 
 /*
  * NSS utilities's major version, minor version, patch level, build number,
  * and whether this is a beta release.
  *
  * The format of the version string should be
  *     "<major version>.<minor version>[.<patch level>[.<build number>]][ <Beta>]"
  */
-#define NSSUTIL_VERSION  "3.14.2.0"
+#define NSSUTIL_VERSION  "3.14.3.0 Beta"
 #define NSSUTIL_VMAJOR   3
 #define NSSUTIL_VMINOR   14
-#define NSSUTIL_VPATCH   2
+#define NSSUTIL_VPATCH   3
 #define NSSUTIL_VBUILD   0
-#define NSSUTIL_BETA     PR_FALSE
+#define NSSUTIL_BETA     PR_TRUE
 
 SEC_BEGIN_PROTOS
 
 /*
  * Returns a const string of the UTIL library version.
  */
 extern const char *NSSUTIL_GetVersion(void);
 
--- a/security/nss/lib/util/pkcs11n.h
+++ b/security/nss/lib/util/pkcs11n.h
@@ -1,17 +1,17 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #ifndef _PKCS11N_H_
 #define _PKCS11N_H_
 
 #ifdef DEBUG
-static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.28 $ $Date: 2012/04/25 14:50:16 $";
+static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.31 $ $Date: 2013/02/07 01:29:19 $";
 #endif /* DEBUG */
 
 /*
  * pkcs11n.h
  *
  * This file contains the NSS-specific type definitions for Cryptoki
  * (PKCS#11).
  */
@@ -190,16 +190,19 @@ static const char CKT_CVS_ID[] = "@(#) $
  * You must apply a KDF (e.g. CKM_NSS_HKDF_*) to resultant keying material 
  * to get a key with uniformly distributed bits.
  */
 #define CKM_NSS_JPAKE_FINAL_SHA1    (CKM_NSS + 15)
 #define CKM_NSS_JPAKE_FINAL_SHA256  (CKM_NSS + 16)
 #define CKM_NSS_JPAKE_FINAL_SHA384  (CKM_NSS + 17)
 #define CKM_NSS_JPAKE_FINAL_SHA512  (CKM_NSS + 18)
 
+#define CKM_NSS_HMAC_CONSTANT_TIME      (CKM_NSS + 19)
+#define CKM_NSS_SSL3_MAC_CONSTANT_TIME  (CKM_NSS + 20)
+
 /*
  * HISTORICAL:
  * Do not attempt to use these. They are only used by NETSCAPE's internal
  * PKCS #11 interface. Most of these are place holders for other mechanism
  * and will change in the future.
  */
 #define CKM_NETSCAPE_PBE_SHA1_DES_CBC           0x80000002UL
 #define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC    0x80000003UL
@@ -235,16 +238,30 @@ typedef struct CK_NSS_JPAKERound2Params 
     CK_NSS_JPAKEPublicValue gx4; /* in */
     CK_NSS_JPAKEPublicValue A;   /* out */
 } CK_NSS_JPAKERound2Params;
 
 typedef struct CK_NSS_JPAKEFinalParams {
     CK_NSS_JPAKEPublicValue B; /* in */
 } CK_NSS_JPAKEFinalParams;
 
+/* NOTE: the softoken's implementation of CKM_NSS_HMAC_CONSTANT_TIME and
+ * CKM_NSS_SSL3_MAC_CONSTANT_TIME requires that the sum of ulBodyTotalLen
+ * and ulHeaderLen be much smaller than 2^32 / 8 bytes because it uses an
+ * unsigned int variable to represent the length in bits. This should not
+ * be a problem because the SSL/TLS protocol limits the size of an SSL
+ * record to something considerably less than 2^32 bytes.
+ */
+typedef struct CK_NSS_MAC_CONSTANT_TIME_PARAMS {
+    CK_MECHANISM_TYPE macAlg;   /* in */
+    CK_ULONG ulBodyTotalLen;    /* in */
+    CK_BYTE * pHeader;          /* in */
+    CK_ULONG ulHeaderLen;       /* in */
+} CK_NSS_MAC_CONSTANT_TIME_PARAMS;
+
 /*
  * NSS-defined return values
  *
  */
 #define CKR_NSS (CKM_VENDOR_DEFINED|NSSCK_VENDOR_NSS)
 
 #define CKR_NSS_CERTDB_FAILED      (CKR_NSS + 1)
 #define CKR_NSS_KEYDB_FAILED       (CKR_NSS + 2)
--- a/security/nss/tests/ssl/ssl.sh
+++ b/security/nss/tests/ssl/ssl.sh
@@ -294,17 +294,17 @@ ssl_cov()
           echo "$SCRIPTNAME: skipping  $testname for $NORM_EXT"
       elif [ "$ectype" = "ECC" -a -z "$NSS_ENABLE_ECC" ] ; then
           echo "$SCRIPTNAME: skipping  $testname (ECC only)"
       elif [ "$SERVER_MODE" = "fips" -o "$CLIENT_MODE" = "fips" ] && [ "$SSL2" -eq 0 -o "$EXP" -eq 0 ] ; then
           echo "$SCRIPTNAME: skipping  $testname (non-FIPS only)"
       elif [ "`echo $ectype | cut -b 1`" != "#" ] ; then
           echo "$SCRIPTNAME: running $testname ----------------------------"
           VMAX="ssl3"
-          if [ "$testmax" = "TLS" ]; then
+          if [ "$testmax" = "TLS10" ]; then
               VMAX="tls1.0"
           fi
           if [ "$testmax" = "TLS11" ]; then
               VMAX="tls1.1"
           fi
 
 # These five tests need an EC cert signed with RSA
 # This requires a different certificate loaded in selfserv