From 345c99b6654b8313c792d54f829943068911ddbd Mon Sep 17 00:00:00 2001 From: Danny Tsen Date: Thu, 27 Jan 2022 18:49:59 -0600 Subject: [PATCH] Fixed counter overflow Reviewed-by: Tomas Mraz Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/17607) --- crypto/evp/e_aes.c | 101 +++++++++++++++++++++++++++++++++++++--- crypto/modes/asm/aes-gcm-ppc.pl | 1 2 files changed, 94 insertions(+), 8 deletions(-) --- a/crypto/evp/e_aes.c +++ b/crypto/evp/e_aes.c @@ -181,16 +181,103 @@ static void ctr64_inc(unsigned char *cou # define PPC_AES_GCM_CAPABLE (OPENSSL_ppccap_P & PPC_MADD300) # define AES_GCM_ENC_BYTES 128 # define AES_GCM_DEC_BYTES 128 -size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, - const void *key, unsigned char ivec[16], u64 *Xi); -void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); # if PPC_AES_GCM_CAPABLE -# define AES_gcm_encrypt ppc_aes_gcm_encrypt -# define AES_gcm_decrypt ppc_aes_gcm_decrypt +size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, unsigned char ivec[16], + u64 *Xi); +size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, + size_t len, const void *key, unsigned char ivec[16], + u64 *Xi); +size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], u64 *Xi); +size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out, + size_t len, const void *key, + unsigned char ivec[16], u64 *Xi); +# define AES_gcm_encrypt ppc_aes_gcm_encrypt_wrap +# define AES_gcm_decrypt ppc_aes_gcm_decrypt_wrap # define AES_GCM_ASM(gctx) ((gctx)->ctr==aes_p8_ctr32_encrypt_blocks && \ (gctx)->gcm.ghash==gcm_ghash_p8) +void gcm_ghash_p8(u64 Xi[2],const u128 Htable[16],const u8 *inp, size_t len); + +extern size_t ppc_aes_gcm_encrypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); +extern size_t ppc_aes_gcm_decrypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi); + +static inline u32 UTO32(unsigned char *buf) +{ + return ((u32) buf[0] << 24) | ((u32) buf[1] << 16) | ((u32) buf[2] << 8) | ((u32) buf[3]); +} + +static inline u32 add32TOU(unsigned char buf[4], u32 n) +{ + u32 r; + + r = UTO32(buf); + r += n; + buf[0] = (unsigned char) (r >> 24) & 0xFF; + buf[1] = (unsigned char) (r >> 16) & 0xFF; + buf[2] = (unsigned char) (r >> 8) & 0xFF; + buf[3] = (unsigned char) r & 0xFF; + return r; +} + +static size_t aes_p10_gcm_crypt(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi, int encrypt) +{ + int s = 0; + int ndone = 0; + int ctr_reset = 0; + u64 blocks_unused; + u64 nb = len / 16; + u64 next_ctr = 0; + unsigned char ctr_saved[12]; + + memcpy(ctr_saved, ivec, 12); + + while (nb) { + blocks_unused = (u64) 0xffffffffU + 1 - (u64) UTO32 (ivec + 12); + if (nb > blocks_unused) { + len = blocks_unused * 16; + nb -= blocks_unused; + next_ctr = blocks_unused; + ctr_reset = 1; + } else { + len = nb * 16; + next_ctr = nb; + nb = 0; + } + + s = encrypt ? ppc_aes_gcm_encrypt(in, out, len, key, ivec, Xi) + : ppc_aes_gcm_decrypt(in, out, len, key, ivec, Xi); + + /* add counter to ivec */ + add32TOU(ivec + 12, (u32) next_ctr); + if (ctr_reset) { + ctr_reset = 0; + in += len; + out += len; + } + memcpy(ivec, ctr_saved, 12); + ndone += s; + } + + return ndone; +} + +size_t ppc_aes_gcm_encrypt_wrap(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi) +{ + return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 1); +} + +size_t ppc_aes_gcm_decrypt_wrap(const unsigned char *in, unsigned char *out, size_t len, + const void *key, unsigned char ivec[16], u64 *Xi) +{ + return aes_p10_gcm_crypt(in, out, len, key, ivec, Xi, 0); +} + # endif #endif --- a/crypto/modes/asm/aes-gcm-ppc.pl +++ b/crypto/modes/asm/aes-gcm-ppc.pl @@ -81,7 +81,6 @@ open STDOUT,"| $^X $xlate $flavour \"$ou $code=<<___; .machine "any" -.abiversion 2 .text # 4x loops