mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-10-08 19:04:45 +00:00
Bug 839141 - Upgrade Mozilla to NSS 3.14.3, starting with Beta1, r=ekr
This commit is contained in:
parent
c4c4dbc220
commit
0ec2973ab8
@ -1 +1 @@
|
||||
NSS_3_14_2_RTM
|
||||
NSS_3_14_3_BETA1
|
||||
|
@ -1 +1 @@
|
||||
NSS_3_14_2_RTM
|
||||
NSS_3_14_3_BETA1
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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_
|
||||
@ -874,6 +874,18 @@ extern void MD5_Update(MD5Context *cx,
|
||||
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
|
||||
@ -1030,6 +1042,18 @@ extern void SHA1_Update(SHA1Context *cx, const unsigned char *input,
|
||||
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.
|
||||
*/
|
||||
@ -1068,6 +1092,8 @@ 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);
|
||||
@ -1086,6 +1112,8 @@ 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);
|
||||
@ -1102,6 +1130,8 @@ 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,
|
||||
@ -1122,6 +1152,8 @@ 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);
|
||||
|
@ -285,11 +285,10 @@ ec_GFp_validate_point(const mp_int *px, const mp_int *py, const ECGroup *group)
|
||||
}
|
||||
/* 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) );
|
||||
|
336
security/nss/lib/freebl/hmacct.c
Normal file
336
security/nss/lib/freebl/hmacct.c
Normal file
@ -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 */);
|
||||
}
|
||||
|
38
security/nss/lib/freebl/hmacct.h
Normal file
38
security/nss/lib/freebl/hmacct.h
Normal file
@ -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
|
@ -4,7 +4,7 @@
|
||||
* 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);
|
||||
@ -12,6 +12,7 @@ extern int FREEBL_InitStubs(void);
|
||||
|
||||
#include "loader.h"
|
||||
#include "alghmac.h"
|
||||
#include "hmacct.h"
|
||||
|
||||
|
||||
static const struct FREEBLVectorStr vector =
|
||||
@ -258,9 +259,14 @@ static const struct FREEBLVectorStr vector =
|
||||
/* 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 *
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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"
|
||||
@ -1858,3 +1858,51 @@ PRNGTEST_RunHealthTests(void)
|
||||
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);
|
||||
}
|
||||
|
@ -4,14 +4,14 @@
|
||||
* 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 {
|
||||
|
||||
@ -569,7 +569,35 @@ struct FREEBLVectorStr {
|
||||
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;
|
||||
|
||||
|
@ -56,6 +56,7 @@ EXPORTS = \
|
||||
PRIVATE_EXPORTS = \
|
||||
alghmac.h \
|
||||
blapi.h \
|
||||
hmacct.h \
|
||||
secmpi.h \
|
||||
secrng.h \
|
||||
ec.h \
|
||||
@ -102,6 +103,7 @@ CSRCS = \
|
||||
cts.c \
|
||||
ctr.c \
|
||||
gcm.c \
|
||||
hmacct.c \
|
||||
rijndael.c \
|
||||
aeskeywrap.c \
|
||||
camellia.c \
|
||||
|
@ -523,7 +523,8 @@ MD5_End(MD5Context *cx, unsigned char *digest,
|
||||
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]);
|
||||
@ -533,6 +534,32 @@ MD5_End(MD5Context *cx, unsigned char *digest,
|
||||
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)
|
||||
{
|
||||
|
@ -58,7 +58,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -68,7 +70,8 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -78,7 +81,8 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -88,7 +92,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -99,7 +105,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -110,7 +118,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -121,7 +131,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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,
|
||||
@ -132,7 +144,9 @@ const SECHashObject SECRawHashObjects[] = {
|
||||
(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
|
||||
},
|
||||
};
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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"
|
||||
@ -462,6 +462,35 @@ SHA256_End(SHA256Context *ctx, unsigned char *digest,
|
||||
*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)
|
||||
@ -556,6 +585,14 @@ SHA224_End(SHA256Context *ctx, unsigned char *digest,
|
||||
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)
|
||||
@ -1228,6 +1265,36 @@ SHA512_End(SHA512Context *ctx, unsigned char *digest,
|
||||
*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)
|
||||
@ -1336,6 +1403,14 @@ SHA384_End(SHA384Context *ctx, unsigned char *digest,
|
||||
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)
|
||||
|
@ -148,6 +148,7 @@ SHA1_End(SHA1Context *ctx, unsigned char *hashout,
|
||||
{
|
||||
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,
|
||||
@ -174,12 +175,28 @@ SHA1_End(SHA1Context *ctx, unsigned char *hashout,
|
||||
* 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.
|
||||
*
|
||||
|
@ -147,12 +147,12 @@ static __inline__ PRUint32 swap4b(PRUint32 value)
|
||||
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
|
||||
|
@ -1021,3 +1021,9 @@ CERT_CreateOCSPSingleResponseRevoked;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSS_3.14.3 { # NSS 3.14.3 release
|
||||
;+ global:
|
||||
PK11_SignWithSymKey;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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_
|
||||
@ -34,12 +34,12 @@
|
||||
* 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
|
||||
|
||||
|
@ -777,6 +777,51 @@ PK11_Sign(SECKEYPrivateKey *key, SECItem *sig, const SECItem *hash)
|
||||
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
|
||||
|
@ -660,6 +660,8 @@ 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,
|
||||
|
@ -1281,8 +1281,7 @@ 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;
|
||||
@ -1300,8 +1299,7 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
||||
SECItem *content_type;
|
||||
PK11SymKey *sigkey;
|
||||
SECItem *encoded_stime;
|
||||
PRTime stime;
|
||||
PRTime verificationTime;
|
||||
int64 stime;
|
||||
SECStatus rv;
|
||||
|
||||
/*
|
||||
@ -1438,10 +1436,8 @@ sec_pkcs7_verify_signature(SEC_PKCS7ContentInfo *cinfo,
|
||||
* 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)
|
||||
{
|
||||
/*
|
||||
@ -1761,7 +1757,7 @@ SEC_PKCS7VerifySignature(SEC_PKCS7ContentInfo *cinfo,
|
||||
PRBool keepcerts)
|
||||
{
|
||||
return sec_pkcs7_verify_signature (cinfo, certusage,
|
||||
NULL, HASH_AlgNULL, keepcerts, 0);
|
||||
NULL, HASH_AlgNULL, keepcerts);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -1783,34 +1779,9 @@ SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
|
||||
{
|
||||
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
|
||||
@ -1873,7 +1844,7 @@ sec_pkcs7_get_signer_cert_info(SEC_PKCS7ContentInfo *cinfo, int selector)
|
||||
* 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;
|
||||
|
@ -133,23 +133,6 @@ extern PRBool SEC_PKCS7VerifyDetachedSignature(SEC_PKCS7ContentInfo *cinfo,
|
||||
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
|
||||
|
@ -267,9 +267,3 @@ NSSSMIME_GetVersion;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
;+NSS_3.14.3 { # NSS 3.14.3 release
|
||||
;+ global:
|
||||
SEC_PKCS7VerifyDetachedSignatureAtTime;
|
||||
;+ local:
|
||||
;+ *;
|
||||
;+};
|
||||
|
@ -47,6 +47,7 @@ CSRCS = \
|
||||
rsawrapr.c \
|
||||
sdb.c \
|
||||
sftkdb.c \
|
||||
sftkhmac.c \
|
||||
sftkpars.c \
|
||||
sftkpwd.c \
|
||||
softkver.c \
|
||||
|
@ -488,7 +488,10 @@ static const struct mechanismList mechanisms[] = {
|
||||
{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]);
|
||||
|
||||
|
@ -457,6 +457,24 @@ sftk_aes_mode(CK_MECHANISM_TYPE mechanism)
|
||||
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.
|
||||
@ -513,6 +531,7 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
||||
if (isEncrypt) {
|
||||
NSSLOWKEYPublicKey *pubKey = sftk_GetPubKey(key,CKK_RSA,&crv);
|
||||
if (pubKey == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
break;
|
||||
}
|
||||
context->maxLen = nsslowkey_PublicModulusLen(pubKey);
|
||||
@ -523,6 +542,7 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
||||
} else {
|
||||
NSSLOWKEYPrivateKey *privKey = sftk_GetPrivKey(key,CKK_RSA,&crv);
|
||||
if (privKey == NULL) {
|
||||
crv = CKR_KEY_HANDLE_INVALID;
|
||||
break;
|
||||
}
|
||||
context->maxLen = nsslowkey_PrivateModulusLen(privKey);
|
||||
@ -533,6 +553,55 @@ sftk_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
|
||||
}
|
||||
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 */
|
||||
@ -1460,17 +1529,25 @@ 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;
|
||||
}
|
||||
|
||||
@ -1519,14 +1596,14 @@ sftk_doHMACInit(SFTKSessionContext *context,HASH_HashType hash,
|
||||
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);
|
||||
@ -2172,6 +2249,65 @@ finish_rsa:
|
||||
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;
|
||||
|
@ -101,6 +101,8 @@ 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;
|
||||
|
||||
@ -372,6 +374,19 @@ struct SFTKHashSignInfoStr {
|
||||
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;
|
||||
@ -693,6 +708,28 @@ 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)
|
||||
*/
|
||||
|
@ -5,7 +5,7 @@
|
||||
* 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"
|
||||
@ -19,137 +19,42 @@
|
||||
#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);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -265,97 +170,6 @@ rsa_FormatOneBlock(unsigned modulusLen, RSA_BlockType blockType,
|
||||
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);
|
||||
@ -403,26 +217,6 @@ rsa_FormatBlock(SECItem *result, unsigned modulusLen,
|
||||
|
||||
break;
|
||||
|
||||
case RSA_BlockOAEP:
|
||||
/*
|
||||
* 0x00 || BT || M1(Salt) || M2(Pad1||ActualData[||Pad2])
|
||||
*
|
||||
* The "2" below is the first octet + the second octet.
|
||||
* (The other fields do not contain the clear values, but are
|
||||
* the same length as the clear values.)
|
||||
*/
|
||||
PORT_Assert (data->len <= (modulusLen - (2 + OAEP_SALT_LEN
|
||||
+ OAEP_PAD_LEN)));
|
||||
|
||||
result->data = rsa_FormatOneBlock(modulusLen, blockType, data);
|
||||
if (result->data == NULL) {
|
||||
result->len = 0;
|
||||
return SECFailure;
|
||||
}
|
||||
result->len = modulusLen;
|
||||
|
||||
break;
|
||||
|
||||
case RSA_BlockRaw:
|
||||
/*
|
||||
* Pad || ActualData
|
||||
@ -958,6 +752,266 @@ MGF1(HASH_HashType hashAlg, unsigned char *mask, unsigned int maskLen,
|
||||
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.
|
||||
@ -1008,7 +1062,7 @@ emsa_pss_encode(unsigned char *em, unsigned int emLen,
|
||||
(*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 */
|
||||
@ -1251,3 +1305,145 @@ 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;
|
||||
}
|
||||
|
@ -254,6 +254,11 @@ sdb_getFallbackTempDir(void)
|
||||
#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)
|
||||
{
|
||||
|
192
security/nss/lib/softoken/sftkhmac.c
Normal file
192
security/nss/lib/softoken/sftkhmac.c
Normal file
@ -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);
|
||||
}
|
@ -25,11 +25,11 @@
|
||||
* 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_ */
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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_
|
||||
@ -14,7 +14,7 @@
|
||||
#include "softoknt.h"
|
||||
#include "secoidt.h"
|
||||
|
||||
#include "pkcs11t.h" /* CK_RV Required for sftk_fipsPowerUpSelfTest(). */
|
||||
#include "pkcs11t.h"
|
||||
|
||||
SEC_BEGIN_PROTOS
|
||||
|
||||
@ -94,6 +94,20 @@ 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
|
||||
|
@ -4,7 +4,7 @@
|
||||
* 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_
|
||||
@ -20,9 +20,6 @@ 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;
|
||||
|
@ -5,7 +5,7 @@
|
||||
* 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. */
|
||||
|
||||
@ -1844,7 +1844,6 @@ static const unsigned char mac_pad_2 [60] = {
|
||||
};
|
||||
|
||||
/* Called from: ssl3_SendRecord()
|
||||
** ssl3_HandleRecord()
|
||||
** Caller must already hold the SpecReadLock. (wish we could assert that!)
|
||||
*/
|
||||
static SECStatus
|
||||
@ -2026,6 +2025,128 @@ ssl3_ComputeRecordMAC(
|
||||
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*) ¶ms;
|
||||
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, ¶m, &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;
|
||||
@ -9534,6 +9655,186 @@ ssl3_HandleHandshake(sslSocket *ss, sslBuffer *origBuf)
|
||||
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
|
||||
@ -9563,15 +9864,18 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
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) );
|
||||
|
||||
@ -9639,6 +9943,30 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
@ -9656,16 +9984,6 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
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));
|
||||
|
||||
@ -9676,12 +9994,7 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
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
|
||||
@ -9723,54 +10036,70 @@ ssl3_HandleRecord(sslSocket *ss, SSL3Ciphertext *cText, sslBuffer *databuf)
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cipher_def->type == type_block) {
|
||||
const unsigned int blockSize = cipher_def->iv_size;
|
||||
const unsigned int macSize = crSpec->mac_size;
|
||||
|
||||
/* Remove the MAC. */
|
||||
if (plaintext->len >= crSpec->mac_size)
|
||||
plaintext->len -= crSpec->mac_size;
|
||||
else
|
||||
padIsBad = PR_TRUE; /* really macIsBad */
|
||||
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 */
|
||||
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;
|
||||
}
|
||||
|
||||
/* Check the MAC */
|
||||
if (hashBytes != (unsigned)crSpec->mac_size || padIsBad ||
|
||||
NSS_SecureMemcmp(plaintext->buf + plaintext->len, hash,
|
||||
crSpec->mac_size) != 0) {
|
||||
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);
|
||||
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* 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_
|
||||
@ -51,6 +51,7 @@ struct SECHashObjectStr {
|
||||
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 {
|
||||
|
@ -19,12 +19,12 @@
|
||||
* 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
|
||||
|
||||
|
@ -6,7 +6,7 @@
|
||||
#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 */
|
||||
|
||||
/*
|
||||
@ -195,6 +195,9 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile: pkcs11n.h,v $ $Revision: 1.28 $
|
||||
#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
|
||||
@ -240,6 +243,20 @@ 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
|
||||
*
|
||||
|
@ -299,7 +299,7 @@ ssl_cov()
|
||||
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
|
||||
|
Loading…
Reference in New Issue
Block a user