Use a union in tls_cbc.c.

This is slightly tidier than casting through function pointers. (Also
more defined? But we cast T* => void* within a function pointer all over
the place, so that's probably a lost cause.)

Change-Id: I8f435906f3066d1377eababf940e3db34c626acd
Reviewed-on: https://boringssl-review.googlesource.com/14313
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2017-03-20 12:45:56 -04:00 committed by Adam Langley
parent 79bc7a3212
commit e94ec3f85b

View File

@ -208,36 +208,49 @@ void EVP_tls_cbc_copy_mac(uint8_t *out, size_t md_size, const uint8_t *in,
*((p)++) = (uint8_t)((n)); \ *((p)++) = (uint8_t)((n)); \
} while (0) } while (0)
typedef union {
SHA_CTX sha1;
SHA256_CTX sha256;
SHA512_CTX sha512;
} HASH_CTX;
static void tls1_sha1_transform(HASH_CTX *ctx, const uint8_t *block) {
SHA1_Transform(&ctx->sha1, block);
}
static void tls1_sha256_transform(HASH_CTX *ctx, const uint8_t *block) {
SHA256_Transform(&ctx->sha256, block);
}
static void tls1_sha512_transform(HASH_CTX *ctx, const uint8_t *block) {
SHA512_Transform(&ctx->sha512, block);
}
/* These functions serialize the state of a hash and thus perform the standard /* These functions serialize the state of a hash and thus perform the standard
* "final" operation without adding the padding and length that such a function * "final" operation without adding the padding and length that such a function
* typically does. */ * typically does. */
static void tls1_sha1_final_raw(void *ctx, uint8_t *md_out) { static void tls1_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA_CTX *sha1 = ctx; SHA_CTX *sha1 = &ctx->sha1;
u32toBE(sha1->h[0], md_out); u32toBE(sha1->h[0], md_out);
u32toBE(sha1->h[1], md_out); u32toBE(sha1->h[1], md_out);
u32toBE(sha1->h[2], md_out); u32toBE(sha1->h[2], md_out);
u32toBE(sha1->h[3], md_out); u32toBE(sha1->h[3], md_out);
u32toBE(sha1->h[4], md_out); u32toBE(sha1->h[4], md_out);
} }
#define LARGEST_DIGEST_CTX SHA_CTX
static void tls1_sha256_final_raw(void *ctx, uint8_t *md_out) { static void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA256_CTX *sha256 = ctx; SHA256_CTX *sha256 = &ctx->sha256;
for (unsigned i = 0; i < 8; i++) { for (unsigned i = 0; i < 8; i++) {
u32toBE(sha256->h[i], md_out); u32toBE(sha256->h[i], md_out);
} }
} }
#undef LARGEST_DIGEST_CTX
#define LARGEST_DIGEST_CTX SHA256_CTX
static void tls1_sha512_final_raw(void *ctx, uint8_t *md_out) { static void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA512_CTX *sha512 = ctx; SHA512_CTX *sha512 = &ctx->sha512;
for (unsigned i = 0; i < 8; i++) { for (unsigned i = 0; i < 8; i++) {
u64toBE(sha512->h[i], md_out); u64toBE(sha512->h[i], md_out);
} }
} }
#undef LARGEST_DIGEST_CTX
#define LARGEST_DIGEST_CTX SHA512_CTX
int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) { int EVP_tls_cbc_record_digest_supported(const EVP_MD *md) {
switch (EVP_MD_type(md)) { switch (EVP_MD_type(md)) {
@ -257,12 +270,9 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
size_t data_plus_mac_plus_padding_size, size_t data_plus_mac_plus_padding_size,
const uint8_t *mac_secret, const uint8_t *mac_secret,
unsigned mac_secret_length) { unsigned mac_secret_length) {
union { HASH_CTX md_state;
double align; void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out);
uint8_t c[sizeof(LARGEST_DIGEST_CTX)]; void (*md_transform)(HASH_CTX *ctx, const uint8_t *block);
} md_state;
void (*md_final_raw)(void *ctx, uint8_t *md_out);
void (*md_transform)(void *ctx, const uint8_t *block);
unsigned md_size, md_block_size = 64; unsigned md_size, md_block_size = 64;
/* md_length_size is the number of bytes in the length field that terminates /* md_length_size is the number of bytes in the length field that terminates
* the hash. */ * the hash. */
@ -278,27 +288,24 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
switch (EVP_MD_type(md)) { switch (EVP_MD_type(md)) {
case NID_sha1: case NID_sha1:
SHA1_Init((SHA_CTX *)md_state.c); SHA1_Init(&md_state.sha1);
md_final_raw = tls1_sha1_final_raw; md_final_raw = tls1_sha1_final_raw;
md_transform = md_transform = tls1_sha1_transform;
(void (*)(void *ctx, const uint8_t *block))SHA1_Transform; md_size = SHA_DIGEST_LENGTH;
md_size = 20;
break; break;
case NID_sha256: case NID_sha256:
SHA256_Init((SHA256_CTX *)md_state.c); SHA256_Init(&md_state.sha256);
md_final_raw = tls1_sha256_final_raw; md_final_raw = tls1_sha256_final_raw;
md_transform = md_transform = tls1_sha256_transform;
(void (*)(void *ctx, const uint8_t *block))SHA256_Transform; md_size = SHA256_DIGEST_LENGTH;
md_size = 32;
break; break;
case NID_sha384: case NID_sha384:
SHA384_Init((SHA512_CTX *)md_state.c); SHA384_Init(&md_state.sha512);
md_final_raw = tls1_sha512_final_raw; md_final_raw = tls1_sha512_final_raw;
md_transform = md_transform = tls1_sha512_transform;
(void (*)(void *ctx, const uint8_t *block))SHA512_Transform; md_size = SHA384_DIGEST_LENGTH;
md_size = 384 / 8;
md_block_size = 128; md_block_size = 128;
md_length_size = 16; md_length_size = 16;
break; break;
@ -378,7 +385,7 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
hmac_pad[i] ^= 0x36; hmac_pad[i] ^= 0x36;
} }
md_transform(md_state.c, hmac_pad); md_transform(&md_state, hmac_pad);
/* The length check means |bits| fits in four bytes. */ /* The length check means |bits| fits in four bytes. */
uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES]; uint8_t length_bytes[MAX_HASH_BIT_COUNT_BYTES];
@ -393,9 +400,9 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
uint8_t first_block[MAX_HASH_BLOCK_SIZE]; uint8_t first_block[MAX_HASH_BLOCK_SIZE];
OPENSSL_memcpy(first_block, header, 13); OPENSSL_memcpy(first_block, header, 13);
OPENSSL_memcpy(first_block + 13, data, md_block_size - 13); OPENSSL_memcpy(first_block + 13, data, md_block_size - 13);
md_transform(md_state.c, first_block); md_transform(&md_state, first_block);
for (size_t i = 1; i < k / md_block_size; i++) { for (size_t i = 1; i < k / md_block_size; i++) {
md_transform(md_state.c, data + md_block_size * i - 13); md_transform(&md_state, data + md_block_size * i - 13);
} }
} }
@ -446,8 +453,8 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
block[j] = b; block[j] = b;
} }
md_transform(md_state.c, block); md_transform(&md_state, block);
md_final_raw(md_state.c, block); md_final_raw(&md_state, block);
/* If this is index_b, copy the hash value to |mac_out|. */ /* If this is index_b, copy the hash value to |mac_out|. */
for (size_t j = 0; j < md_size; j++) { for (size_t j = 0; j < md_size; j++) {
mac_out[j] |= block[j] & is_block_b; mac_out[j] |= block[j] & is_block_b;