Skip to contentSkip to conversation

Refactor AES Instructions

PATCH In review Tom Musta 3 participants 12 messages Mar 13, 2014 – May 8, 2014

lore
Share & tools
lore

Tom Musta

author
#0 lore raw

v2 cover Refactor AES Instructions

This patch series addresses concerns raised by Richard Henderson regarding redundant copies of Advanced Encryption Standard (AES) data and code (see
http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg04391.html).

The patches declare commonly used AES tables in the include/qemu/aes.h header file and define the tables in util/aes.c, thus eliminating redundant copies.

Minor refactorization of the i386 and ARM instruction models are made to utilize this common support. The newly added PowerPC instructions are completely rewritten and look much more like the i386 equivalents; a substantial amount of code is eliminated.

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Tom Musta (6):
util: Add S-Box and InvS-Box Arrays to Common AES Utils
util: Add AES ShiftRows and InvShiftRows Tables
util: Add InvMixColumns
target-i386: Use Common ShiftRows and InvShiftRows Tables
target-arm: Use Common Tables in AES Instructions
target-ppc: Refactor AES Instructions

 include/qemu/aes.h         |   14 ++
 target-arm/crypto_helper.c |   79 +----------
 target-i386/ops_sse.h      |   32 ++---
 target-ppc/int_helper.c    |  292 +++++--------------------------------
 util/aes.c                 |  343 ++++++++++++++++++++++++++++++++++++++++++++
 5 files changed, 412 insertions(+), 348 deletions(-)
author
#1 lore raw

PATCH v2 1/6 util: Add S-Box and InvS-Box Arrays to Common AES Utils

This patch adds tables for the S-Box and InvS-Box transformations commonly used by various Advanced Encription Standard (AES) instruction models.

---
 include/qemu/aes.h |    3 ++
 util/aes.c         |   70 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 73 insertions(+), 0 deletions(-)
include/qemu/aes.h +3 -0
index e79c707..a4044f5 100644
@@ -23,6 +23,9 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
 		     const unsigned long length, const AES_KEY *key,
 		     unsigned char *ivec, const int enc);
 
+extern const uint8_t AES_sbox[256];
+extern const uint8_t AES_isbox[256];
+
 /*
 AES_Te0[x] = S [x].[02, 01, 01, 03];
 AES_Te1[x] = S [x].[03, 02, 01, 01];
util/aes.c +70 -0

76 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#2 lore raw

PATCH v2 2/6 util: Add AES ShiftRows and InvShiftRows Tables

In reply to Tom Musta

This patch adds tables that implement the Advanced Encryption Standard (AES) ShiftRows and InvShiftRows transformations. These are commonly used in instruction models.

---
 include/qemu/aes.h |    4 ++++
 util/aes.c         |    8 ++++++++
 2 files changed, 12 insertions(+), 0 deletions(-)
include/qemu/aes.h +4 -0
index a4044f5..c45bc57 100644
@@ -26,6 +26,10 @@ void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
 extern const uint8_t AES_sbox[256];
 extern const uint8_t AES_isbox[256];
 
+/* AES ShiftRows and InvShiftRows */
+extern const uint8_t AES_shifts[16];
+extern const uint8_t AES_ishifts[16];
+
 /*
 AES_Te0[x] = S [x].[02, 01, 01, 03];
 AES_Te1[x] = S [x].[03, 02, 01, 01];
util/aes.c +8 -0
index eeb644b..c26cf55 100644
@@ -108,6 +108,14 @@ const uint8_t AES_isbox[256] = {
     0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D,
 };
 
+const uint8_t AES_shifts[16] = {
+    0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
+};
+
+const uint8_t AES_ishifts[16] = {
+    0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
+};
+
 /*
 AES_Te0[x] = S [x].[02, 01, 01, 03];
 AES_Te1[x] = S [x].[03, 02, 01, 01];
Signature · 1 line
1.7.1
author
#3 lore raw

PATCH v2 3/6 util: Add InvMixColumns

In reply to Tom Musta

This patch adds the table implementation of the Advanced Encryption Standard (AES) InvMixColumns transformation.

The patch is intentionally asymmetrical -- the MixColumns table is not added because there is no known use for it at this time.

---
 include/qemu/aes.h |    7 ++
 util/aes.c         |  265 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 272 insertions(+), 0 deletions(-)
include/qemu/aes.h +7 -0
index c45bc57..c106660 100644
@@ -30,6 +30,13 @@ extern const uint8_t AES_isbox[256];
 extern const uint8_t AES_shifts[16];
 extern const uint8_t AES_ishifts[16];
 
+/* AES InvMixColumns */
+/* AES_imc[x][0] = [x].[0e, 09, 0d, 0b]; */
+/* AES_imc[x][1] = [x].[0b, 0e, 09, 0d]; */
+/* AES_imc[x][2] = [x].[0d, 0b, 0e, 09]; */
+/* AES_imc[x][3] = [x].[09, 0d, 0b, 0e]; */
+extern const uint32_t AES_imc[256][4];
+
 /*
 AES_Te0[x] = S [x].[02, 01, 01, 03];
 AES_Te1[x] = S [x].[03, 02, 01, 01];
util/aes.c +265 -0

271 lines not on this page · raw message

Signature · 1 line
1.7.1
author
#4 lore raw

PATCH v2 4/6 target-i386: Use Common ShiftRows and InvShiftRows Tables

In reply to Tom Musta

This patch eliminates the (now) redundant copy of the Advanced Encryption Standard (AES) ShiftRows and InvShiftRows tables; the code is updated to use the common tables declared in include/qemu/aes.h.

---
 target-i386/ops_sse.h |   32 +++++++++++++-------------------
 1 files changed, 13 insertions(+), 19 deletions(-)
target-i386/ops_sse.h +13 -19
index eb24b5f..886e0a8 100644
@@ -17,6 +17,9 @@
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  */
+
+#include "qemu/aes.h"
+
 #if SHIFT == 0
 #define Reg MMXReg
 #define XMM_ONLY(...)
@@ -2204,15 +2207,6 @@ void glue(helper_pclmulqdq, SUFFIX)(CPUX86State *env, Reg *d, Reg *s,
     d->Q(1) = resh;
 }
 
-/* AES-NI op helpers */
-static const uint8_t aes_shifts[16] = {
-    0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, 1, 6, 11
-};
-
-static const uint8_t aes_ishifts[16] = {
-    0, 13, 10, 7, 4, 1, 14, 11, 8, 5, 2, 15, 12, 9, 6, 3
-};
-
 void glue(helper_aesdec, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
 {
     int i;
@@ -2220,10 +2214,10 @@ void glue(helper_aesdec, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
     Reg rk = *s;
 
     for (i = 0 ; i < 4 ; i++) {
-        d->L(i) = rk.L(i) ^ bswap32(AES_Td0[st.B(aes_ishifts[4*i+0])] ^
-                                    AES_Td1[st.B(aes_ishifts[4*i+1])] ^
-                                    AES_Td2[st.B(aes_ishifts[4*i+2])] ^
-                                    AES_Td3[st.B(aes_ishifts[4*i+3])]);
+        d->L(i) = rk.L(i) ^ bswap32(AES_Td0[st.B(AES_ishifts[4*i+0])] ^
+                                    AES_Td1[st.B(AES_ishifts[4*i+1])] ^
+                                    AES_Td2[st.B(AES_ishifts[4*i+2])] ^
+                                    AES_Td3[st.B(AES_ishifts[4*i+3])]);
     }
 }
 
@@ -2234,7 +2228,7 @@ void glue(helper_aesdeclast, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
     Reg rk = *s;
 
     for (i = 0; i < 16; i++) {
-        d->B(i) = rk.B(i) ^ (AES_Td4[st.B(aes_ishifts[i])] & 0xff);
+        d->B(i) = rk.B(i) ^ (AES_Td4[st.B(AES_ishifts[i])] & 0xff);
     }
 }
 
@@ -2245,10 +2239,10 @@ void glue(helper_aesenc, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
     Reg rk = *s;
 
     for (i = 0 ; i < 4 ; i++) {
-        d->L(i) = rk.L(i) ^ bswap32(AES_Te0[st.B(aes_shifts[4*i+0])] ^
-                                    AES_Te1[st.B(aes_shifts[4*i+1])] ^
-                                    AES_Te2[st.B(aes_shifts[4*i+2])] ^
-                                    AES_Te3[st.B(aes_shifts[4*i+3])]);
+        d->L(i) = rk.L(i) ^ bswap32(AES_Te0[st.B(AES_shifts[4*i+0])] ^
+                                    AES_Te1[st.B(AES_shifts[4*i+1])] ^
+                                    AES_Te2[st.B(AES_shifts[4*i+2])] ^
+                                    AES_Te3[st.B(AES_shifts[4*i+3])]);
     }
 }
 
@@ -2259,7 +2253,7 @@ void glue(helper_aesenclast, SUFFIX)(CPUX86State *env, Reg *d, Reg *s)
     Reg rk = *s;
 
     for (i = 0; i < 16; i++) {
-        d->B(i) = rk.B(i) ^ (AES_Te4[st.B(aes_shifts[i])] & 0xff);
+        d->B(i) = rk.B(i) ^ (AES_Te4[st.B(AES_shifts[i])] & 0xff);
     }
 
 }
Signature · 1 line
1.7.1
author
#5 lore raw

PATCH v2 5/6 target-arm: Use Common Tables in AES Instructions

In reply to Tom Musta

This patch refactors the ARM cryptographic instructions to use the (newly) added common tables from include/qemu/aes.h.

---
V2: corrected sbox definition to be constant pointer to constant per Richard Henderson's review.

 target-arm/crypto_helper.c |   79 ++-----------------------------------------
 1 files changed, 4 insertions(+), 75 deletions(-)
target-arm/crypto_helper.c +4 -75
index f94be69..31bda2b 100644
@@ -14,6 +14,7 @@
 #include "cpu.h"
 #include "exec/exec-all.h"
 #include "helper.h"
+#include "qemu/aes.h"
 
 union AES_STATE {
     uint8_t    bytes[16];
@@ -24,81 +25,9 @@ union AES_STATE {
 void HELPER(crypto_aese)(CPUARMState *env, uint32_t rd, uint32_t rm,
                          uint32_t decrypt)
 {
-    static uint8_t const sbox[][256] = { {
-        /* S-box for encryption */
-        0x63, 0x7c, 0x77, 0x7b, 0xf2, 0x6b, 0x6f, 0xc5,
-        0x30, 0x01, 0x67, 0x2b, 0xfe, 0xd7, 0xab, 0x76,
-        0xca, 0x82, 0xc9, 0x7d, 0xfa, 0x59, 0x47, 0xf0,
-        0xad, 0xd4, 0xa2, 0xaf, 0x9c, 0xa4, 0x72, 0xc0,
-        0xb7, 0xfd, 0x93, 0x26, 0x36, 0x3f, 0xf7, 0xcc,
-        0x34, 0xa5, 0xe5, 0xf1, 0x71, 0xd8, 0x31, 0x15,
-        0x04, 0xc7, 0x23, 0xc3, 0x18, 0x96, 0x05, 0x9a,
-        0x07, 0x12, 0x80, 0xe2, 0xeb, 0x27, 0xb2, 0x75,
-        0x09, 0x83, 0x2c, 0x1a, 0x1b, 0x6e, 0x5a, 0xa0,
-        0x52, 0x3b, 0xd6, 0xb3, 0x29, 0xe3, 0x2f, 0x84,
-        0x53, 0xd1, 0x00, 0xed, 0x20, 0xfc, 0xb1, 0x5b,
-        0x6a, 0xcb, 0xbe, 0x39, 0x4a, 0x4c, 0x58, 0xcf,
-        0xd0, 0xef, 0xaa, 0xfb, 0x43, 0x4d, 0x33, 0x85,
-        0x45, 0xf9, 0x02, 0x7f, 0x50, 0x3c, 0x9f, 0xa8,
-        0x51, 0xa3, 0x40, 0x8f, 0x92, 0x9d, 0x38, 0xf5,
-        0xbc, 0xb6, 0xda, 0x21, 0x10, 0xff, 0xf3, 0xd2,
-        0xcd, 0x0c, 0x13, 0xec, 0x5f, 0x97, 0x44, 0x17,
-        0xc4, 0xa7, 0x7e, 0x3d, 0x64, 0x5d, 0x19, 0x73,
-        0x60, 0x81, 0x4f, 0xdc, 0x22, 0x2a, 0x90, 0x88,
-        0x46, 0xee, 0xb8, 0x14, 0xde, 0x5e, 0x0b, 0xdb,
-        0xe0, 0x32, 0x3a, 0x0a, 0x49, 0x06, 0x24, 0x5c,
-        0xc2, 0xd3, 0xac, 0x62, 0x91, 0x95, 0xe4, 0x79,
-        0xe7, 0xc8, 0x37, 0x6d, 0x8d, 0xd5, 0x4e, 0xa9,
-        0x6c, 0x56, 0xf4, 0xea, 0x65, 0x7a, 0xae, 0x08,
-        0xba, 0x78, 0x25, 0x2e, 0x1c, 0xa6, 0xb4, 0xc6,
-        0xe8, 0xdd, 0x74, 0x1f, 0x4b, 0xbd, 0x8b, 0x8a,
-        0x70, 0x3e, 0xb5, 0x66, 0x48, 0x03, 0xf6, 0x0e,
-        0x61, 0x35, 0x57, 0xb9, 0x86, 0xc1, 0x1d, 0x9e,
-        0xe1, 0xf8, 0x98, 0x11, 0x69, 0xd9, 0x8e, 0x94,
-        0x9b, 0x1e, 0x87, 0xe9, 0xce, 0x55, 0x28, 0xdf,
-        0x8c, 0xa1, 0x89, 0x0d, 0xbf, 0xe6, 0x42, 0x68,
-        0x41, 0x99, 0x2d, 0x0f, 0xb0, 0x54, 0xbb, 0x16
-    }, {
-        /* S-box for decryption */
-        0x52, 0x09, 0x6a, 0xd5, 0x30, 0x36, 0xa5, 0x38,
-        0xbf, 0x40, 0xa3, 0x9e, 0x81, 0xf3, 0xd7, 0xfb,
-        0x7c, 0xe3, 0x39, 0x82, 0x9b, 0x2f, 0xff, 0x87,
-        0x34, 0x8e, 0x43, 0x44, 0xc4, 0xde, 0xe9, 0xcb,
-        0x54, 0x7b, 0x94, 0x32, 0xa6, 0xc2, 0x23, 0x3d,
-        0xee, 0x4c, 0x95, 0x0b, 0x42, 0xfa, 0xc3, 0x4e,
-        0x08, 0x2e, 0xa1, 0x66, 0x28, 0xd9, 0x24, 0xb2,
-        0x76, 0x5b, 0xa2, 0x49, 0x6d, 0x8b, 0xd1, 0x25,
-        0x72, 0xf8, 0xf6, 0x64, 0x86, 0x68, 0x98, 0x16,
-        0xd4, 0xa4, 0x5c, 0xcc, 0x5d, 0x65, 0xb6, 0x92,
-        0x6c, 0x70, 0x48, 0x50, 0xfd, 0xed, 0xb9, 0xda,
-        0x5e, 0x15, 0x46, 0x57, 0xa7, 0x8d, 0x9d, 0x84,
-        0x90, 0xd8, 0xab, 0x00, 0x8c, 0xbc, 0xd3, 0x0a,
-        0xf7, 0xe4, 0x58, 0x05, 0xb8, 0xb3, 0x45, 0x06,
-        0xd0, 0x2c, 0x1e, 0x8f, 0xca, 0x3f, 0x0f, 0x02,
-        0xc1, 0xaf, 0xbd, 0x03, 0x01, 0x13, 0x8a, 0x6b,
-        0x3a, 0x91, 0x11, 0x41, 0x4f, 0x67, 0xdc, 0xea,
-        0x97, 0xf2, 0xcf, 0xce, 0xf0, 0xb4, 0xe6, 0x73,
-        0x96, 0xac, 0x74, 0x22, 0xe7, 0xad, 0x35, 0x85,
-        0xe2, 0xf9, 0x37, 0xe8, 0x1c, 0x75, 0xdf, 0x6e,
-        0x47, 0xf1, 0x1a, 0x71, 0x1d, 0x29, 0xc5, 0x89,
-        0x6f, 0xb7, 0x62, 0x0e, 0xaa, 0x18, 0xbe, 0x1b,
-        0xfc, 0x56, 0x3e, 0x4b, 0xc6, 0xd2, 0x79, 0x20,
-        0x9a, 0xdb, 0xc0, 0xfe, 0x78, 0xcd, 0x5a, 0xf4,
-        0x1f, 0xdd, 0xa8, 0x33, 0x88, 0x07, 0xc7, 0x31,
-        0xb1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xec, 0x5f,
-        0x60, 0x51, 0x7f, 0xa9, 0x19, 0xb5, 0x4a, 0x0d,
-        0x2d, 0xe5, 0x7a, 0x9f, 0x93, 0xc9, 0x9c, 0xef,
-        0xa0, 0xe0, 0x3b, 0x4d, 0xae, 0x2a, 0xf5, 0xb0,
-        0xc8, 0xeb, 0xbb, 0x3c, 0x83, 0x53, 0x99, 0x61,
-        0x17, 0x2b, 0x04, 0x7e, 0xba, 0x77, 0xd6, 0x26,
-        0xe1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0c, 0x7d
-    } };
-    static uint8_t const shift[][16] = {
-        /* ShiftRows permutation vector for encryption */
-        { 0,  5, 10, 15, 4, 9, 14,  3, 8, 13, 2,  7, 12, 1, 6, 11 },
-        /* ShiftRows permutation vector for decryption */
-        { 0, 13, 10,  7, 4, 1, 14, 11, 8,  5, 2, 15, 12, 9, 6,  3 },
-    };
+    static uint8_t const * const sbox[2] = { AES_sbox, AES_isbox };
+    static uint8_t const * const shift[2] = { AES_shifts, AES_ishifts };
+
     union AES_STATE rk = { .l = {
         float64_val(env->vfp.regs[rm]),
         float64_val(env->vfp.regs[rm + 1])
Signature · 1 line
1.7.1
author
#6 lore raw

PATCH v2 6/6 target-ppc: Refactor AES Instructions

In reply to Tom Musta

This patch refactors the PowerPC Advanced Encryption Standard (AES) instructions to use the common AES tables (include/qemu/aes.h).

Specifically:
- vsbox is recoded to use the AES_sbox table.
- vcipher, vcipherlast and vncipherlast are all recoded to use the optimized AES_t[ed][0-4] tables.
- vncipher is recoded to use a combination of InvS-Box, InvShiftRows and InvMixColumns tables. It was not possible to use AES_Td[0-4] due to a slight difference in how PowerPC implements vncipher.

---
 target-ppc/int_helper.c |  292 ++++++----------------------------------------
 1 files changed, 38 insertions(+), 254 deletions(-)
target-ppc/int_helper.c +38 -254
index 63dde94..2c788e9 100644
@@ -19,6 +19,7 @@
 #include "cpu.h"
 #include "qemu/host-utils.h"
 #include "helper.h"
+#include "qemu/aes.h"
 
 #include "helper_regs.h"
 /*****************************************************************************/
@@ -396,9 +397,13 @@ target_ulong helper_602_mfrom(target_ulong arg)
 #if defined(HOST_WORDS_BIGENDIAN)
 #define HI_IDX 0
 #define LO_IDX 1
+#define AVRB(i) u8[i]
+#define AVRW(i) u32[i]
 #else
 #define HI_IDX 1
 #define LO_IDX 0
+#define AVRB(i) u8[15-(i)]
+#define AVRW(i) u32[3-(i)]
 #endif
 
 #if defined(HOST_WORDS_BIGENDIAN)
@@ -2338,284 +2343,63 @@ uint32_t helper_bcdsub(ppc_avr_t *r,  ppc_avr_t *a, ppc_avr_t *b, uint32_t ps)
     return helper_bcdadd(r, a, &bcopy, ps);
 }
 
-static uint8_t SBOX[256] = {
-0x63, 0x7C, 0x77, 0x7B, 0xF2, 0x6B, 0x6F, 0xC5,
-0x30, 0x01, 0x67, 0x2B, 0xFE, 0xD7, 0xAB, 0x76,
-0xCA, 0x82, 0xC9, 0x7D, 0xFA, 0x59, 0x47, 0xF0,
-0xAD, 0xD4, 0xA2, 0xAF, 0x9C, 0xA4, 0x72, 0xC0,
-0xB7, 0xFD, 0x93, 0x26, 0x36, 0x3F, 0xF7, 0xCC,
-0x34, 0xA5, 0xE5, 0xF1, 0x71, 0xD8, 0x31, 0x15,
-0x04, 0xC7, 0x23, 0xC3, 0x18, 0x96, 0x05, 0x9A,
-0x07, 0x12, 0x80, 0xE2, 0xEB, 0x27, 0xB2, 0x75,
-0x09, 0x83, 0x2C, 0x1A, 0x1B, 0x6E, 0x5A, 0xA0,
-0x52, 0x3B, 0xD6, 0xB3, 0x29, 0xE3, 0x2F, 0x84,
-0x53, 0xD1, 0x00, 0xED, 0x20, 0xFC, 0xB1, 0x5B,
-0x6A, 0xCB, 0xBE, 0x39, 0x4A, 0x4C, 0x58, 0xCF,
-0xD0, 0xEF, 0xAA, 0xFB, 0x43, 0x4D, 0x33, 0x85,
-0x45, 0xF9, 0x02, 0x7F, 0x50, 0x3C, 0x9F, 0xA8,
-0x51, 0xA3, 0x40, 0x8F, 0x92, 0x9D, 0x38, 0xF5,
-0xBC, 0xB6, 0xDA, 0x21, 0x10, 0xFF, 0xF3, 0xD2,
-0xCD, 0x0C, 0x13, 0xEC, 0x5F, 0x97, 0x44, 0x17,
-0xC4, 0xA7, 0x7E, 0x3D, 0x64, 0x5D, 0x19, 0x73,
-0x60, 0x81, 0x4F, 0xDC, 0x22, 0x2A, 0x90, 0x88,
-0x46, 0xEE, 0xB8, 0x14, 0xDE, 0x5E, 0x0B, 0xDB,
-0xE0, 0x32, 0x3A, 0x0A, 0x49, 0x06, 0x24, 0x5C,
-0xC2, 0xD3, 0xAC, 0x62, 0x91, 0x95, 0xE4, 0x79,
-0xE7, 0xC8, 0x37, 0x6D, 0x8D, 0xD5, 0x4E, 0xA9,
-0x6C, 0x56, 0xF4, 0xEA, 0x65, 0x7A, 0xAE, 0x08,
-0xBA, 0x78, 0x25, 0x2E, 0x1C, 0xA6, 0xB4, 0xC6,
-0xE8, 0xDD, 0x74, 0x1F, 0x4B, 0xBD, 0x8B, 0x8A,
-0x70, 0x3E, 0xB5, 0x66, 0x48, 0x03, 0xF6, 0x0E,
-0x61, 0x35, 0x57, 0xB9, 0x86, 0xC1, 0x1D, 0x9E,
-0xE1, 0xF8, 0x98, 0x11, 0x69, 0xD9, 0x8E, 0x94,
-0x9B, 0x1E, 0x87, 0xE9, 0xCE, 0x55, 0x28, 0xDF,
-0x8C, 0xA1, 0x89, 0x0D, 0xBF, 0xE6, 0x42, 0x68,
-0x41, 0x99, 0x2D, 0x0F, 0xB0, 0x54, 0xBB, 0x16,
-};
-
-static void SubBytes(ppc_avr_t *r, ppc_avr_t *a)
-{
-    int i;
-    VECTOR_FOR_INORDER_I(i, u8) {
-        r->u8[i] = SBOX[a->u8[i]];
-    }
-}
-
-static uint8_t InvSBOX[256] = {
-0x52, 0x09, 0x6A, 0xD5, 0x30, 0x36, 0xA5, 0x38,
-0xBF, 0x40, 0xA3, 0x9E, 0x81, 0xF3, 0xD7, 0xFB,
-0x7C, 0xE3, 0x39, 0x82, 0x9B, 0x2F, 0xFF, 0x87,
-0x34, 0x8E, 0x43, 0x44, 0xC4, 0xDE, 0xE9, 0xCB,
-0x54, 0x7B, 0x94, 0x32, 0xA6, 0xC2, 0x23, 0x3D,
-0xEE, 0x4C, 0x95, 0x0B, 0x42, 0xFA, 0xC3, 0x4E,
-0x08, 0x2E, 0xA1, 0x66, 0x28, 0xD9, 0x24, 0xB2,
-0x76, 0x5B, 0xA2, 0x49, 0x6D, 0x8B, 0xD1, 0x25,
-0x72, 0xF8, 0xF6, 0x64, 0x86, 0x68, 0x98, 0x16,
-0xD4, 0xA4, 0x5C, 0xCC, 0x5D, 0x65, 0xB6, 0x92,
-0x6C, 0x70, 0x48, 0x50, 0xFD, 0xED, 0xB9, 0xDA,
-0x5E, 0x15, 0x46, 0x57, 0xA7, 0x8D, 0x9D, 0x84,
-0x90, 0xD8, 0xAB, 0x00, 0x8C, 0xBC, 0xD3, 0x0A,
-0xF7, 0xE4, 0x58, 0x05, 0xB8, 0xB3, 0x45, 0x06,
-0xD0, 0x2C, 0x1E, 0x8F, 0xCA, 0x3F, 0x0F, 0x02,
-0xC1, 0xAF, 0xBD, 0x03, 0x01, 0x13, 0x8A, 0x6B,
-0x3A, 0x91, 0x11, 0x41, 0x4F, 0x67, 0xDC, 0xEA,
-0x97, 0xF2, 0xCF, 0xCE, 0xF0, 0xB4, 0xE6, 0x73,
-0x96, 0xAC, 0x74, 0x22, 0xE7, 0xAD, 0x35, 0x85,
-0xE2, 0xF9, 0x37, 0xE8, 0x1C, 0x75, 0xDF, 0x6E,
-0x47, 0xF1, 0x1A, 0x71, 0x1D, 0x29, 0xC5, 0x89,
-0x6F, 0xB7, 0x62, 0x0E, 0xAA, 0x18, 0xBE, 0x1B,
-0xFC, 0x56, 0x3E, 0x4B, 0xC6, 0xD2, 0x79, 0x20,
-0x9A, 0xDB, 0xC0, 0xFE, 0x78, 0xCD, 0x5A, 0xF4,
-0x1F, 0xDD, 0xA8, 0x33, 0x88, 0x07, 0xC7, 0x31,
-0xB1, 0x12, 0x10, 0x59, 0x27, 0x80, 0xEC, 0x5F,
-0x60, 0x51, 0x7F, 0xA9, 0x19, 0xB5, 0x4A, 0x0D,
-0x2D, 0xE5, 0x7A, 0x9F, 0x93, 0xC9, 0x9C, 0xEF,
-0xA0, 0xE0, 0x3B, 0x4D, 0xAE, 0x2A, 0xF5, 0xB0,
-0xC8, 0xEB, 0xBB, 0x3C, 0x83, 0x53, 0x99, 0x61,
-0x17, 0x2B, 0x04, 0x7E, 0xBA, 0x77, 0xD6, 0x26,
-0xE1, 0x69, 0x14, 0x63, 0x55, 0x21, 0x0C, 0x7D,
-};
-
-static void InvSubBytes(ppc_avr_t *r, ppc_avr_t *a)
+void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
 {
     int i;
     VECTOR_FOR_INORDER_I(i, u8) {
-        r->u8[i] = InvSBOX[a->u8[i]];
+        r->u8[i] = AES_sbox[a->u8[i]];
     }
 }
 
-static uint8_t ROTL8(uint8_t x, int n)
-{
-    return (x << n) | (x >> (8-n));
-}
-
-static inline int BIT8(uint8_t x, int n)
-{
-    return (x & (0x80 >> n)) != 0;
-}
-
-static uint8_t GFx02(uint8_t x)
-{
-    return ROTL8(x, 1) ^ (BIT8(x, 0) ? 0x1A : 0);
-}
-
-static uint8_t GFx03(uint8_t x)
-{
-    return x ^ ROTL8(x, 1) ^ (BIT8(x, 0) ? 0x1A : 0);
-}
-
-static uint8_t GFx09(uint8_t x)
-{
-    uint8_t term2 = ROTL8(x, 3);
-    uint8_t term3 = (BIT8(x, 0) ? 0x68 : 0) | (BIT8(x, 1) ? 0x14 : 0) |
-                    (BIT8(x, 2) ? 0x02 : 0);
-    uint8_t term4 = (BIT8(x, 1) ? 0x20 : 0) | (BIT8(x, 2) ? 0x18 : 0);
-    return x ^ term2 ^ term3 ^ term4;
-}
-
-static uint8_t GFx0B(uint8_t x)
-{
-    uint8_t term2 = ROTL8(x, 1);
-    uint8_t term3 = (x << 3) | (BIT8(x, 0) ? 0x06 : 0) |
-                    (BIT8(x, 2) ? 0x01 : 0);
-    uint8_t term4 = (BIT8(x, 0) ? 0x70 : 0) | (BIT8(x, 1) ? 0x06 : 0) |
-                    (BIT8(x, 2) ? 0x08 : 0);
-    uint8_t term5 = (BIT8(x, 1) ? 0x30 : 0) | (BIT8(x, 2) ? 0x02 : 0);
-    uint8_t term6 = BIT8(x, 2) ? 0x10 : 0;
-    return x ^ term2 ^ term3 ^ term4 ^ term5 ^ term6;
-}
-
-static uint8_t GFx0D(uint8_t x)
-{
-    uint8_t term2 = ROTL8(x, 2);
-    uint8_t term3 = (x << 3) | (BIT8(x, 1) ? 0x04 : 0) |
-                    (BIT8(x, 2) ? 0x03 : 0);
-    uint8_t term4 = (BIT8(x, 0) ? 0x58 : 0) | (BIT8(x, 1) ? 0x20 : 0);
-    uint8_t term5 = (BIT8(x, 1) ? 0x08 : 0) | (BIT8(x, 2) ? 0x10 : 0);
-    uint8_t term6 = BIT8(x, 2) ? 0x08 : 0;
-    return x ^ term2 ^ term3 ^ term4 ^ term5 ^ term6;
-}
-
-static uint8_t GFx0E(uint8_t x)
-{
-    uint8_t term1 = ROTL8(x, 1);
-    uint8_t term2 = (x << 2) | (BIT8(x, 2) ? 0x02 : 0) |
-                    (BIT8(x, 1) ? 0x01 : 0);
-    uint8_t term3 = (x << 3) | (BIT8(x, 1) ? 0x04 : 0) |
-                    (BIT8(x, 2) ? 0x01 : 0);
-    uint8_t term4 = (BIT8(x, 0) ? 0x40 : 0) | (BIT8(x, 1) ? 0x28 : 0) |
-                    (BIT8(x, 2) ? 0x10 : 0);
-    uint8_t term5 = (BIT8(x, 2) ? 0x08 : 0);
-    return term1 ^ term2 ^ term3 ^ term4 ^ term5;
-}
-
-#if defined(HOST_WORDS_BIGENDIAN)
-#define MCB(x, i, b) ((x)->u8[(i)*4 + (b)])
-#else
-#define MCB(x, i, b) ((x)->u8[15 - ((i)*4 + (b))])
-#endif
-
-static void MixColumns(ppc_avr_t *r, ppc_avr_t *x)
+void helper_vcipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
     int i;
-    for (i = 0; i < 4; i++) {
-        MCB(r, i, 0) = GFx02(MCB(x, i, 0)) ^ GFx03(MCB(x, i, 1)) ^
-                       MCB(x, i, 2) ^ MCB(x, i, 3);
-        MCB(r, i, 1) = MCB(x, i, 0) ^ GFx02(MCB(x, i, 1)) ^
-                       GFx03(MCB(x, i, 2)) ^ MCB(x, i, 3);
-        MCB(r, i, 2) = MCB(x, i, 0) ^ MCB(x, i, 1) ^
-                       GFx02(MCB(x, i, 2)) ^ GFx03(MCB(x, i, 3));
-        MCB(r, i, 3) = GFx03(MCB(x, i, 0)) ^ MCB(x, i, 1) ^
-                       MCB(x, i, 2) ^ GFx02(MCB(x, i, 3));
-    }
-}
 
-static void InvMixColumns(ppc_avr_t *r, ppc_avr_t *x)
-{
-    int i;
-    for (i = 0; i < 4; i++) {
-        MCB(r, i, 0) = GFx0E(MCB(x, i, 0)) ^ GFx0B(MCB(x, i, 1)) ^
-                       GFx0D(MCB(x, i, 2)) ^ GFx09(MCB(x, i, 3));
-        MCB(r, i, 1) = GFx09(MCB(x, i, 0)) ^ GFx0E(MCB(x, i, 1)) ^
-                       GFx0B(MCB(x, i, 2)) ^ GFx0D(MCB(x, i, 3));
-        MCB(r, i, 2) = GFx0D(MCB(x, i, 0)) ^ GFx09(MCB(x, i, 1)) ^
-                       GFx0E(MCB(x, i, 2)) ^ GFx0B(MCB(x, i, 3));
-        MCB(r, i, 3) = GFx0B(MCB(x, i, 0)) ^ GFx0D(MCB(x, i, 1)) ^
-                       GFx09(MCB(x, i, 2)) ^ GFx0E(MCB(x, i, 3));
+    VECTOR_FOR_INORDER_I(i, u32) {
+        r->AVRW(i) = b->AVRW(i) ^
+            (AES_Te0[a->AVRB(AES_shifts[4*i + 0])] ^
+             AES_Te1[a->AVRB(AES_shifts[4*i + 1])] ^
+             AES_Te2[a->AVRB(AES_shifts[4*i + 2])] ^
+             AES_Te3[a->AVRB(AES_shifts[4*i + 3])]);
     }
 }
 
-static void ShiftRows(ppc_avr_t *r, ppc_avr_t *x)
-{
-    MCB(r, 0, 0) = MCB(x, 0, 0);
-    MCB(r, 1, 0) = MCB(x, 1, 0);
-    MCB(r, 2, 0) = MCB(x, 2, 0);
-    MCB(r, 3, 0) = MCB(x, 3, 0);
-
-    MCB(r, 0, 1) = MCB(x, 1, 1);
-    MCB(r, 1, 1) = MCB(x, 2, 1);
-    MCB(r, 2, 1) = MCB(x, 3, 1);
-    MCB(r, 3, 1) = MCB(x, 0, 1);
-
-    MCB(r, 0, 2) = MCB(x, 2, 2);
-    MCB(r, 1, 2) = MCB(x, 3, 2);
-    MCB(r, 2, 2) = MCB(x, 0, 2);
-    MCB(r, 3, 2) = MCB(x, 1, 2);
-
-    MCB(r, 0, 3) = MCB(x, 3, 3);
-    MCB(r, 1, 3) = MCB(x, 0, 3);
-    MCB(r, 2, 3) = MCB(x, 1, 3);
-    MCB(r, 3, 3) = MCB(x, 2, 3);
-}
-
-static void InvShiftRows(ppc_avr_t *r, ppc_avr_t *x)
-{
-    MCB(r, 0, 0) = MCB(x, 0, 0);
-    MCB(r, 1, 0) = MCB(x, 1, 0);
-    MCB(r, 2, 0) = MCB(x, 2, 0);
-    MCB(r, 3, 0) = MCB(x, 3, 0);
-
-    MCB(r, 0, 1) = MCB(x, 3, 1);
-    MCB(r, 1, 1) = MCB(x, 0, 1);
-    MCB(r, 2, 1) = MCB(x, 1, 1);
-    MCB(r, 3, 1) = MCB(x, 2, 1);
-
-    MCB(r, 0, 2) = MCB(x, 2, 2);
-    MCB(r, 1, 2) = MCB(x, 3, 2);
-    MCB(r, 2, 2) = MCB(x, 0, 2);
-    MCB(r, 3, 2) = MCB(x, 1, 2);
-
-    MCB(r, 0, 3) = MCB(x, 1, 3);
-    MCB(r, 1, 3) = MCB(x, 2, 3);
-    MCB(r, 2, 3) = MCB(x, 3, 3);
-    MCB(r, 3, 3) = MCB(x, 0, 3);
-}
-
-#undef MCB
-
-void helper_vsbox(ppc_avr_t *r, ppc_avr_t *a)
-{
-    SubBytes(r, a);
-}
-
-void helper_vcipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
-{
-    ppc_avr_t vtemp1, vtemp2, vtemp3;
-    SubBytes(&vtemp1, a);
-    ShiftRows(&vtemp2, &vtemp1);
-    MixColumns(&vtemp3, &vtemp2);
-    r->u64[0] = vtemp3.u64[0] ^ b->u64[0];
-    r->u64[1] = vtemp3.u64[1] ^ b->u64[1];
-}
-
 void helper_vcipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
-    ppc_avr_t vtemp1, vtemp2;
-    SubBytes(&vtemp1, a);
-    ShiftRows(&vtemp2, &vtemp1);
-    r->u64[0] = vtemp2.u64[0] ^ b->u64[0];
-    r->u64[1] = vtemp2.u64[1] ^ b->u64[1];
+    int i;
+
+    VECTOR_FOR_INORDER_I(i, u8) {
+        r->AVRB(i) = b->AVRB(i) ^ (AES_Te4[a->AVRB(AES_shifts[i])] & 0xFF);
+    }
 }
 
 void helper_vncipher(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
     /* This differs from what is written in ISA V2.07.  The RTL is */
     /* incorrect and will be fixed in V2.07B.                      */
-    ppc_avr_t vtemp1, vtemp2, vtemp3;
-    InvShiftRows(&vtemp1, a);
-    InvSubBytes(&vtemp2, &vtemp1);
-    vtemp3.u64[0] = vtemp2.u64[0] ^ b->u64[0];
-    vtemp3.u64[1] = vtemp2.u64[1] ^ b->u64[1];
-    InvMixColumns(r, &vtemp3);
+    int i;
+    ppc_avr_t tmp;
+
+    VECTOR_FOR_INORDER_I(i, u8) {
+        tmp.AVRB(i) = b->AVRB(i) ^ AES_isbox[a->AVRB(AES_ishifts[i])];
+    }
+
+    VECTOR_FOR_INORDER_I(i, u32) {
+        r->AVRW(i) =
+            AES_imc[tmp.AVRB(4*i + 0)][0] ^
+            AES_imc[tmp.AVRB(4*i + 1)][1] ^
+            AES_imc[tmp.AVRB(4*i + 2)][2] ^
+            AES_imc[tmp.AVRB(4*i + 3)][3];
+    }
 }
 
 void helper_vncipherlast(ppc_avr_t *r, ppc_avr_t *a, ppc_avr_t *b)
 {
-    ppc_avr_t vtemp1, vtemp2;
-    InvShiftRows(&vtemp1, a);
-    InvSubBytes(&vtemp2, &vtemp1);
-    r->u64[0] = vtemp2.u64[0] ^ b->u64[0];
-    r->u64[1] = vtemp2.u64[1] ^ b->u64[1];
+    int i;
+
+    VECTOR_FOR_INORDER_I(i, u8) {
+        r->AVRB(i) = b->AVRB(i) ^ (AES_Td4[a->AVRB(AES_ishifts[i])] & 0xFF);
+    }
 }
 
 #define ROTRu32(v, n) (((v) >> (n)) | ((v) << (32-n)))
Signature · 1 line
1.7.1
#7 lore raw
In reply to Tom Musta
Quoted 7 lines · Tom Musta

This patch series addresses concerns raised by Richard Henderson regarding redundant copies of Advanced Encryption Standard (AES) data and code (see
http://lists.nongnu.org/archive/html/qemu-devel/2014-02/msg04391.html).

The patches declare commonly used AES tables in the include/qemu/aes.h header file and define the tables in util/aes.c, thus eliminating redundant copies.

Quoted 6 lines

Minor refactorization of the i386 and ARM instruction models are made to utilize this common support. The newly added PowerPC instructions are completely rewritten and look much more like the i386 equivalents; a substantial amount of code is eliminated.

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Looks good to me. Which queue should this go through? IMHO Richard would be the perfect person to get this through one of his.

Alex

#8 lore raw
Quoted 5 lines · Alexander Graf
Quoted 2 lines

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Looks good to me. Which queue should this go through? IMHO Richard would be the perfect person to get this through one of his.

I'm happy with it going through ppc-next.
It's minimal changes to i386 and arm, honestly.

Plus it's less work for me. ;-)

r~

#9 lore raw
Quoted 8 lines

Am 11.04.2014 um 19:05 schrieb Richard Henderson <[email protected]>:

Quoted 3 lines · Alexander Graf
Quoted 2 lines

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Quoted 7 lines
Quoted 2 lines

Looks good to me. Which queue should this go through? IMHO Richard would be the perfect person to get this through one of his.

I'm happy with it going through ppc-next.
It's minimal changes to i386 and arm, honestly.

Plus it's less work for me. ;-)

Then I need your Ack or Reviewed-by tags :)

Alex

Quoted 3 lines

r~

author
#10 lore raw
Quoted 11 lines · Alexander Graf
Quoted 11 lines

Am 11.04.2014 um 19:05 schrieb Richard Henderson <[email protected]>:

Quoted 5 lines · Alexander Graf
Quoted 2 lines

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Looks good to me. Which queue should this go through? IMHO Richard would be the perfect person to get this through one of his.

Quoted 12 lines
Quoted 4 lines

I'm happy with it going through ppc-next.
It's minimal changes to i386 and arm, honestly.

Plus it's less work for me. ;-)

Then I need your Ack or Reviewed-by tags :)

Alex

Quoted 3 lines

r~

Ping. Is there actually anything more you need, Alex? Richard did review.

#11 lore raw
Quoted 11 lines · Tom Musta
Quoted 10 lines · Alexander Graf
Quoted 10 lines

Am 11.04.2014 um 19:05 schrieb Richard Henderson <[email protected]>:

Quoted 3 lines · Alexander Graf
Quoted 1 line

V2: updated patch 05/06 per Richard Henderson's review (const pointer to const)

Looks good to me. Which queue should this go through? IMHO Richard would be the perfect person to get this through one of his.

I'm happy with it going through ppc-next.
It's minimal changes to i386 and arm, honestly.

Quoted 8 lines
Quoted 7 lines
Quoted 1 line

Plus it's less work for me. ;-)

Then I need your Ack or Reviewed-by tags :)

Alex

Quoted 2 lines

r~

Ping. Is there actually anything more you need, Alex? Richard did review.

Oops, missed them :). Thanks, applied to ppc-next.

Alex