summaryrefslogtreecommitdiff
path: root/providers
diff options
context:
space:
mode:
authorTodd Short <todd.short@me.com>2022-07-31 21:24:13 -0400
committerTomas Mraz <tomas@openssl.org>2022-08-01 10:23:57 +0200
commit6f74677911de87f3271721073bd360806a93733f (patch)
treee7f200219bf1681a31519bf3bfdf808f288f2616 /providers
parent76ad9ae6fa459af0bd804c01d3d681ec02cddb4b (diff)
downloadopenssl-new-6f74677911de87f3271721073bd360806a93733f.tar.gz
Fix AES-GCM-SIV endian issues
Fixes #18911 `BSWAP`x/`GETU`xx are no-ops on big-endian. Change the byte swapper. Fix big-endian issues in the `mulx_ghash()` function Reviewed-by: Matt Caswell <matt@openssl.org> Reviewed-by: Tomas Mraz <tomas@openssl.org> (Merged from https://github.com/openssl/openssl/pull/18920)
Diffstat (limited to 'providers')
-rw-r--r--providers/implementations/ciphers/cipher_aes_gcm_siv.h24
-rw-r--r--providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c16
-rw-r--r--providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c27
3 files changed, 38 insertions, 29 deletions
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv.h b/providers/implementations/ciphers/cipher_aes_gcm_siv.h
index 1224512e3a..37d1e3326b 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_siv.h
+++ b/providers/implementations/ciphers/cipher_aes_gcm_siv.h
@@ -58,21 +58,19 @@ const PROV_CIPHER_HW_AES_GCM_SIV *ossl_prov_cipher_hw_aes_gcm_siv(size_t keybits
void ossl_polyval_ghash_init(u128 Htable[16], const uint64_t H[2]);
void ossl_polyval_ghash_hash(const u128 Htable[16], uint8_t *tag, const uint8_t *inp, size_t len);
-/* Define our own BSWAP8/BSWAP4, if not already defined */
-#ifndef BSWAP8
-static ossl_inline uint64_t BSWAP8(uint64_t n)
+/* Define GSWAP8/GSWAP4 - used for BOTH little and big endian architectures */
+static ossl_inline uint32_t GSWAP4(uint32_t n)
{
- uint8_t *p = (uint8_t *)&n;
-
- return (uint64_t)GETU32(p) << 32 | GETU32(p + 4);
+ return (((n & 0x000000FF) << 24)
+ | ((n & 0x0000FF00) << 8)
+ | ((n & 0x00FF0000) >> 8)
+ | ((n & 0xFF000000) >> 24));
}
-#endif
-
-#ifndef BSWAP4
-static ossl_inline uint32_t BSWAP4(uint32_t n)
+static ossl_inline uint64_t GSWAP8(uint64_t n)
{
- uint8_t *p = (uint8_t *)&n;
+ uint64_t result;
- return GETU32(p);
+ result = GSWAP4(n & 0x0FFFFFFFF);
+ result <<= 32;
+ return result | GSWAP4(n >> 32);
}
-#endif
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
index 9ee5c32f4f..9887e1c3a4 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_hw.c
@@ -64,7 +64,7 @@ static int aes_gcm_siv_initkey(void *vctx)
if (IS_LITTLE_ENDIAN) {
data.counter = counter;
} else {
- data.counter = BSWAP4(counter);
+ data.counter = GSWAP4(counter);
}
/* Block size is 16 (128 bits), but only 8 bytes are used */
out_len = BLOCK_SIZE;
@@ -79,7 +79,7 @@ static int aes_gcm_siv_initkey(void *vctx)
if (IS_LITTLE_ENDIAN) {
data.counter = counter;
} else {
- data.counter = BSWAP4(counter);
+ data.counter = GSWAP4(counter);
}
/* Block size is 16 bytes (128 bits), but only 8 bytes are used */
out_len = BLOCK_SIZE;
@@ -169,8 +169,8 @@ static int aes_gcm_siv_encrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *i
len_blk[0] = (uint64_t)ctx->aad_len * 8;
len_blk[1] = (uint64_t)len * 8;
} else {
- len_blk[0] = BSWAP8((uint64_t)ctx->aad_len * 8);
- len_blk[1] = BSWAP8((uint64_t)len * 8);
+ len_blk[0] = GSWAP8((uint64_t)ctx->aad_len * 8);
+ len_blk[1] = GSWAP8((uint64_t)len * 8);
}
memset(S_s, 0, TAG_SIZE);
ossl_polyval_ghash_init(ctx->Htable, (const uint64_t*)ctx->msg_auth_key);
@@ -235,8 +235,8 @@ static int aes_gcm_siv_decrypt(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *i
len_blk[0] = (uint64_t)ctx->aad_len * 8;
len_blk[1] = (uint64_t)len * 8;
} else {
- len_blk[0] = BSWAP8((uint64_t)ctx->aad_len * 8);
- len_blk[1] = BSWAP8((uint64_t)len * 8);
+ len_blk[0] = GSWAP8((uint64_t)ctx->aad_len * 8);
+ len_blk[1] = GSWAP8((uint64_t)len * 8);
}
memset(S_s, 0, TAG_SIZE);
ossl_polyval_ghash_init(ctx->Htable, (const uint64_t*)ctx->msg_auth_key);
@@ -350,7 +350,7 @@ static int aes_gcm_siv_ctr32(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *ini
memcpy(&block, init_counter, sizeof(block));
if (IS_BIG_ENDIAN) {
- counter = BSWAP4(block.x32[0]);
+ counter = GSWAP4(block.x32[0]);
}
for (i = 0; i < len; i += sizeof(block)) {
@@ -360,7 +360,7 @@ static int aes_gcm_siv_ctr32(PROV_AES_GCM_SIV_CTX *ctx, const unsigned char *ini
block.x32[0]++;
} else {
counter++;
- block.x32[0] = BSWAP4(counter);
+ block.x32[0] = GSWAP4(counter);
}
todo = len - i;
if (todo > sizeof(keystream))
diff --git a/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c
index 66f6ed457e..4d147f3bc4 100644
--- a/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c
+++ b/providers/implementations/ciphers/cipher_aes_gcm_siv_polyval.c
@@ -22,22 +22,33 @@
static ossl_inline void mulx_ghash(uint64_t *a)
{
uint64_t t[2], mask;
+ DECLARE_IS_ENDIAN;
- t[0] = BSWAP8(a[0]);
- t[1] = BSWAP8(a[1]);
+ if (IS_LITTLE_ENDIAN) {
+ t[0] = GSWAP8(a[0]);
+ t[1] = GSWAP8(a[1]);
+ } else {
+ t[0] = a[0];
+ t[1] = a[1];
+ }
mask = -(int64_t)(t[1] & 1) & 0xe1;
mask <<= 56;
- a[1] = BSWAP8((t[1] >> 1) ^ (t[0] << 63));
- a[0] = BSWAP8((t[0] >> 1) ^ mask);
+ if (IS_LITTLE_ENDIAN) {
+ a[1] = GSWAP8((t[1] >> 1) ^ (t[0] << 63));
+ a[0] = GSWAP8((t[0] >> 1) ^ mask);
+ } else {
+ a[1] = (t[1] >> 1) ^ (t[0] << 63);
+ a[0] = (t[0] >> 1) ^ mask;
+ }
}
#define aligned64(p) (((uintptr_t)p & 0x07) == 0)
static ossl_inline void byte_reverse16(uint8_t *out, const uint8_t *in)
{
if (aligned64(out) && aligned64(in)) {
- ((uint64_t *)out)[0] = BSWAP8(((uint64_t *)in)[1]);
- ((uint64_t *)out)[1] = BSWAP8(((uint64_t *)in)[0]);
+ ((uint64_t *)out)[0] = GSWAP8(((uint64_t *)in)[1]);
+ ((uint64_t *)out)[1] = GSWAP8(((uint64_t *)in)[0]);
} else {
int i;
@@ -56,8 +67,8 @@ void ossl_polyval_ghash_init(u128 Htable[16], const uint64_t H[2])
mulx_ghash(tmp);
if (IS_LITTLE_ENDIAN) {
/* "H is stored in host byte order" */
- tmp[0] = BSWAP8(tmp[0]);
- tmp[1] = BSWAP8(tmp[1]);
+ tmp[0] = GSWAP8(tmp[0]);
+ tmp[1] = GSWAP8(tmp[1]);
}
ossl_gcm_init_4bit(Htable, (u64*)tmp);