diff --git a/crypto/cipher/tls_cbc.c b/crypto/cipher/tls_cbc.c index 46377bff..a825c1ce 100644 --- a/crypto/cipher/tls_cbc.c +++ b/crypto/cipher/tls_cbc.c @@ -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;