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)); \
} 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
* "final" operation without adding the padding and length that such a function
* typically does. */
static void tls1_sha1_final_raw(void *ctx, uint8_t *md_out) {
SHA_CTX *sha1 = ctx;
static void tls1_sha1_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA_CTX *sha1 = &ctx->sha1;
u32toBE(sha1->h[0], md_out);
u32toBE(sha1->h[1], md_out);
u32toBE(sha1->h[2], md_out);
u32toBE(sha1->h[3], 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) {
SHA256_CTX *sha256 = ctx;
static void tls1_sha256_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA256_CTX *sha256 = &ctx->sha256;
for (unsigned i = 0; i < 8; i++) {
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) {
SHA512_CTX *sha512 = ctx;
static void tls1_sha512_final_raw(HASH_CTX *ctx, uint8_t *md_out) {
SHA512_CTX *sha512 = &ctx->sha512;
for (unsigned i = 0; i < 8; i++) {
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) {
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,
const uint8_t *mac_secret,
unsigned mac_secret_length) {
union {
double align;
uint8_t c[sizeof(LARGEST_DIGEST_CTX)];
} md_state;
void (*md_final_raw)(void *ctx, uint8_t *md_out);
void (*md_transform)(void *ctx, const uint8_t *block);
HASH_CTX md_state;
void (*md_final_raw)(HASH_CTX *ctx, uint8_t *md_out);
void (*md_transform)(HASH_CTX *ctx, const uint8_t *block);
unsigned md_size, md_block_size = 64;
/* md_length_size is the number of bytes in the length field that terminates
* 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)) {
case NID_sha1:
SHA1_Init((SHA_CTX *)md_state.c);
SHA1_Init(&md_state.sha1);
md_final_raw = tls1_sha1_final_raw;
md_transform =
(void (*)(void *ctx, const uint8_t *block))SHA1_Transform;
md_size = 20;
md_transform = tls1_sha1_transform;
md_size = SHA_DIGEST_LENGTH;
break;
case NID_sha256:
SHA256_Init((SHA256_CTX *)md_state.c);
SHA256_Init(&md_state.sha256);
md_final_raw = tls1_sha256_final_raw;
md_transform =
(void (*)(void *ctx, const uint8_t *block))SHA256_Transform;
md_size = 32;
md_transform = tls1_sha256_transform;
md_size = SHA256_DIGEST_LENGTH;
break;
case NID_sha384:
SHA384_Init((SHA512_CTX *)md_state.c);
SHA384_Init(&md_state.sha512);
md_final_raw = tls1_sha512_final_raw;
md_transform =
(void (*)(void *ctx, const uint8_t *block))SHA512_Transform;
md_size = 384 / 8;
md_transform = tls1_sha512_transform;
md_size = SHA384_DIGEST_LENGTH;
md_block_size = 128;
md_length_size = 16;
break;
@ -378,7 +385,7 @@ int EVP_tls_cbc_digest_record(const EVP_MD *md, uint8_t *md_out,
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. */
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];
OPENSSL_memcpy(first_block, header, 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++) {
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;
}
md_transform(md_state.c, block);
md_final_raw(md_state.c, block);
md_transform(&md_state, block);
md_final_raw(&md_state, block);
/* If this is index_b, copy the hash value to |mac_out|. */
for (size_t j = 0; j < md_size; j++) {
mac_out[j] |= block[j] & is_block_b;