diff --git a/crypto/endian_test.cc b/crypto/endian_test.cc index a2ab32994b..8dd701aeb4 100644 --- a/crypto/endian_test.cc +++ b/crypto/endian_test.cc @@ -269,12 +269,10 @@ TEST(EndianTest, BN_bn2bin_padded) { TEST(EndianTest, AES) { // Initialize the key and message buffers with zeros - uint8_t key[AES_BLOCK_SIZE] = {0}; - key[0] = 0xaa; - key[1] = 0xbb; - uint8_t message[AES_BLOCK_SIZE] = {0}; - message[0] = 0xcc; - message[1] = 0xdd; + uint8_t key[16] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x11, 0x22, 0x33, + 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0x50}; + uint8_t message[AES_BLOCK_SIZE] = {0x50, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, + 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99}; // Allocate buffer to store the encrypted message uint8_t encrypted_message[AES_BLOCK_SIZE]; @@ -286,7 +284,7 @@ TEST(EndianTest, AES) { AES_encrypt(message, encrypted_message, &aes_key); const uint8_t known_value_bytes[AES_BLOCK_SIZE] = { - 0xf6, 0x8a, 0x88, 0x76, 0x05, 0x23, 0xd4, 0x14, 0x7e, 0x5a, 0xb8, 0x52, 0x8f, 0x56, 0x62, 0x3e + 0x5e, 0x3e, 0x8e, 0x76, 0xf4, 0xf2, 0x7d, 0x41, 0x35, 0x86, 0x96, 0xb5, 0x57, 0x2d, 0xd5, 0xc6 }; EXPECT_EQ(Bytes(known_value_bytes), Bytes(encrypted_message)); } diff --git a/crypto/fipsmodule/aes/aes_nohw.c b/crypto/fipsmodule/aes/aes_nohw.c index eb5445b536..5ed3ca89cf 100644 --- a/crypto/fipsmodule/aes/aes_nohw.c +++ b/crypto/fipsmodule/aes/aes_nohw.c @@ -349,15 +349,27 @@ static inline void aes_nohw_compact_block(aes_word_t out[AES_NOHW_BLOCK_WORDS], #if defined(OPENSSL_SSE2) // No conversions needed. #elif defined(OPENSSL_64_BIT) +#if defined(OPENSSL_BIG_ENDIAN) + uint64_t a0 = aes_nohw_compact_word(CRYPTO_load_u64_le(&out[0])); + uint64_t a1 = aes_nohw_compact_word(CRYPTO_load_u64_le(&out[1])); +#else uint64_t a0 = aes_nohw_compact_word(out[0]); uint64_t a1 = aes_nohw_compact_word(out[1]); +#endif out[0] = (a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32); out[1] = (a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32); +#else +#if defined(OPENSSL_BIG_ENDIAN) + uint32_t a0 = aes_nohw_compact_word(CRYPTO_load_u32_le(&out[0])); + uint32_t a1 = aes_nohw_compact_word(CRYPTO_load_u32_le(&out[1])); + uint32_t a2 = aes_nohw_compact_word(CRYPTO_load_u32_le(&out[2])); + uint32_t a3 = aes_nohw_compact_word(CRYPTO_load_u32_le(&out[3])); #else uint32_t a0 = aes_nohw_compact_word(out[0]); uint32_t a1 = aes_nohw_compact_word(out[1]); uint32_t a2 = aes_nohw_compact_word(out[2]); uint32_t a3 = aes_nohw_compact_word(out[3]); +#endif // Note clang, when building for ARM Thumb2, will sometimes miscompile // expressions such as (a0 & 0x0000ff00) << 8, particularly when building // without optimizations. This bug was introduced in @@ -381,8 +393,8 @@ static inline void aes_nohw_uncompact_block( aes_nohw_uncompact_word((a0 & UINT64_C(0x00000000ffffffff)) | (a1 << 32)); uint64_t b1 = aes_nohw_uncompact_word((a1 & UINT64_C(0xffffffff00000000)) | (a0 >> 32)); - memcpy(out, &b0, 8); - memcpy(out + 8, &b1, 8); + CRYPTO_store_u64_le(&out[0], b0); + CRYPTO_store_u64_le(&out[8], b1); #else uint32_t a0 = in[0]; uint32_t a1 = in[1]; @@ -403,10 +415,10 @@ static inline void aes_nohw_uncompact_block( b1 = aes_nohw_uncompact_word(b1); b2 = aes_nohw_uncompact_word(b2); b3 = aes_nohw_uncompact_word(b3); - memcpy(out, &b0, 4); - memcpy(out + 4, &b1, 4); - memcpy(out + 8, &b2, 4); - memcpy(out + 12, &b3, 4); + CRYPTO_store_u32_le(&out[0], b0); + CRYPTO_store_u32_le(&out[4], b1); + CRYPTO_store_u32_le(&out[8], b2); + CRYPTO_store_u32_le(&out[12], b3); #endif } diff --git a/crypto/fipsmodule/cipher/aead.c b/crypto/fipsmodule/cipher/aead.c index 7f212d9759..1cb666f337 100644 --- a/crypto/fipsmodule/cipher/aead.c +++ b/crypto/fipsmodule/cipher/aead.c @@ -296,8 +296,8 @@ int EVP_AEAD_get_iv_from_ipv4_nanosecs( return 0; } - OPENSSL_memcpy(out_iv, &ipv4_address, sizeof(ipv4_address)); - OPENSSL_memcpy(out_iv + sizeof(ipv4_address), &nanosecs, sizeof(nanosecs)); + CRYPTO_store_u32_le(&out_iv[0], ipv4_address); + CRYPTO_store_u64_le(&out_iv[sizeof(ipv4_address)], nanosecs); return 1; } diff --git a/crypto/fipsmodule/modes/xts.c b/crypto/fipsmodule/modes/xts.c index 235ccd3f7f..f72dccadb3 100644 --- a/crypto/fipsmodule/modes/xts.c +++ b/crypto/fipsmodule/modes/xts.c @@ -62,7 +62,6 @@ size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, uint8_t *out, size_t len, int enc) { union { uint64_t u[2]; - uint32_t d[4]; uint8_t c[16]; } tweak, scratch; unsigned int i; @@ -91,10 +90,22 @@ size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, unsigned int carry, res; - res = 0x87 & (((int)tweak.d[3]) >> 31); +#if defined(OPENSSL_BIG_ENDIAN) + uint64_t tweak_u0, tweak_u1; + tweak_u0 = CRYPTO_load_u64_le(&tweak.u[0]); + tweak_u1 = CRYPTO_load_u64_le(&tweak.u[1]); + res = 0x87 & (((int64_t)tweak_u1) >> 63); + carry = (unsigned int)(tweak_u0 >> 63); + tweak_u0 = (tweak_u0 << 1) ^ res; + tweak_u1 = (tweak_u1 << 1) | carry; + CRYPTO_store_u64_le(&tweak.u[0], tweak_u0); + CRYPTO_store_u64_le(&tweak.u[1], tweak_u1); +#else + res = 0x87 & (((int64_t)tweak.u[1]) >> 63); carry = (unsigned int)(tweak.u[0] >> 63); tweak.u[0] = (tweak.u[0] << 1) ^ res; tweak.u[1] = (tweak.u[1] << 1) | carry; +#endif } if (enc) { for (i = 0; i < len; ++i) { @@ -116,10 +127,22 @@ size_t CRYPTO_xts128_encrypt(const XTS128_CONTEXT *ctx, unsigned int carry, res; - res = 0x87 & (((int)tweak.d[3]) >> 31); +#if defined(OPENSSL_BIG_ENDIAN) + uint64_t tweak_u0, tweak_u1; + tweak_u0 = CRYPTO_load_u64_le(&tweak.u[0]); + tweak_u1 = CRYPTO_load_u64_le(&tweak.u[1]); + res = 0x87 & (((int64_t)tweak_u1) >> 63); + carry = (unsigned int)(tweak_u0 >> 63); + tweak_u0 = (tweak_u0 << 1) ^ res; + tweak_u1 = (tweak_u1 << 1) | carry; + CRYPTO_store_u64_le(&tweak1.u[0], tweak_u0); + CRYPTO_store_u64_le(&tweak1.u[1], tweak_u1); +#else + res = 0x87 & (((int64_t)tweak.u[1]) >> 63); carry = (unsigned int)(tweak.u[0] >> 63); tweak1.u[0] = (tweak.u[0] << 1) ^ res; tweak1.u[1] = (tweak.u[1] << 1) | carry; +#endif OPENSSL_memcpy(scratch.c, inp, 16); scratch.u[0] ^= tweak1.u[0]; scratch.u[1] ^= tweak1.u[1]; diff --git a/include/openssl/aead.h b/include/openssl/aead.h index 9d1e2edfa3..13005c3d73 100644 --- a/include/openssl/aead.h +++ b/include/openssl/aead.h @@ -466,8 +466,8 @@ OPENSSL_EXPORT int EVP_AEAD_CTX_tag_len(const EVP_AEAD_CTX *ctx, // EVP_AEAD_get_iv_from_ipv4_nanosecs computes a deterministic IV compliant with // NIST SP 800-38D, built from an IPv4 address and the number of nanoseconds -// since boot, writing it to |out_iv|. It returns one on success or zero for -// error. +// since boot, writing it to |out_iv| (in little endian). +// It returns one on success or zero for error. // // This is not a general-purpose API, you should not be using it unless you // specifically know you need to use this.