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:
parent
79bc7a3212
commit
e94ec3f85b
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user