Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | |
michael@0 | 5 | #ifdef FREEBL_NO_DEPEND |
michael@0 | 6 | #include "stubs.h" |
michael@0 | 7 | #endif |
michael@0 | 8 | |
michael@0 | 9 | #include "secport.h" |
michael@0 | 10 | #include "hasht.h" |
michael@0 | 11 | #include "blapit.h" |
michael@0 | 12 | #include "hmacct.h" |
michael@0 | 13 | #include "secerr.h" |
michael@0 | 14 | |
michael@0 | 15 | /* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length |
michael@0 | 16 | * field. (SHA-384/512 have 128-bit length.) */ |
michael@0 | 17 | #define MAX_HASH_BIT_COUNT_BYTES 16 |
michael@0 | 18 | |
michael@0 | 19 | /* Some utility functions are needed: |
michael@0 | 20 | * |
michael@0 | 21 | * These macros return the given value with the MSB copied to all the other |
michael@0 | 22 | * bits. They use the fact that an arithmetic shift shifts-in the sign bit. |
michael@0 | 23 | * However, this is not ensured by the C standard so you may need to replace |
michael@0 | 24 | * them with something else on odd CPUs. |
michael@0 | 25 | * |
michael@0 | 26 | * Note: the argument to these macros must be an unsigned int. |
michael@0 | 27 | * */ |
michael@0 | 28 | #define DUPLICATE_MSB_TO_ALL(x) ( (unsigned int)( (int)(x) >> (sizeof(int)*8-1) ) ) |
michael@0 | 29 | #define DUPLICATE_MSB_TO_ALL_8(x) ( (unsigned char)(DUPLICATE_MSB_TO_ALL(x)) ) |
michael@0 | 30 | |
michael@0 | 31 | /* constantTimeGE returns 0xff if a>=b and 0x00 otherwise, where a, b < |
michael@0 | 32 | * MAX_UINT/2. */ |
michael@0 | 33 | static unsigned char |
michael@0 | 34 | constantTimeGE(unsigned int a, unsigned int b) |
michael@0 | 35 | { |
michael@0 | 36 | a -= b; |
michael@0 | 37 | return DUPLICATE_MSB_TO_ALL(~a); |
michael@0 | 38 | } |
michael@0 | 39 | |
michael@0 | 40 | /* constantTimeEQ8 returns 0xff if a==b and 0x00 otherwise. */ |
michael@0 | 41 | static unsigned char |
michael@0 | 42 | constantTimeEQ8(unsigned char a, unsigned char b) |
michael@0 | 43 | { |
michael@0 | 44 | unsigned int c = a ^ b; |
michael@0 | 45 | c--; |
michael@0 | 46 | return DUPLICATE_MSB_TO_ALL_8(c); |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | /* MAC performs a constant time SSLv3/TLS MAC of |dataLen| bytes of |data|, |
michael@0 | 50 | * where |dataLen| includes both the authenticated bytes and the MAC tag from |
michael@0 | 51 | * the sender. |dataLen| must be >= the length of the MAC tag. |
michael@0 | 52 | * |
michael@0 | 53 | * |dataTotalLen| is >= |dataLen| and also accounts for any padding bytes |
michael@0 | 54 | * that may follow the sender's MAC. (Only a single block of padding may |
michael@0 | 55 | * follow in SSLv3, or up to 255 bytes in TLS.) |
michael@0 | 56 | * |
michael@0 | 57 | * Since the results of decryption are secret information (otherwise a |
michael@0 | 58 | * padding-oracle is created), this function is constant-time with respect to |
michael@0 | 59 | * |dataLen|. |
michael@0 | 60 | * |
michael@0 | 61 | * |header| contains either the 13-byte TLS header (containing the sequence |
michael@0 | 62 | * number, record type etc), or it contains the SSLv3 header with the SSLv3 |
michael@0 | 63 | * padding bytes etc. */ |
michael@0 | 64 | static SECStatus |
michael@0 | 65 | MAC(unsigned char *mdOut, |
michael@0 | 66 | unsigned int *mdOutLen, |
michael@0 | 67 | unsigned int mdOutMax, |
michael@0 | 68 | const SECHashObject *hashObj, |
michael@0 | 69 | const unsigned char *macSecret, |
michael@0 | 70 | unsigned int macSecretLen, |
michael@0 | 71 | const unsigned char *header, |
michael@0 | 72 | unsigned int headerLen, |
michael@0 | 73 | const unsigned char *data, |
michael@0 | 74 | unsigned int dataLen, |
michael@0 | 75 | unsigned int dataTotalLen, |
michael@0 | 76 | unsigned char isSSLv3) |
michael@0 | 77 | { |
michael@0 | 78 | void *mdState = hashObj->create(); |
michael@0 | 79 | const unsigned int mdSize = hashObj->length; |
michael@0 | 80 | const unsigned int mdBlockSize = hashObj->blocklength; |
michael@0 | 81 | /* mdLengthSize is the number of bytes in the length field that terminates |
michael@0 | 82 | * the hash. |
michael@0 | 83 | * |
michael@0 | 84 | * This assumes that hash functions with a 64 byte block size use a 64-bit |
michael@0 | 85 | * length, and otherwise they use a 128-bit length. This is true of {MD5, |
michael@0 | 86 | * SHA*} (which are all of the hash functions specified for use with TLS |
michael@0 | 87 | * today). */ |
michael@0 | 88 | const unsigned int mdLengthSize = mdBlockSize == 64 ? 8 : 16; |
michael@0 | 89 | |
michael@0 | 90 | const unsigned int sslv3PadLen = hashObj->type == HASH_AlgMD5 ? 48 : 40; |
michael@0 | 91 | |
michael@0 | 92 | /* varianceBlocks is the number of blocks of the hash that we have to |
michael@0 | 93 | * calculate in constant time because they could be altered by the |
michael@0 | 94 | * padding value. |
michael@0 | 95 | * |
michael@0 | 96 | * In SSLv3, the padding must be minimal so the end of the plaintext |
michael@0 | 97 | * varies by, at most, 15+20 = 35 bytes. (We conservatively assume that |
michael@0 | 98 | * the MAC size varies from 0..20 bytes.) In case the 9 bytes of hash |
michael@0 | 99 | * termination (0x80 + 64-bit length) don't fit in the final block, we |
michael@0 | 100 | * say that the final two blocks can vary based on the padding. |
michael@0 | 101 | * |
michael@0 | 102 | * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not |
michael@0 | 103 | * required to be minimal. Therefore we say that the final six blocks |
michael@0 | 104 | * can vary based on the padding. |
michael@0 | 105 | * |
michael@0 | 106 | * Later in the function, if the message is short and there obviously |
michael@0 | 107 | * cannot be this many blocks then varianceBlocks can be reduced. */ |
michael@0 | 108 | unsigned int varianceBlocks = isSSLv3 ? 2 : 6; |
michael@0 | 109 | /* From now on we're dealing with the MAC, which conceptually has 13 |
michael@0 | 110 | * bytes of `header' before the start of the data (TLS) or 71/75 bytes |
michael@0 | 111 | * (SSLv3) */ |
michael@0 | 112 | const unsigned int len = dataTotalLen + headerLen; |
michael@0 | 113 | /* maxMACBytes contains the maximum bytes of bytes in the MAC, including |
michael@0 | 114 | * |header|, assuming that there's no padding. */ |
michael@0 | 115 | const unsigned int maxMACBytes = len - mdSize - 1; |
michael@0 | 116 | /* numBlocks is the maximum number of hash blocks. */ |
michael@0 | 117 | const unsigned int numBlocks = |
michael@0 | 118 | (maxMACBytes + 1 + mdLengthSize + mdBlockSize - 1) / mdBlockSize; |
michael@0 | 119 | /* macEndOffset is the index just past the end of the data to be |
michael@0 | 120 | * MACed. */ |
michael@0 | 121 | const unsigned int macEndOffset = dataLen + headerLen - mdSize; |
michael@0 | 122 | /* c is the index of the 0x80 byte in the final hash block that |
michael@0 | 123 | * contains application data. */ |
michael@0 | 124 | const unsigned int c = macEndOffset % mdBlockSize; |
michael@0 | 125 | /* indexA is the hash block number that contains the 0x80 terminating |
michael@0 | 126 | * value. */ |
michael@0 | 127 | const unsigned int indexA = macEndOffset / mdBlockSize; |
michael@0 | 128 | /* indexB is the hash block number that contains the 64-bit hash |
michael@0 | 129 | * length, in bits. */ |
michael@0 | 130 | const unsigned int indexB = (macEndOffset + mdLengthSize) / mdBlockSize; |
michael@0 | 131 | /* bits is the hash-length in bits. It includes the additional hash |
michael@0 | 132 | * block for the masked HMAC key, or whole of |header| in the case of |
michael@0 | 133 | * SSLv3. */ |
michael@0 | 134 | unsigned int bits; |
michael@0 | 135 | /* In order to calculate the MAC in constant time we have to handle |
michael@0 | 136 | * the final blocks specially because the padding value could cause the |
michael@0 | 137 | * end to appear somewhere in the final |varianceBlocks| blocks and we |
michael@0 | 138 | * can't leak where. However, |numStartingBlocks| worth of data can |
michael@0 | 139 | * be hashed right away because no padding value can affect whether |
michael@0 | 140 | * they are plaintext. */ |
michael@0 | 141 | unsigned int numStartingBlocks = 0; |
michael@0 | 142 | /* k is the starting byte offset into the conceptual header||data where |
michael@0 | 143 | * we start processing. */ |
michael@0 | 144 | unsigned int k = 0; |
michael@0 | 145 | unsigned char lengthBytes[MAX_HASH_BIT_COUNT_BYTES]; |
michael@0 | 146 | /* hmacPad is the masked HMAC key. */ |
michael@0 | 147 | unsigned char hmacPad[HASH_BLOCK_LENGTH_MAX]; |
michael@0 | 148 | unsigned char firstBlock[HASH_BLOCK_LENGTH_MAX]; |
michael@0 | 149 | unsigned char macOut[HASH_LENGTH_MAX]; |
michael@0 | 150 | unsigned i, j; |
michael@0 | 151 | |
michael@0 | 152 | /* For SSLv3, if we're going to have any starting blocks then we need |
michael@0 | 153 | * at least two because the header is larger than a single block. */ |
michael@0 | 154 | if (numBlocks > varianceBlocks + (isSSLv3 ? 1 : 0)) { |
michael@0 | 155 | numStartingBlocks = numBlocks - varianceBlocks; |
michael@0 | 156 | k = mdBlockSize*numStartingBlocks; |
michael@0 | 157 | } |
michael@0 | 158 | |
michael@0 | 159 | bits = 8*macEndOffset; |
michael@0 | 160 | hashObj->begin(mdState); |
michael@0 | 161 | if (!isSSLv3) { |
michael@0 | 162 | /* Compute the initial HMAC block. For SSLv3, the padding and |
michael@0 | 163 | * secret bytes are included in |header| because they take more |
michael@0 | 164 | * than a single block. */ |
michael@0 | 165 | bits += 8*mdBlockSize; |
michael@0 | 166 | memset(hmacPad, 0, mdBlockSize); |
michael@0 | 167 | PORT_Assert(macSecretLen <= sizeof(hmacPad)); |
michael@0 | 168 | memcpy(hmacPad, macSecret, macSecretLen); |
michael@0 | 169 | for (i = 0; i < mdBlockSize; i++) |
michael@0 | 170 | hmacPad[i] ^= 0x36; |
michael@0 | 171 | hashObj->update(mdState, hmacPad, mdBlockSize); |
michael@0 | 172 | } |
michael@0 | 173 | |
michael@0 | 174 | j = 0; |
michael@0 | 175 | memset(lengthBytes, 0, sizeof(lengthBytes)); |
michael@0 | 176 | if (mdLengthSize == 16) { |
michael@0 | 177 | j = 8; |
michael@0 | 178 | } |
michael@0 | 179 | if (hashObj->type == HASH_AlgMD5) { |
michael@0 | 180 | /* MD5 appends a little-endian length. */ |
michael@0 | 181 | for (i = 0; i < 4; i++) { |
michael@0 | 182 | lengthBytes[i+j] = bits >> (8*i); |
michael@0 | 183 | } |
michael@0 | 184 | } else { |
michael@0 | 185 | /* All other TLS hash functions use a big-endian length. */ |
michael@0 | 186 | for (i = 0; i < 4; i++) { |
michael@0 | 187 | lengthBytes[4+i+j] = bits >> (8*(3-i)); |
michael@0 | 188 | } |
michael@0 | 189 | } |
michael@0 | 190 | |
michael@0 | 191 | if (k > 0) { |
michael@0 | 192 | if (isSSLv3) { |
michael@0 | 193 | /* The SSLv3 header is larger than a single block. |
michael@0 | 194 | * overhang is the number of bytes beyond a single |
michael@0 | 195 | * block that the header consumes: either 7 bytes |
michael@0 | 196 | * (SHA1) or 11 bytes (MD5). */ |
michael@0 | 197 | const unsigned int overhang = headerLen-mdBlockSize; |
michael@0 | 198 | hashObj->update(mdState, header, mdBlockSize); |
michael@0 | 199 | memcpy(firstBlock, header + mdBlockSize, overhang); |
michael@0 | 200 | memcpy(firstBlock + overhang, data, mdBlockSize-overhang); |
michael@0 | 201 | hashObj->update(mdState, firstBlock, mdBlockSize); |
michael@0 | 202 | for (i = 1; i < k/mdBlockSize - 1; i++) { |
michael@0 | 203 | hashObj->update(mdState, data + mdBlockSize*i - overhang, |
michael@0 | 204 | mdBlockSize); |
michael@0 | 205 | } |
michael@0 | 206 | } else { |
michael@0 | 207 | /* k is a multiple of mdBlockSize. */ |
michael@0 | 208 | memcpy(firstBlock, header, 13); |
michael@0 | 209 | memcpy(firstBlock+13, data, mdBlockSize-13); |
michael@0 | 210 | hashObj->update(mdState, firstBlock, mdBlockSize); |
michael@0 | 211 | for (i = 1; i < k/mdBlockSize; i++) { |
michael@0 | 212 | hashObj->update(mdState, data + mdBlockSize*i - 13, |
michael@0 | 213 | mdBlockSize); |
michael@0 | 214 | } |
michael@0 | 215 | } |
michael@0 | 216 | } |
michael@0 | 217 | |
michael@0 | 218 | memset(macOut, 0, sizeof(macOut)); |
michael@0 | 219 | |
michael@0 | 220 | /* We now process the final hash blocks. For each block, we construct |
michael@0 | 221 | * it in constant time. If i == indexA then we'll include the 0x80 |
michael@0 | 222 | * bytes and zero pad etc. For each block we selectively copy it, in |
michael@0 | 223 | * constant time, to |macOut|. */ |
michael@0 | 224 | for (i = numStartingBlocks; i <= numStartingBlocks+varianceBlocks; i++) { |
michael@0 | 225 | unsigned char block[HASH_BLOCK_LENGTH_MAX]; |
michael@0 | 226 | unsigned char isBlockA = constantTimeEQ8(i, indexA); |
michael@0 | 227 | unsigned char isBlockB = constantTimeEQ8(i, indexB); |
michael@0 | 228 | for (j = 0; j < mdBlockSize; j++) { |
michael@0 | 229 | unsigned char isPastC = isBlockA & constantTimeGE(j, c); |
michael@0 | 230 | unsigned char isPastCPlus1 = isBlockA & constantTimeGE(j, c+1); |
michael@0 | 231 | unsigned char b = 0; |
michael@0 | 232 | if (k < headerLen) { |
michael@0 | 233 | b = header[k]; |
michael@0 | 234 | } else if (k < dataTotalLen + headerLen) { |
michael@0 | 235 | b = data[k-headerLen]; |
michael@0 | 236 | } |
michael@0 | 237 | k++; |
michael@0 | 238 | |
michael@0 | 239 | /* If this is the block containing the end of the |
michael@0 | 240 | * application data, and we are at the offset for the |
michael@0 | 241 | * 0x80 value, then overwrite b with 0x80. */ |
michael@0 | 242 | b = (b&~isPastC) | (0x80&isPastC); |
michael@0 | 243 | /* If this the the block containing the end of the |
michael@0 | 244 | * application data and we're past the 0x80 value then |
michael@0 | 245 | * just write zero. */ |
michael@0 | 246 | b = b&~isPastCPlus1; |
michael@0 | 247 | /* If this is indexB (the final block), but not |
michael@0 | 248 | * indexA (the end of the data), then the 64-bit |
michael@0 | 249 | * length didn't fit into indexA and we're having to |
michael@0 | 250 | * add an extra block of zeros. */ |
michael@0 | 251 | b &= ~isBlockB | isBlockA; |
michael@0 | 252 | |
michael@0 | 253 | /* The final bytes of one of the blocks contains the length. */ |
michael@0 | 254 | if (j >= mdBlockSize - mdLengthSize) { |
michael@0 | 255 | /* If this is indexB, write a length byte. */ |
michael@0 | 256 | b = (b&~isBlockB) | |
michael@0 | 257 | (isBlockB&lengthBytes[j-(mdBlockSize-mdLengthSize)]); |
michael@0 | 258 | } |
michael@0 | 259 | block[j] = b; |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | hashObj->update(mdState, block, mdBlockSize); |
michael@0 | 263 | hashObj->end_raw(mdState, block, NULL, mdSize); |
michael@0 | 264 | /* If this is indexB, copy the hash value to |macOut|. */ |
michael@0 | 265 | for (j = 0; j < mdSize; j++) { |
michael@0 | 266 | macOut[j] |= block[j]&isBlockB; |
michael@0 | 267 | } |
michael@0 | 268 | } |
michael@0 | 269 | |
michael@0 | 270 | hashObj->begin(mdState); |
michael@0 | 271 | |
michael@0 | 272 | if (isSSLv3) { |
michael@0 | 273 | /* We repurpose |hmacPad| to contain the SSLv3 pad2 block. */ |
michael@0 | 274 | for (i = 0; i < sslv3PadLen; i++) |
michael@0 | 275 | hmacPad[i] = 0x5c; |
michael@0 | 276 | |
michael@0 | 277 | hashObj->update(mdState, macSecret, macSecretLen); |
michael@0 | 278 | hashObj->update(mdState, hmacPad, sslv3PadLen); |
michael@0 | 279 | hashObj->update(mdState, macOut, mdSize); |
michael@0 | 280 | } else { |
michael@0 | 281 | /* Complete the HMAC in the standard manner. */ |
michael@0 | 282 | for (i = 0; i < mdBlockSize; i++) |
michael@0 | 283 | hmacPad[i] ^= 0x6a; |
michael@0 | 284 | |
michael@0 | 285 | hashObj->update(mdState, hmacPad, mdBlockSize); |
michael@0 | 286 | hashObj->update(mdState, macOut, mdSize); |
michael@0 | 287 | } |
michael@0 | 288 | |
michael@0 | 289 | hashObj->end(mdState, mdOut, mdOutLen, mdOutMax); |
michael@0 | 290 | hashObj->destroy(mdState, PR_TRUE); |
michael@0 | 291 | |
michael@0 | 292 | return SECSuccess; |
michael@0 | 293 | } |
michael@0 | 294 | |
michael@0 | 295 | SECStatus |
michael@0 | 296 | HMAC_ConstantTime( |
michael@0 | 297 | unsigned char *result, |
michael@0 | 298 | unsigned int *resultLen, |
michael@0 | 299 | unsigned int maxResultLen, |
michael@0 | 300 | const SECHashObject *hashObj, |
michael@0 | 301 | const unsigned char *secret, |
michael@0 | 302 | unsigned int secretLen, |
michael@0 | 303 | const unsigned char *header, |
michael@0 | 304 | unsigned int headerLen, |
michael@0 | 305 | const unsigned char *body, |
michael@0 | 306 | unsigned int bodyLen, |
michael@0 | 307 | unsigned int bodyTotalLen) |
michael@0 | 308 | { |
michael@0 | 309 | if (hashObj->end_raw == NULL) |
michael@0 | 310 | return SECFailure; |
michael@0 | 311 | return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen, |
michael@0 | 312 | header, headerLen, body, bodyLen, bodyTotalLen, |
michael@0 | 313 | 0 /* not SSLv3 */); |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | SECStatus |
michael@0 | 317 | SSLv3_MAC_ConstantTime( |
michael@0 | 318 | unsigned char *result, |
michael@0 | 319 | unsigned int *resultLen, |
michael@0 | 320 | unsigned int maxResultLen, |
michael@0 | 321 | const SECHashObject *hashObj, |
michael@0 | 322 | const unsigned char *secret, |
michael@0 | 323 | unsigned int secretLen, |
michael@0 | 324 | const unsigned char *header, |
michael@0 | 325 | unsigned int headerLen, |
michael@0 | 326 | const unsigned char *body, |
michael@0 | 327 | unsigned int bodyLen, |
michael@0 | 328 | unsigned int bodyTotalLen) |
michael@0 | 329 | { |
michael@0 | 330 | if (hashObj->end_raw == NULL) |
michael@0 | 331 | return SECFailure; |
michael@0 | 332 | return MAC(result, resultLen, maxResultLen, hashObj, secret, secretLen, |
michael@0 | 333 | header, headerLen, body, bodyLen, bodyTotalLen, |
michael@0 | 334 | 1 /* SSLv3 */); |
michael@0 | 335 | } |
michael@0 | 336 |