1d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* ==================================================================== 2d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Copyright (c) 2012 The OpenSSL Project. All rights reserved. 3d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Redistribution and use in source and binary forms, with or without 5d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * modification, are permitted provided that the following conditions 6d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * are met: 7d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 8d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 1. Redistributions of source code must retain the above copyright 9d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer. 10d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 11d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 2. Redistributions in binary form must reproduce the above copyright 12d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * notice, this list of conditions and the following disclaimer in 13d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the documentation and/or other materials provided with the 14d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * distribution. 15d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 16d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 3. All advertising materials mentioning features or use of this 17d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * software must display the following acknowledgment: 18d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 19d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" 20d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 21d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to 22d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * endorse or promote products derived from this software without 23d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * prior written permission. For written permission, please contact 24d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * openssl-core@openssl.org. 25d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 26d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 5. Products derived from this software may not be called "OpenSSL" 27d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * nor may "OpenSSL" appear in their names without prior written 28d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * permission of the OpenSSL Project. 29d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 30d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 6. Redistributions of any form whatsoever must retain the following 31d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * acknowledgment: 32d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "This product includes software developed by the OpenSSL Project 33d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * for use in the OpenSSL Toolkit (http://www.openssl.org/)" 34d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 35d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY 36d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 37d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 38d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR 39d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 40d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 41d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 42d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 43d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 44d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 45d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 46d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * OF THE POSSIBILITY OF SUCH DAMAGE. 47d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * ==================================================================== 48d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 49d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * This product includes cryptographic software written by Eric Young 50d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * (eay@cryptsoft.com). This product includes software written by Tim 51d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Hudson (tjh@cryptsoft.com). */ 52d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 53d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <assert.h> 54d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <string.h> 55d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 56d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/digest.h> 574969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#include <openssl/nid.h> 58d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include <openssl/sha.h> 59d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 60d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#include "../internal.h" 614969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin#include "internal.h" 628ff035535f7cf2903f02bbe94d2fa10b7ab855f1Robert Sloan#include "../fipsmodule/cipher/internal.h" 63d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 64d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 65d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* MAX_HASH_BIT_COUNT_BYTES is the maximum number of bytes in the hash's length 66d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * field. (SHA-384/512 have 128-bit length.) */ 67d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define MAX_HASH_BIT_COUNT_BYTES 16 68d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 69d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* MAX_HASH_BLOCK_SIZE is the maximum hash block size that we'll support. 70d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * Currently SHA-384/512 has a 128-byte block size and that's the largest 71d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * supported by TLS.) */ 72d9e397b599b13d642138480a28c14db7a136bf0Adam Langley#define MAX_HASH_BLOCK_SIZE 128 73d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 749254e681d446a8105bd66f08bae1252d4d89a139Robert Sloanint EVP_tls_cbc_remove_padding(crypto_word_t *out_padding_ok, size_t *out_len, 756f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan const uint8_t *in, size_t in_len, 766f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t block_size, size_t mac_size) { 776f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan const size_t overhead = 1 /* padding length byte */ + mac_size; 78d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 79d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* These lengths are all public so we can test them in non-constant time. */ 80d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (overhead > in_len) { 81d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 82d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 83d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 846f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t padding_length = in[in_len - 1]; 85d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 869254e681d446a8105bd66f08bae1252d4d89a139Robert Sloan crypto_word_t good = constant_time_ge_w(in_len, overhead + padding_length); 87d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* The padding consists of a length byte at the end of the record and 88d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * then that many bytes of padding, all with the same value as the 89d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * length byte. Thus, with the length byte included, there are i+1 90d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * bytes of padding. 91d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 92d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * We can't check just |padding_length+1| bytes because that leaks 93d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * decrypted information. Therefore we always have to check the maximum 94d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * amount of padding possible. (Again, the length of the record is 95d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * public information so we can use it.) */ 966f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t to_check = 256; /* maximum amount of padding, inc length byte. */ 97d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (to_check > in_len) { 98d9e397b599b13d642138480a28c14db7a136bf0Adam Langley to_check = in_len; 99d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 100d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1016f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = 0; i < to_check; i++) { 102d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t mask = constant_time_ge_8(padding_length, i); 103d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t b = in[in_len - 1 - i]; 104d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* The final |padding_length+1| bytes should all have the value 105d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * |padding_length|. Therefore the XOR should be zero. */ 106d9e397b599b13d642138480a28c14db7a136bf0Adam Langley good &= ~(mask & (padding_length ^ b)); 107d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 108d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 109d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If any of the final |padding_length+1| bytes had the wrong value, 110d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * one or more of the lower eight bits of |good| will be cleared. */ 1119254e681d446a8105bd66f08bae1252d4d89a139Robert Sloan good = constant_time_eq_w(0xff, good & 0xff); 112d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 113d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Always treat |padding_length| as zero on error. If, assuming block size of 114d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 16, a padding of [<15 arbitrary bytes> 15] treated |padding_length| as 16 115d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * and returned -1, distinguishing good MAC and bad padding from bad MAC and 116d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * bad padding would give POODLE's padding oracle. */ 117d9e397b599b13d642138480a28c14db7a136bf0Adam Langley padding_length = good & (padding_length + 1); 118d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *out_len = in_len - padding_length; 119c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin *out_padding_ok = good; 120c895d6b1c580258e72e1ed3fcc86d38970ded9e1David Benjamin return 1; 121d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 122d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1236f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanvoid EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in, 1246f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t in_len, size_t orig_len) { 1257c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin uint8_t rotated_mac1[EVP_MAX_MD_SIZE], rotated_mac2[EVP_MAX_MD_SIZE]; 1267c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin uint8_t *rotated_mac = rotated_mac1; 1277c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin uint8_t *rotated_mac_tmp = rotated_mac2; 128d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 129d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* mac_end is the index of |in| just after the end of the MAC. */ 1306f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t mac_end = in_len; 1316f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t mac_start = mac_end - md_size; 132d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 133d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(orig_len >= in_len); 134d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(in_len >= md_size); 135d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(md_size <= EVP_MAX_MD_SIZE); 136d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1371b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin /* scan_start contains the number of bytes that we can ignore because 1381b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin * the MAC's position can only vary by 255 bytes. */ 1396f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t scan_start = 0; 140d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* This information is public so it's safe to branch based on it. */ 141d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (orig_len > md_size + 255 + 1) { 142d9e397b599b13d642138480a28c14db7a136bf0Adam Langley scan_start = orig_len - (md_size + 255 + 1); 143d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 1444969cc9b0ab2905ec478277f50ed3849b37a6c6bDavid Benjamin 1456f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t rotate_offset = 0; 1461b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin uint8_t mac_started = 0; 14769939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(rotated_mac, 0, md_size); 1486f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = scan_start, j = 0; i < orig_len; i++, j++) { 1491b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin if (j >= md_size) { 1501b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin j -= md_size; 1511b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin } 1529254e681d446a8105bd66f08bae1252d4d89a139Robert Sloan crypto_word_t is_mac_start = constant_time_eq_w(i, mac_start); 1531b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin mac_started |= is_mac_start; 154d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t mac_ended = constant_time_ge_8(i, mac_end); 1551b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin rotated_mac[j] |= in[i] & mac_started & ~mac_ended; 1561b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin /* Save the offset that |mac_start| is mapped to. */ 1571b249678059ecd918235790a7a0471771cc4e5ceDavid Benjamin rotate_offset |= j & is_mac_start; 158d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 159d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 1607c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin /* Now rotate the MAC. We rotate in log(md_size) steps, one for each bit 1617c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin * position. */ 1626f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t offset = 1; offset < md_size; offset <<= 1, rotate_offset >>= 1) { 1637c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin /* Rotate by |offset| iff the corresponding bit is set in 1647c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin * |rotate_offset|, placing the result in |rotated_mac_tmp|. */ 1657c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin const uint8_t skip_rotate = (rotate_offset & 1) - 1; 1666f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = 0, j = offset; i < md_size; i++, j++) { 1677c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin if (j >= md_size) { 1687c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin j -= md_size; 1697c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin } 1707c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin rotated_mac_tmp[i] = 1717c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin constant_time_select_8(skip_rotate, rotated_mac[i], rotated_mac[j]); 172d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 1737c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin 1747c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin /* Swap pointers so |rotated_mac| contains the (possibly) rotated value. 1757c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin * Note the number of iterations and thus the identity of these pointers is 1767c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin * public information. */ 1777c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin uint8_t *tmp = rotated_mac; 1787c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin rotated_mac = rotated_mac_tmp; 1797c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin rotated_mac_tmp = tmp; 180d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 1817c0d06c221ce9edf44bbf978b909b38a0aee2084David Benjamin 18269939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(out, rotated_mac, md_size); 183d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 184d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 185d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* u32toBE serialises an unsigned, 32-bit number (n) as four bytes at (p) in 186d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * big-endian order. The value of p is advanced by four. */ 18795add82835138f09cf7bb4a51c04c6320c241674David Benjamin#define u32toBE(n, p) \ 18895add82835138f09cf7bb4a51c04c6320c241674David Benjamin do { \ 18995add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 24); \ 19095add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 16); \ 19195add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 8); \ 19295add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n)); \ 19395add82835138f09cf7bb4a51c04c6320c241674David Benjamin } while (0) 194d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 195d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* u64toBE serialises an unsigned, 64-bit number (n) as eight bytes at (p) in 196d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * big-endian order. The value of p is advanced by eight. */ 19795add82835138f09cf7bb4a51c04c6320c241674David Benjamin#define u64toBE(n, p) \ 19895add82835138f09cf7bb4a51c04c6320c241674David Benjamin do { \ 19995add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 56); \ 20095add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 48); \ 20195add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 40); \ 20295add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 32); \ 20395add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 24); \ 20495add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 16); \ 20595add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n) >> 8); \ 20695add82835138f09cf7bb4a51c04c6320c241674David Benjamin *((p)++) = (uint8_t)((n)); \ 20795add82835138f09cf7bb4a51c04c6320c241674David Benjamin } while (0) 208d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2096f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloantypedef union { 2106f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA_CTX sha1; 2116f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA256_CTX sha256; 2126f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA512_CTX sha512; 2136f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan} HASH_CTX; 2146f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan 2156f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha1_transform(HASH_CTX *ctx, const uint8_t *block) { 2166f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA1_Transform(&ctx->sha1, block); 2176f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan} 2186f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan 2196f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha256_transform(HASH_CTX *ctx, const uint8_t *block) { 2206f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA256_Transform(&ctx->sha256, block); 2216f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan} 2226f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan 2236f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha512_transform(HASH_CTX *ctx, const uint8_t *block) { 2246f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA512_Transform(&ctx->sha512, block); 2256f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan} 2266f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan 227d9e397b599b13d642138480a28c14db7a136bf0Adam Langley/* These functions serialize the state of a hash and thus perform the standard 228d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * "final" operation without adding the padding and length that such a function 229d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * typically does. */ 2306f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) { 2316f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA_CTX *sha1 = &ctx->sha1; 232fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley u32toBE(sha1->h[0], md_out); 233fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley u32toBE(sha1->h[1], md_out); 234fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley u32toBE(sha1->h[2], md_out); 235fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley u32toBE(sha1->h[3], md_out); 236fad6327e4112082b1e77e89a995723f26bd5a9aaAdam Langley u32toBE(sha1->h[4], md_out); 237d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 238d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2396f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) { 2406f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA256_CTX *sha256 = &ctx->sha256; 2416f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (unsigned i = 0; i < 8; i++) { 242d9e397b599b13d642138480a28c14db7a136bf0Adam Langley u32toBE(sha256->h[i], md_out); 243d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 244d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 245d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2466f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloanstatic void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) { 2476f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA512_CTX *sha512 = &ctx->sha512; 2486f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (unsigned i = 0; i < 8; i++) { 249d9e397b599b13d642138480a28c14db7a136bf0Adam Langley u64toBE(sha512->h[i], md_out); 250d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 251d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 252d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 253d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { 254d9e397b599b13d642138480a28c14db7a136bf0Adam Langley switch (EVP_MD_type(md)) { 255d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha1: 256d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha256: 257d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha384: 258d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 259d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 260d9e397b599b13d642138480a28c14db7a136bf0Adam Langley default: 261d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 262d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 263d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 264d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 265d9e397b599b13d642138480a28c14db7a136bf0Adam Langleyint EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out, 266d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t *md_out_size, const uint8_t header[13], 267d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *data, size_t data_plus_mac_size, 268d9e397b599b13d642138480a28c14db7a136bf0Adam Langley size_t data_plus_mac_plus_padding_size, 269d9e397b599b13d642138480a28c14db7a136bf0Adam Langley const uint8_t *mac_secret, 270d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned mac_secret_length) { 2716f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan HASH_CTX md_state; 2726f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out); 2736f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan void (*md_transform)(HASH_CTX *ctx, const uint8_t *block); 274d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned md_size, md_block_size = 64; 2756f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan /* md_length_size is the number of bytes in the length field that terminates 2766f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan * the hash. */ 277d9e397b599b13d642138480a28c14db7a136bf0Adam Langley unsigned md_length_size = 8; 278d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 2796f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan /* Bound the acceptable input so we can forget about many possible overflows 2806f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan * later in this function. This is redundant with the record size limits in 2816f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan * TLS. */ 2826f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan if (data_plus_mac_plus_padding_size >= 1024 * 1024) { 2836f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan assert(0); 2846f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan return 0; 2856f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan } 286d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 287d9e397b599b13d642138480a28c14db7a136bf0Adam Langley switch (EVP_MD_type(md)) { 288d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha1: 2896f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA1_Init(&md_state.sha1); 290d9e397b599b13d642138480a28c14db7a136bf0Adam Langley md_final_raw = tls1_sha1_final_raw; 2916f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform = tls1_sha1_transform; 2926f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_size = SHA_DIGEST_LENGTH; 293d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 294d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 295d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha256: 2966f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA256_Init(&md_state.sha256); 297d9e397b599b13d642138480a28c14db7a136bf0Adam Langley md_final_raw = tls1_sha256_final_raw; 2986f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform = tls1_sha256_transform; 2996f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_size = SHA256_DIGEST_LENGTH; 300d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 301d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 302d9e397b599b13d642138480a28c14db7a136bf0Adam Langley case NID_sha384: 3036f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan SHA384_Init(&md_state.sha512); 304d9e397b599b13d642138480a28c14db7a136bf0Adam Langley md_final_raw = tls1_sha512_final_raw; 3056f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform = tls1_sha512_transform; 3066f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_size = SHA384_DIGEST_LENGTH; 307d9e397b599b13d642138480a28c14db7a136bf0Adam Langley md_block_size = 128; 308d9e397b599b13d642138480a28c14db7a136bf0Adam Langley md_length_size = 16; 309d9e397b599b13d642138480a28c14db7a136bf0Adam Langley break; 310d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 311d9e397b599b13d642138480a28c14db7a136bf0Adam Langley default: 312d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* EVP_tls_cbc_record_digest_supported should have been called first to 313d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * check that the hash function is supported. */ 314d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(0); 315d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *md_out_size = 0; 316d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 317d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 318d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 319d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(md_length_size <= MAX_HASH_BIT_COUNT_BYTES); 320d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(md_block_size <= MAX_HASH_BLOCK_SIZE); 321d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(md_size <= EVP_MAX_MD_SIZE); 322d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3236f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan static const size_t kHeaderLength = 13; 324d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 325d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* kVarianceBlocks is the number of blocks of the hash that we have to 326d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * calculate in constant time because they could be altered by the 327d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * padding value. 328d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 329d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * TLSv1 has MACs up to 48 bytes long (SHA-384) and the padding is not 330d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * required to be minimal. Therefore we say that the final six blocks 331d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * can vary based on the padding. */ 3326f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan static const size_t kVarianceBlocks = 6; 333d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 334d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* From now on we're dealing with the MAC, which conceptually has 13 335d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * bytes of `header' before the start of the data. */ 3366f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t len = data_plus_mac_plus_padding_size + kHeaderLength; 337d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* max_mac_bytes contains the maximum bytes of bytes in the MAC, including 3386f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan * |header|, assuming that there's no padding. */ 3396f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t max_mac_bytes = len - md_size - 1; 340d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* num_blocks is the maximum number of hash blocks. */ 3416f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t num_blocks = 342d9e397b599b13d642138480a28c14db7a136bf0Adam Langley (max_mac_bytes + 1 + md_length_size + md_block_size - 1) / md_block_size; 343d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* In order to calculate the MAC in constant time we have to handle 344d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * the final blocks specially because the padding value could cause the 345d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * end to appear somewhere in the final |kVarianceBlocks| blocks and we 346d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * can't leak where. However, |num_starting_blocks| worth of data can 347d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * be hashed right away because no padding value can affect whether 348d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * they are plaintext. */ 3496f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t num_starting_blocks = 0; 350d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* k is the starting byte offset into the conceptual header||data where 351d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * we start processing. */ 3526f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t k = 0; 353d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* mac_end_offset is the index just past the end of the data to be 354d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * MACed. */ 3556f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t mac_end_offset = data_plus_mac_size + kHeaderLength - md_size; 356d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* c is the index of the 0x80 byte in the final hash block that 357d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * contains application data. */ 3586f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t c = mac_end_offset % md_block_size; 359d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* index_a is the hash block number that contains the 0x80 terminating 360d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * value. */ 3616f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t index_a = mac_end_offset / md_block_size; 362d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* index_b is the hash block number that contains the 64-bit hash 363d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * length, in bits. */ 3646f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t index_b = (mac_end_offset + md_length_size) / md_block_size; 365d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 366d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (num_blocks > kVarianceBlocks) { 367d9e397b599b13d642138480a28c14db7a136bf0Adam Langley num_starting_blocks = num_blocks - kVarianceBlocks; 368d9e397b599b13d642138480a28c14db7a136bf0Adam Langley k = md_block_size * num_starting_blocks; 369d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 370d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3716f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan /* bits is the hash-length in bits. It includes the additional hash 3726f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan * block for the masked HMAC key. */ 3736f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan size_t bits = 8 * mac_end_offset; /* at most 18 bits to represent */ 374d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 375d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Compute the initial HMAC block. */ 376d9e397b599b13d642138480a28c14db7a136bf0Adam Langley bits += 8 * md_block_size; 3776f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan /* hmac_pad is the masked HMAC key. */ 3786f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t hmac_pad[MAX_HASH_BLOCK_SIZE]; 37969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(hmac_pad, 0, md_block_size); 380d9e397b599b13d642138480a28c14db7a136bf0Adam Langley assert(mac_secret_length <= sizeof(hmac_pad)); 38169939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(hmac_pad, mac_secret, mac_secret_length); 3826f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = 0; i < md_block_size; i++) { 383d9e397b599b13d642138480a28c14db7a136bf0Adam Langley hmac_pad[i] ^= 0x36; 384d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 385d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3866f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform(&md_state, hmac_pad); 387d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 3886f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan /* The length check means |bits| fits in four bytes. */ 3896f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; 39069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(length_bytes, 0, md_length_size - 4); 391d9e397b599b13d642138480a28c14db7a136bf0Adam Langley length_bytes[md_length_size - 4] = (uint8_t)(bits >> 24); 392d9e397b599b13d642138480a28c14db7a136bf0Adam Langley length_bytes[md_length_size - 3] = (uint8_t)(bits >> 16); 393d9e397b599b13d642138480a28c14db7a136bf0Adam Langley length_bytes[md_length_size - 2] = (uint8_t)(bits >> 8); 394d9e397b599b13d642138480a28c14db7a136bf0Adam Langley length_bytes[md_length_size - 1] = (uint8_t)bits; 395d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 396d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (k > 0) { 397d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* k is a multiple of md_block_size. */ 3986f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t first_block[MAX_HASH_BLOCK_SIZE]; 39969939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(first_block, header, 13); 40069939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); 4016f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform(&md_state, first_block); 4026f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = 1; i < k / md_block_size; i++) { 4036f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform(&md_state, data + md_block_size * i - 13); 404d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 405d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 406d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4076f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t mac_out[EVP_MAX_MD_SIZE]; 40869939df2891f62f7f00ff2ac275f1cd81a67454cRobert Sloan OPENSSL_memset(mac_out, 0, sizeof(mac_out)); 409d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 410d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* We now process the final hash blocks. For each block, we construct 411d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * it in constant time. If the |i==index_a| then we'll include the 0x80 412d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * bytes and zero pad etc. For each block we selectively copy it, in 413d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * constant time, to |mac_out|. */ 4146f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = num_starting_blocks; 4156f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan i <= num_starting_blocks + kVarianceBlocks; i++) { 416d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t block[MAX_HASH_BLOCK_SIZE]; 417d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t is_block_a = constant_time_eq_8(i, index_a); 418d9e397b599b13d642138480a28c14db7a136bf0Adam Langley uint8_t is_block_b = constant_time_eq_8(i, index_b); 4196f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t j = 0; j < md_block_size; j++) { 4206f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t b = 0; 421d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (k < kHeaderLength) { 422d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b = header[k]; 423d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } else if (k < data_plus_mac_plus_padding_size + kHeaderLength) { 424d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b = data[k - kHeaderLength]; 425d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 426d9e397b599b13d642138480a28c14db7a136bf0Adam Langley k++; 427d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4286f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t is_past_c = is_block_a & constant_time_ge_8(j, c); 4296f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan uint8_t is_past_cp1 = is_block_a & constant_time_ge_8(j, c + 1); 430d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If this is the block containing the end of the 431d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * application data, and we are at the offset for the 432d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * 0x80 value, then overwrite b with 0x80. */ 433d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b = constant_time_select_8(is_past_c, 0x80, b); 434d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If this the the block containing the end of the 435d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * application data and we're past the 0x80 value then 436d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * just write zero. */ 437d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b = b & ~is_past_cp1; 438d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If this is index_b (the final block), but not 439d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * index_a (the end of the data), then the 64-bit 440d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * length didn't fit into index_a and we're having to 441d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * add an extra block of zeros. */ 442d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b &= ~is_block_b | is_block_a; 443d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 444d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* The final bytes of one of the blocks contains the 445d9e397b599b13d642138480a28c14db7a136bf0Adam Langley * length. */ 446d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (j >= md_block_size - md_length_size) { 447d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If this is index_b, write a length byte. */ 448d9e397b599b13d642138480a28c14db7a136bf0Adam Langley b = constant_time_select_8( 449d9e397b599b13d642138480a28c14db7a136bf0Adam Langley is_block_b, length_bytes[j - (md_block_size - md_length_size)], b); 450d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 451d9e397b599b13d642138480a28c14db7a136bf0Adam Langley block[j] = b; 452d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 453d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4546f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_transform(&md_state, block); 4556f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan md_final_raw(&md_state, block); 456d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* If this is index_b, copy the hash value to |mac_out|. */ 4576f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t j = 0; j < md_size; j++) { 458d9e397b599b13d642138480a28c14db7a136bf0Adam Langley mac_out[j] |= block[j] & is_block_b; 459d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 460d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 461d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 4626f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan EVP_MD_CTX md_ctx; 463d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_CTX_init(&md_ctx); 464d9e397b599b13d642138480a28c14db7a136bf0Adam Langley if (!EVP_DigestInit_ex(&md_ctx, md, NULL /* engine */)) { 465d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_CTX_cleanup(&md_ctx); 466d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 0; 467d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 468d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 469d9e397b599b13d642138480a28c14db7a136bf0Adam Langley /* Complete the HMAC in the standard manner. */ 4706f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan for (size_t i = 0; i < md_block_size; i++) { 471d9e397b599b13d642138480a28c14db7a136bf0Adam Langley hmac_pad[i] ^= 0x6a; 472d9e397b599b13d642138480a28c14db7a136bf0Adam Langley } 473d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 474d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_DigestUpdate(&md_ctx, hmac_pad, md_block_size); 475d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_DigestUpdate(&md_ctx, mac_out, md_size); 4766f79a50fbad5817b8fc7a07c5657d8249c57a0f7Robert Sloan unsigned md_out_size_u; 477d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_DigestFinal(&md_ctx, md_out, &md_out_size_u); 478d9e397b599b13d642138480a28c14db7a136bf0Adam Langley *md_out_size = md_out_size_u; 479d9e397b599b13d642138480a28c14db7a136bf0Adam Langley EVP_MD_CTX_cleanup(&md_ctx); 480d9e397b599b13d642138480a28c14db7a136bf0Adam Langley 481d9e397b599b13d642138480a28c14db7a136bf0Adam Langley return 1; 482d9e397b599b13d642138480a28c14db7a136bf0Adam Langley} 483