| diff -pu a/nss/lib/ssl/ssl3con.c b/nss/lib/ssl/ssl3con.c |
| --- a/nss/lib/ssl/ssl3con.c 2013-07-31 14:10:35.113325316 -0700 |
| +++ b/nss/lib/ssl/ssl3con.c 2013-07-31 14:12:00.254575103 -0700 |
| @@ -2157,6 +2157,20 @@ ssl3_ComputeRecordMAC( |
| return rv; |
| } |
| |
| +/* This is a bodge to allow this code to be compiled against older NSS headers |
| + * that don't contain the CBC constant-time changes. */ |
| +#ifndef CKM_NSS_HMAC_CONSTANT_TIME |
| +#define CKM_NSS_HMAC_CONSTANT_TIME (CKM_NSS + 19) |
| +#define CKM_NSS_SSL3_MAC_CONSTANT_TIME (CKM_NSS + 20) |
| + |
| +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; |
| +#endif |
| + |
| /* Called from: ssl3_HandleRecord() |
| * Caller must already hold the SpecReadLock. (wish we could assert that!) |
| * |
| @@ -2179,7 +2193,8 @@ ssl3_ComputeRecordMACConstantTime( |
| { |
| CK_MECHANISM_TYPE macType; |
| CK_NSS_MAC_CONSTANT_TIME_PARAMS params; |
| - SECItem param, inputItem, outputItem; |
| + PK11Context * mac_context; |
| + SECItem param; |
| SECStatus rv; |
| unsigned char header[13]; |
| PK11SymKey * key; |
| @@ -2240,34 +2255,27 @@ ssl3_ComputeRecordMACConstantTime( |
| 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; |
| } |
| + mac_context = PK11_CreateContextBySymKey(macType, CKA_SIGN, key, ¶m); |
| + if (mac_context == NULL) { |
| + /* Older versions of NSS may not support constant-time MAC. */ |
| + goto fallback; |
| + } |
| |
| - rv = PK11_SignWithSymKey(key, macType, ¶m, &outputItem, &inputItem); |
| - if (rv != SECSuccess) { |
| - if (PORT_GetError() == SEC_ERROR_INVALID_ALGORITHM) { |
| - goto fallback; |
| - } |
| + rv = PK11_DigestBegin(mac_context); |
| + rv |= PK11_DigestOp(mac_context, input, inputLen); |
| + rv |= PK11_DigestFinal(mac_context, outbuf, outLen, spec->mac_size); |
| + PK11_DestroyContext(mac_context, PR_TRUE); |
| |
| - *outLen = 0; |
| + PORT_Assert(rv != SECSuccess || *outLen == (unsigned)spec->mac_size); |
| + |
| + if (rv != SECSuccess) { |
| 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: |