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