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