Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1777)

Unified Diff: nss/lib/freebl/hmacct.c

Issue 2078763002: Delete bundled copy of NSS and replace with README. (Closed) Base URL: https://chromium.googlesource.com/chromium/deps/nss@master
Patch Set: Delete bundled copy of NSS and replace with README. Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « nss/lib/freebl/hmacct.h ('k') | nss/lib/freebl/intel-aes.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: nss/lib/freebl/hmacct.c
diff --git a/nss/lib/freebl/hmacct.c b/nss/lib/freebl/hmacct.c
deleted file mode 100644
index 0c3ba41dec1064a87a2a056c4bdf4ca7109b1ffe..0000000000000000000000000000000000000000
--- a/nss/lib/freebl/hmacct.c
+++ /dev/null
@@ -1,336 +0,0 @@
-/* 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 */);
-}
-
« no previous file with comments | « nss/lib/freebl/hmacct.h ('k') | nss/lib/freebl/intel-aes.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698