Remove a few more unions.

Bug: 301
Change-Id: Idb558cd2a925e9c762369ec7cead08f7d1cec2eb
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/53093
Reviewed-by: Adam Langley <agl@google.com>
chromium-5359
David Benjamin 3 years ago committed by Adam Langley
parent 0f2c55cb74
commit 6c2af68fe8
  1. 19
      crypto/fipsmodule/aes/aes_nohw.c
  2. 8
      crypto/fipsmodule/aes/key_wrap.c
  3. 15
      crypto/fipsmodule/cipher/e_aes.c
  4. 14
      crypto/fipsmodule/modes/cbc.c
  5. 16
      crypto/fipsmodule/rand/ctrdrbg.c
  6. 5
      crypto/fipsmodule/rand/internal.h

@ -18,6 +18,7 @@
#include <string.h> #include <string.h>
#include "../../internal.h" #include "../../internal.h"
#include "internal.h"
#if defined(OPENSSL_SSE2) #if defined(OPENSSL_SSE2)
#include <emmintrin.h> #include <emmintrin.h>
@ -1181,29 +1182,27 @@ void aes_nohw_ctr32_encrypt_blocks(const uint8_t *in, uint8_t *out,
aes_nohw_expand_round_keys(&sched, key); aes_nohw_expand_round_keys(&sched, key);
// Make |AES_NOHW_BATCH_SIZE| copies of |ivec|. // Make |AES_NOHW_BATCH_SIZE| copies of |ivec|.
alignas(AES_NOHW_WORD_SIZE) union { alignas(AES_NOHW_WORD_SIZE) uint8_t ivs[AES_NOHW_BATCH_SIZE * 16];
uint32_t u32[AES_NOHW_BATCH_SIZE * 4]; alignas(AES_NOHW_WORD_SIZE) uint8_t enc_ivs[AES_NOHW_BATCH_SIZE * 16];
uint8_t u8[AES_NOHW_BATCH_SIZE * 16];
} ivs, enc_ivs;
for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) {
memcpy(ivs.u8 + 16 * i, ivec, 16); memcpy(ivs + 16 * i, ivec, 16);
} }
uint32_t ctr = CRYPTO_bswap4(ivs.u32[3]); uint32_t ctr = CRYPTO_load_u32_be(ivs + 12);
for (;;) { for (;;) {
// Update counters. // Update counters.
for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) { for (size_t i = 0; i < AES_NOHW_BATCH_SIZE; i++) {
ivs.u32[4 * i + 3] = CRYPTO_bswap4(ctr + i); CRYPTO_store_u32_be(ivs + 16 * i + 12, ctr + i);
} }
size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks; size_t todo = blocks >= AES_NOHW_BATCH_SIZE ? AES_NOHW_BATCH_SIZE : blocks;
AES_NOHW_BATCH batch; AES_NOHW_BATCH batch;
aes_nohw_to_batch(&batch, ivs.u8, todo); aes_nohw_to_batch(&batch, ivs, todo);
aes_nohw_encrypt_batch(&sched, key->rounds, &batch); aes_nohw_encrypt_batch(&sched, key->rounds, &batch);
aes_nohw_from_batch(enc_ivs.u8, todo, &batch); aes_nohw_from_batch(enc_ivs, todo, &batch);
for (size_t i = 0; i < todo; i++) { for (size_t i = 0; i < todo; i++) {
aes_nohw_xor_block(out + 16 * i, in + 16 * i, enc_ivs.u8 + 16 * i); aes_nohw_xor_block(out + 16 * i, in + 16 * i, enc_ivs + 16 * i);
} }
blocks -= todo; blocks -= todo;

@ -164,10 +164,8 @@ static const uint8_t kPaddingConstant[4] = {0xa6, 0x59, 0x59, 0xa6};
int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len, int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len,
size_t max_out, const uint8_t *in, size_t in_len) { size_t max_out, const uint8_t *in, size_t in_len) {
// See https://tools.ietf.org/html/rfc5649#section-4.1 // See https://tools.ietf.org/html/rfc5649#section-4.1
const uint32_t in_len32_be = CRYPTO_bswap4(in_len);
const uint64_t in_len64 = in_len; const uint64_t in_len64 = in_len;
const size_t padded_len = (in_len + 7) & ~7; const size_t padded_len = (in_len + 7) & ~7;
*out_len = 0; *out_len = 0;
if (in_len == 0 || in_len64 > 0xffffffffu || in_len + 7 < in_len || if (in_len == 0 || in_len64 > 0xffffffffu || in_len + 7 < in_len ||
padded_len + 8 < padded_len || max_out < padded_len + 8) { padded_len + 8 < padded_len || max_out < padded_len + 8) {
@ -176,7 +174,7 @@ int AES_wrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len,
uint8_t block[AES_BLOCK_SIZE]; uint8_t block[AES_BLOCK_SIZE];
memcpy(block, kPaddingConstant, sizeof(kPaddingConstant)); memcpy(block, kPaddingConstant, sizeof(kPaddingConstant));
memcpy(block + 4, &in_len32_be, sizeof(in_len32_be)); CRYPTO_store_u32_be(block + 4, (uint32_t)in_len);
if (in_len <= 8) { if (in_len <= 8) {
memset(block + 8, 0, 8); memset(block + 8, 0, 8);
@ -226,9 +224,7 @@ int AES_unwrap_key_padded(const AES_KEY *key, uint8_t *out, size_t *out_len,
crypto_word_t ok = constant_time_eq_int( crypto_word_t ok = constant_time_eq_int(
CRYPTO_memcmp(iv, kPaddingConstant, sizeof(kPaddingConstant)), 0); CRYPTO_memcmp(iv, kPaddingConstant, sizeof(kPaddingConstant)), 0);
uint32_t claimed_len32; const size_t claimed_len = CRYPTO_load_u32_be(iv + 4);
memcpy(&claimed_len32, iv + 4, sizeof(claimed_len32));
const size_t claimed_len = CRYPTO_bswap4(claimed_len32);
ok &= ~constant_time_is_zero_w(claimed_len); ok &= ~constant_time_is_zero_w(claimed_len);
ok &= constant_time_eq_w((claimed_len - 1) >> 3, (in_len - 9) >> 3); ok &= constant_time_eq_w((claimed_len - 1) >> 3, (in_len - 9) >> 3);

@ -1297,12 +1297,9 @@ static int aead_aes_gcm_tls12_seal_scatter(
} }
// The given nonces must be strictly monotonically increasing. // The given nonces must be strictly monotonically increasing.
uint64_t given_counter; uint64_t given_counter =
OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t));
sizeof(given_counter)); if (given_counter == UINT64_MAX || given_counter < gcm_ctx->min_next_nonce) {
given_counter = CRYPTO_bswap8(given_counter);
if (given_counter == UINT64_MAX ||
given_counter < gcm_ctx->min_next_nonce) {
OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE); OPENSSL_PUT_ERROR(CIPHER, CIPHER_R_INVALID_NONCE);
return 0; return 0;
} }
@ -1397,10 +1394,8 @@ static int aead_aes_gcm_tls13_seal_scatter(
// The given nonces must be strictly monotonically increasing. See // The given nonces must be strictly monotonically increasing. See
// https://tools.ietf.org/html/rfc8446#section-5.3 for details of the TLS 1.3 // https://tools.ietf.org/html/rfc8446#section-5.3 for details of the TLS 1.3
// nonce construction. // nonce construction.
uint64_t given_counter; uint64_t given_counter =
OPENSSL_memcpy(&given_counter, nonce + nonce_len - sizeof(given_counter), CRYPTO_load_u64_be(nonce + nonce_len - sizeof(uint64_t));
sizeof(given_counter));
given_counter = CRYPTO_bswap8(given_counter);
if (gcm_ctx->first) { if (gcm_ctx->first) {
// In the first call the sequence number will be zero and therefore the // In the first call the sequence number will be zero and therefore the

@ -116,11 +116,7 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
assert(inptr >= outptr || inptr + len <= outptr); assert(inptr >= outptr || inptr + len <= outptr);
size_t n; size_t n;
union { alignas(16) uint8_t tmp[16];
crypto_word_t t[16 / sizeof(crypto_word_t)];
uint8_t c[16];
} tmp;
if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) { if ((inptr >= 32 && outptr <= inptr - 32) || inptr < outptr) {
// If |out| is at least two blocks behind |in| or completely disjoint, there // If |out| is at least two blocks behind |in| or completely disjoint, there
// is no need to decrypt to a temporary block. // is no need to decrypt to a temporary block.
@ -144,10 +140,10 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
"block cannot be evenly divided into words"); "block cannot be evenly divided into words");
while (len >= 16) { while (len >= 16) {
(*block)(in, tmp.c, key); (*block)(in, tmp, key);
for (n = 0; n < 16; n += sizeof(crypto_word_t)) { for (n = 0; n < 16; n += sizeof(crypto_word_t)) {
crypto_word_t c = CRYPTO_load_word_le(in + n); crypto_word_t c = CRYPTO_load_word_le(in + n);
CRYPTO_store_word_le(out + n, tmp.t[n / sizeof(crypto_word_t)] ^ CRYPTO_store_word_le(out + n, CRYPTO_load_word_le(tmp + n) ^
CRYPTO_load_word_le(ivec + n)); CRYPTO_load_word_le(ivec + n));
CRYPTO_store_word_le(ivec + n, c); CRYPTO_store_word_le(ivec + n, c);
} }
@ -159,10 +155,10 @@ void CRYPTO_cbc128_decrypt(const uint8_t *in, uint8_t *out, size_t len,
while (len) { while (len) {
uint8_t c; uint8_t c;
(*block)(in, tmp.c, key); (*block)(in, tmp, key);
for (n = 0; n < 16 && n < len; ++n) { for (n = 0; n < 16 && n < len; ++n) {
c = in[n]; c = in[n];
out[n] = tmp.c[n] ^ ivec[n]; out[n] = tmp[n] ^ ivec[n];
ivec[n] = c; ivec[n] = c;
} }
if (len <= 16) { if (len <= 16) {

@ -59,7 +59,7 @@ int CTR_DRBG_init(CTR_DRBG_STATE *drbg,
} }
drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32); drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, seed_material, 32);
OPENSSL_memcpy(drbg->counter.bytes, seed_material + 32, 16); OPENSSL_memcpy(drbg->counter, seed_material + 32, 16);
drbg->reseed_counter = 1; drbg->reseed_counter = 1;
return 1; return 1;
@ -71,8 +71,8 @@ OPENSSL_STATIC_ASSERT(CTR_DRBG_ENTROPY_LEN % AES_BLOCK_SIZE == 0,
// ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a // ctr_inc adds |n| to the last four bytes of |drbg->counter|, treated as a
// big-endian number. // big-endian number.
static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) { static void ctr32_add(CTR_DRBG_STATE *drbg, uint32_t n) {
drbg->counter.words[3] = uint32_t ctr = CRYPTO_load_u32_be(drbg->counter + 12);
CRYPTO_bswap4(CRYPTO_bswap4(drbg->counter.words[3]) + n); CRYPTO_store_u32_be(drbg->counter + 12, ctr + n);
} }
static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data, static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data,
@ -87,7 +87,7 @@ static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data,
uint8_t temp[CTR_DRBG_ENTROPY_LEN]; uint8_t temp[CTR_DRBG_ENTROPY_LEN];
for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) { for (size_t i = 0; i < CTR_DRBG_ENTROPY_LEN; i += AES_BLOCK_SIZE) {
ctr32_add(drbg, 1); ctr32_add(drbg, 1);
drbg->block(drbg->counter.bytes, temp + i, &drbg->ks); drbg->block(drbg->counter, temp + i, &drbg->ks);
} }
for (size_t i = 0; i < data_len; i++) { for (size_t i = 0; i < data_len; i++) {
@ -95,7 +95,7 @@ static int ctr_drbg_update(CTR_DRBG_STATE *drbg, const uint8_t *data,
} }
drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32); drbg->ctr = aes_ctr_set_key(&drbg->ks, NULL, &drbg->block, temp, 32);
OPENSSL_memcpy(drbg->counter.bytes, temp + 32, 16); OPENSSL_memcpy(drbg->counter, temp + 32, 16);
return 1; return 1;
} }
@ -167,12 +167,12 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len,
if (drbg->ctr) { if (drbg->ctr) {
OPENSSL_memset(out, 0, todo); OPENSSL_memset(out, 0, todo);
ctr32_add(drbg, 1); ctr32_add(drbg, 1);
drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter.bytes); drbg->ctr(out, out, num_blocks, &drbg->ks, drbg->counter);
ctr32_add(drbg, num_blocks - 1); ctr32_add(drbg, num_blocks - 1);
} else { } else {
for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) { for (size_t i = 0; i < todo; i += AES_BLOCK_SIZE) {
ctr32_add(drbg, 1); ctr32_add(drbg, 1);
drbg->block(drbg->counter.bytes, out + i, &drbg->ks); drbg->block(drbg->counter, out + i, &drbg->ks);
} }
} }
@ -183,7 +183,7 @@ int CTR_DRBG_generate(CTR_DRBG_STATE *drbg, uint8_t *out, size_t out_len,
if (out_len > 0) { if (out_len > 0) {
uint8_t block[AES_BLOCK_SIZE]; uint8_t block[AES_BLOCK_SIZE];
ctr32_add(drbg, 1); ctr32_add(drbg, 1);
drbg->block(drbg->counter.bytes, block, &drbg->ks); drbg->block(drbg->counter, block, &drbg->ks);
OPENSSL_memcpy(out, block, out_len); OPENSSL_memcpy(out, block, out_len);
} }

@ -99,10 +99,7 @@ typedef struct {
AES_KEY ks; AES_KEY ks;
block128_f block; block128_f block;
ctr128_f ctr; ctr128_f ctr;
union { uint8_t counter[16];
uint8_t bytes[16];
uint32_t words[4];
} counter;
uint64_t reseed_counter; uint64_t reseed_counter;
} CTR_DRBG_STATE; } CTR_DRBG_STATE;

Loading…
Cancel
Save