]> git.ipfire.org Git - thirdparty/krb5.git/commitdiff
Update Gladman AES code 1124/head
authorGreg Hudson <ghudson@mit.edu>
Sat, 10 Oct 2020 15:18:12 +0000 (11:18 -0400)
committerGreg Hudson <ghudson@mit.edu>
Sat, 17 Oct 2020 20:25:10 +0000 (16:25 -0400)
Update lib/crypto/builtin/aes to commit
8798ad829374cd5ff312f55ba3ccccfcf586fa11 of
https://github.com/BrianGladman/aes .

The following changes are made to the upstream code:

* In aes.h, #defines are added to give the linker-visible symbols a
  prefix.

* In aes.h, AES_192 is undefined, since we only need AES-128 and
  AES-256.

* In aesopt.h, USE_INTEL_AES_IF_PRESENT and USE_VIA_ACE_IF_PRESENT are
  suppressed by changing the corresponding "#if 1"s to "#if 0"s.

* In aesopt.h, the conditionals for ENC_UNROLL, DEC_UNROLL, ENC_ROUND,
  LAST_ENC_ROUND, DEC_ROUND, LAST_DEC_ROUND, and KEY_SCHED are changed
  from "#if 1" to "#if !defined(CONFIG_SMALL) ||
  defined(CONFIG_SMALL_NO_CRYPTO)".

bigredbutton: whitespace

ticket: 8954

26 files changed:
NOTICE
doc/notice.rst
src/lib/crypto/builtin/aes/Makefile.in
src/lib/crypto/builtin/aes/aes-gen.c
src/lib/crypto/builtin/aes/aes.h
src/lib/crypto/builtin/aes/aes.txt
src/lib/crypto/builtin/aes/aescpp.h [deleted file]
src/lib/crypto/builtin/aes/aescrypp.c [deleted file]
src/lib/crypto/builtin/aes/aescrypt.asm [deleted file]
src/lib/crypto/builtin/aes/aescrypt.c
src/lib/crypto/builtin/aes/aeskey.c
src/lib/crypto/builtin/aes/aeskeypp.c [deleted file]
src/lib/crypto/builtin/aes/aesopt.h
src/lib/crypto/builtin/aes/aessrc.url [deleted file]
src/lib/crypto/builtin/aes/aestab.c
src/lib/crypto/builtin/aes/aestab.h [new file with mode: 0644]
src/lib/crypto/builtin/aes/brg_endian.h [new file with mode: 0644]
src/lib/crypto/builtin/aes/brg_types.h [new file with mode: 0644]
src/lib/crypto/builtin/aes/deps
src/lib/crypto/builtin/aes/kresults.expected [new file with mode: 0644]
src/lib/crypto/builtin/enc_provider/aes.c
src/lib/crypto/krb/crypto_int.h
src/lib/crypto/krb/prng_fortuna.c
src/lib/crypto/libk5crypto.exports
src/lib/crypto/openssl/crypto_mod.h
src/lib/crypto/openssl/stubs.c

diff --git a/NOTICE b/NOTICE
index 17f7146d126daa22e11559860b7ae95aee8edba0..19eb0205baa74e89e64a78611d17b36004448f97 100644 (file)
--- a/NOTICE
+++ b/NOTICE
@@ -137,29 +137,22 @@ Portions of "src/lib/crypto" have the following copyright:
 The implementation of the AES encryption algorithm in
 "src/lib/crypto/builtin/aes" has the following copyright:
 
-      Copyright (C) 2001, Dr Brian Gladman "brg@gladman.uk.net",
-      Worcester, UK.
-      All rights reserved.
-
-   LICENSE TERMS
-
-   The free distribution and use of this software in both source and
-   binary form is allowed (with or without changes) provided that:
-
-   1. distributions of this source code include the above copyright
-      notice, this list of conditions and the following disclaimer;
+      Copyright (C) 1998-2013, Brian Gladman, Worcester, UK. All
+      rights reserved.
 
-   2. distributions in binary form include the above copyright
-      notice, this list of conditions and the following disclaimer in
-      the documentation and/or other associated materials;
+   The redistribution and use of this software (with or without
+   changes) is allowed without the payment of fees or royalties
+   provided that:
 
-   3. the copyright holder's name is not used to endorse products
-      built using this software without specific written permission.
+      source code distributions include the above copyright notice,
+      this list of conditions and the following disclaimer;
 
-   DISCLAIMER
+      binary distributions include the above copyright notice, this
+      list of conditions and the following disclaimer in their
+      documentation.
 
-   This software is provided 'as is' with no explcit or implied
-   warranties in respect of any properties, including, but not limited
+   This software is provided 'as is' with no explicit or implied
+   warranties in respect of its operation, including, but not limited
    to, correctness and fitness for purpose.
 
 ======================================================================
index 45bb7a6ad5961b743c26a2ac8a0c40e047a7dec4..b8d62bdca9c55a917466762d6fb38c7b346b05ff 100644 (file)
@@ -134,27 +134,22 @@ Portions of ``src/lib/crypto`` have the following copyright:
 The implementation of the AES encryption algorithm in
 ``src/lib/crypto/builtin/aes`` has the following copyright:
 
-    | Copyright |copy| 2001, Dr Brian Gladman ``brg@gladman.uk.net``,
-        Worcester, UK.
-    | All rights reserved.
-
-    LICENSE TERMS
+    | Copyright |copy| 1998-2013, Brian Gladman, Worcester, UK. All
+    | rights reserved.
 
-    The free distribution and use of this software in both source and binary
-    form is allowed (with or without changes) provided that:
+    The redistribution and use of this software (with or without
+    changes) is allowed without the payment of fees or royalties
+    provided that:
 
-    1.  distributions of this source code include the above copyright
-        notice, this list of conditions and the following disclaimer;
-    2.  distributions in binary form include the above copyright
-        notice, this list of conditions and the following disclaimer
-        in the documentation and/or other associated materials;
-    3.  the copyright holder's name is not used to endorse products
-        built using this software without specific written permission.
+      source code distributions include the above copyright notice,
+      this list of conditions and the following disclaimer;
 
-    DISCLAIMER
+      binary distributions include the above copyright notice, this
+      list of conditions and the following disclaimer in their
+      documentation.
 
-    This software is provided 'as is' with no explcit or implied warranties
-    in respect of any properties, including, but not limited to, correctness
+    This software is provided 'as is' with no explicit or implied warranties
+    in respect of its operation, including, but not limited to, correctness
     and fitness for purpose.
 
 -------------------
index 11a11074ab9a0feab8e294dcdf0bdf50905f950f..05c7bd505a0f51141d40b4983bd4f4859a0d0674 100644 (file)
@@ -49,6 +49,7 @@ aes-gen: aes-gen.o $(GEN_OBJS)
 
 run-aes-gen: aes-gen
        ./aes-gen > kresults.out
+       cmp kresults.out $(srcdir)/kresults.expected
 
 check: run-aes-gen
 
index e33c193268ee5ca7f1beef3782239e019b0fdb1e..07d94b815525c286b6a8b9c0a31febeed906ddf1 100644 (file)
@@ -17,7 +17,8 @@ struct {
     unsigned char input[4*16];
     unsigned char output[4*16];
 } test_case[NTESTS];
-aes_ctx ctx, dctx;
+aes_encrypt_ctx ctx;
+aes_decrypt_ctx dctx;
 
 static void init ()
 {
@@ -32,10 +33,10 @@ static void init ()
            test_case[i].input[j] = 0xff & rand();
        }
 
-    r = aes_enc_key (key, sizeof(key), &ctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
-    r = aes_dec_key (key, sizeof(key), &dctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_encrypt_key128(key, &ctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_decrypt_key128(key, &dctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
 }
 
 static void hexdump(const unsigned char *ptr, size_t len)
@@ -60,26 +61,26 @@ static void fips_test ()
     };
     unsigned char output[16];
     unsigned char tmp[16];
-    aes_ctx fipsctx;
+    aes_crypt_ctx fipsctx;
     int r;
 
     printf ("FIPS test:\nkey:");
     hexdump (fipskey, 16);
     printf ("\ninput:");
     hexdump (input, 16);
-    r = aes_enc_key (fipskey, sizeof(fipskey), &fipsctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
-    r = aes_enc_blk (input, output, &fipsctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_encrypt_key128(fipskey, &fipsctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_encrypt(input, output, &fipsctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     printf ("\noutput:");
     hexdump (output, 16);
     printf ("\n");
     if (memcmp(expected, output, 16))
        fprintf(stderr, "wrong results!!!\n"), exit (1);
-    r = aes_dec_key (fipskey, sizeof(fipskey), &fipsctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
-    r = aes_dec_blk (output, tmp, &fipsctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_decrypt_key128(fipskey, &fipsctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_decrypt(output, tmp, &fipsctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     if (memcmp(input, tmp, 16))
        fprintf(stderr, "decryption failed!!\n"), exit(1);
     printf ("ok.\n\n");
@@ -98,8 +99,8 @@ ecb_enc (unsigned char *out, unsigned char *in, unsigned int len)
 {
     unsigned int i, r;
     for (i = 0; i < len; i += 16) {
-       r = aes_enc_blk (in + i, out + i, &ctx);
-       if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+       r = aes_encrypt(in + i, out + i, &ctx);
+       if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     }
     if (i != len) abort ();
 }
@@ -109,8 +110,8 @@ ecb_dec (unsigned char *out, unsigned char *in, unsigned int len)
 {
     unsigned int i, r;
     for (i = 0; i < len; i += 16) {
-       r = aes_dec_blk (in + i, out + i, &dctx);
-       if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+       r = aes_decrypt(in + i, out + i, &dctx);
+       if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     }
     if (i != len) abort ();
 }
@@ -132,8 +133,8 @@ cbc_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
        D(in+i);
        xor (tmp, tmp, in + i);
        D(tmp);
-       r = aes_enc_blk (tmp, out + i, &ctx);
-       if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+       r = aes_encrypt(tmp, out + i, &ctx);
+       if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
        memcpy (tmp, out + i, B);
        D(out+i);
     }
@@ -148,8 +149,8 @@ cbc_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
     unsigned char tmp[B];
     memcpy (tmp, iv, B);
     for (i = 0; i < len; i += B) {
-       r = aes_dec_blk (in + i, tmp, &dctx);
-       if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+       r = aes_decrypt(in + i, tmp, &dctx);
+       if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
        xor (tmp, tmp, iv);
        iv = in + i;
        memcpy (out + i, tmp, B);
@@ -180,16 +181,16 @@ cts_enc (unsigned char *out, unsigned char *in, unsigned char *iv,
     D(in);
     xor (pn1, in, iv);
     D(pn1);
-    r = aes_enc_blk (pn1, cn, &ctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_encrypt(pn1, cn, &ctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     D(cn);
     memset (pn, 0, sizeof(pn));
     memcpy (pn, in+B, len-B);
     D(pn);
     xor (pn, pn, cn);
     D(pn);
-    r = aes_enc_blk (pn, cn1, &ctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_encrypt(pn, cn1, &ctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     D(cn1);
     memcpy(out, cn1, B);
     memcpy(out+B, cn, len-B);
@@ -215,14 +216,14 @@ cts_dec (unsigned char *out, unsigned char *in, unsigned char *iv,
        abort ();
 
     memcpy (cn1, in, B);
-    r = aes_dec_blk (cn1, pn, &dctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_decrypt(cn1, pn, &dctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     memset (cn, 0, sizeof(cn));
     memcpy (cn, in+B, len-B);
     xor (pn, pn, cn);
     memcpy (cn+len-B, pn+len-B, 2*B-len);
-    r = aes_dec_blk (cn, pn1, &dctx);
-    if (!r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
+    r = aes_decrypt(cn, pn1, &dctx);
+    if (r) fprintf(stderr, "error, line %d\n", __LINE__), exit(1);
     xor (pn1, pn1, iv);
     memcpy(out, pn1, B);
     memcpy(out+B, pn, len-B);
index 8f6f426b921828e115df9efdf49753e3abd51d18..9b5215eb48c15b02436fa0f375388531aaf38991 100644 (file)
 /*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
 
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the definitions required to use AES (Rijndael) in C.
- */
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
 
-#ifndef _AES_H
-#define _AES_H
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
 
-#include <stdint.h>
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
 
-/*  BLOCK_SIZE is in BYTES: 16, 24, 32 or undefined for aes.c and 16, 20,
-    24, 28, 32 or undefined for aespp.c.  When left undefined a slower
-    version that provides variable block length is compiled.
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 02/09/2018
+
+ This file contains the definitions required to use AES in C. See aesopt.h
+ for optimisation details.
 */
 
-#define BLOCK_SIZE  16
+#ifndef _AES_H
+#define _AES_H
 
-/* key schedule length (in 32-bit words)    */
+/* For MIT krb5, give the linker-visible symbols a prefix. */
+#define aes_decrypt        k5_aes_decrypt
+#define aes_decrypt_key    k5_aes_decrypt_key
+#define aes_decrypt_key128 k5_aes_decrypt_key128
+#define aes_decrypt_key256 k5_aes_decrypt_key256
+#define aes_encrypt        k5_aes_encrypt
+#define aes_encrypt_key    k5_aes_encrypt_key
+#define aes_encrypt_key128 k5_aes_encrypt_key128
+#define aes_encrypt_key256 k5_aes_encrypt_key256
+#define aes_init           k5_aes_init
 
-#if !defined(BLOCK_SIZE)
-#define KS_LENGTH   128
-#else
-#define KS_LENGTH   4 * BLOCK_SIZE
-#endif
+#include <stdlib.h>
+
+/*  This include is used to find 8 & 32 bit unsigned integer types   */
+#include "brg_types.h"
 
 #if defined(__cplusplus)
 extern "C"
 {
 #endif
 
-typedef uint16_t    aes_fret;   /* type for function return value       */
-#define aes_bad     0           /* bad function return value            */
-#define aes_good    1           /* good function return value           */
-#ifndef AES_DLL                 /* implement normal or DLL functions    */
-#define aes_rval    aes_fret
+#define AES_128     /* if a fast 128 bit key scheduler is needed     */
+#undef AES_192     /* if a fast 192 bit key scheduler is needed     */
+#define AES_256     /* if a fast 256 bit key scheduler is needed     */
+#define AES_VAR     /* if variable key size scheduler is needed      */
+#if 1
+#  define AES_MODES /* if support is needed for modes in the C code  */
+#endif              /* (these will use AES_NI if it is present)      */
+#if 0               /* add this to make direct calls to the AES_NI   */
+#                   /* implemented CBC and CTR modes available       */
+#   define ADD_AESNI_MODE_CALLS
+#endif
+
+/* The following must also be set in assembler files if being used   */
+
+#define AES_ENCRYPT /* if support for encryption is needed           */
+#define AES_DECRYPT /* if support for decryption is needed           */
+
+#define AES_BLOCK_SIZE_P2  4  /* AES block size as a power of 2      */
+#define AES_BLOCK_SIZE    (1 << AES_BLOCK_SIZE_P2) /* AES block size */
+#define N_COLS             4  /* the number of columns in the state  */
+
+/* The key schedule length is 11, 13 or 15 16-byte blocks for 128,   */
+/* 192 or 256-bit keys respectively. That is 176, 208 or 240 bytes   */
+/* or 44, 52 or 60 32-bit words.                                     */
+
+#if defined( AES_VAR ) || defined( AES_256 )
+#define KS_LENGTH       60
+#elif defined( AES_192 )
+#define KS_LENGTH       52
 #else
-#define aes_rval    aes_fret __declspec(dllexport) _stdcall
-#endif
-
-typedef struct                      /* the AES context for encryption   */
-{   uint32_t    k_sch[KS_LENGTH];   /* the encryption key schedule      */
-    uint32_t    n_rnd;              /* the number of cipher rounds      */
-    uint32_t    n_blk;              /* the number of bytes in the state */
-} aes_ctx;
-
-/* for Kerberos 5 tree -- hide names!  */
-#define aes_blk_len    krb5int_aes_blk_len
-#define aes_enc_key    krb5int_aes_enc_key
-#define aes_enc_blk    krb5int_aes_enc_blk
-#define aes_dec_key    krb5int_aes_dec_key
-#define aes_dec_blk    krb5int_aes_dec_blk
-#define fl_tab         krb5int_fl_tab
-#define ft_tab         krb5int_ft_tab
-#define il_tab         krb5int_il_tab
-#define im_tab         krb5int_im_tab
-#define it_tab         krb5int_it_tab
-#define rcon_tab       krb5int_rcon_tab
-
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
-
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
-aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
-
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
-aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
+#define KS_LENGTH       44
+#endif
+
+#define AES_RETURN INT_RETURN
+
+/* the character array 'inf' in the following structures is used     */
+/* to hold AES context information. This AES code uses cx->inf.b[0]  */
+/* to hold the number of rounds multiplied by 16. The other three    */
+/* elements can be used by code that implements additional modes     */
+
+typedef union
+{   uint32_t l;
+    uint8_t b[4];
+} aes_inf;
+
+/* Macros for detecting whether a given context was initialized for  */
+/* use with encryption or decryption code. These should only be used */
+/* by e.g. language bindings which lose type information when the    */
+/* context pointer is passed to the calling language's runtime.      */
+#define IS_ENCRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 1)
+#define IS_DECRYPTION_CTX(cx) (((cx)->inf.b[2] & (uint8_t)0x01) == 0)
+
+#ifdef _MSC_VER
+#  pragma warning( disable : 4324 )
+#endif
+
+#if defined(_MSC_VER) && defined(_WIN64)
+#define ALIGNED_(x) __declspec(align(x))
+#elif defined(__GNUC__) && defined(__x86_64__)
+#define ALIGNED_(x) __attribute__ ((aligned(x)))
+#else
+#define ALIGNED_(x)
+#endif
+
+typedef struct ALIGNED_(16)
+{   uint32_t ks[KS_LENGTH];
+    aes_inf inf;
+} aes_crypt_ctx;
+
+typedef aes_crypt_ctx aes_encrypt_ctx;
+typedef aes_crypt_ctx aes_decrypt_ctx;
+
+#ifdef _MSC_VER
+#  pragma warning( default : 4324 )
+#endif
+
+/* This routine must be called before first use if non-static       */
+/* tables are being used                                            */
+
+AES_RETURN aes_init(void);
+
+/* Key lengths in the range 16 <= key_len <= 32 are given in bytes, */
+/* those in the range 128 <= key_len <= 256 are given in bits       */
+
+#if defined( AES_ENCRYPT )
+
+#if defined( AES_128 ) || defined( AES_VAR)
+AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_192 ) || defined( AES_VAR)
+AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_256 ) || defined( AES_VAR)
+AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_VAR )
+AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1]);
+#endif
+
+AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1]);
+
+#endif
+
+#if defined( AES_DECRYPT )
+
+#if defined( AES_128 ) || defined( AES_VAR)
+AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_192 ) || defined( AES_VAR)
+AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_256 ) || defined( AES_VAR)
+AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
+#endif
+
+#if defined( AES_VAR )
+AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1]);
+#endif
+
+AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1]);
+
+#endif
+
+#if defined( AES_MODES )
+
+/* Multiple calls to the following subroutines for multiple block   */
+/* ECB, CBC, CFB, OFB and CTR mode encryption can be used to handle */
+/* long messages incrementally provided that the context AND the iv */
+/* are preserved between all such calls.  For the ECB and CBC modes */
+/* each individual call within a series of incremental calls must   */
+/* process only full blocks (i.e. len must be a multiple of 16) but */
+/* the CFB, OFB and CTR mode calls can handle multiple incremental  */
+/* calls of any length.  Each mode is reset when a new AES key is   */
+/* set but ECB needs no reset and CBC can be reset without setting  */
+/* a new key by setting a new IV value.  To reset CFB, OFB and CTR  */
+/* without setting the key, aes_mode_reset() must be called and the */
+/* IV must be set.  NOTE: All these calls update the IV on exit so  */
+/* this has to be reset if a new operation with the same IV as the  */
+/* previous one is required (or decryption follows encryption with  */
+/* the same IV array).                                              */
+
+AES_RETURN aes_test_alignment_detection(unsigned int n);
+
+AES_RETURN aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, const aes_encrypt_ctx cx[1]);
+
+AES_RETURN aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, const aes_decrypt_ctx cx[1]);
+
+AES_RETURN aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, const aes_encrypt_ctx cx[1]);
+
+AES_RETURN aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, const aes_decrypt_ctx cx[1]);
+
+AES_RETURN aes_mode_reset(aes_encrypt_ctx cx[1]);
+
+AES_RETURN aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
+
+AES_RETURN aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
+
+#define aes_ofb_encrypt aes_ofb_crypt
+#define aes_ofb_decrypt aes_ofb_crypt
+
+AES_RETURN aes_ofb_crypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1]);
+
+typedef void cbuf_inc(unsigned char *cbuf);
+
+#define aes_ctr_encrypt aes_ctr_crypt
+#define aes_ctr_decrypt aes_ctr_crypt
+
+AES_RETURN aes_ctr_crypt(const unsigned char *ibuf, unsigned char *obuf,
+            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1]);
+
+#endif
+
+#if 0 && defined( ADD_AESNI_MODE_CALLS )
+#  define USE_AES_CONTEXT
+#endif
+
+#ifdef ADD_AESNI_MODE_CALLS
+#  ifdef USE_AES_CONTEXT
+
+AES_RETURN aes_CBC_encrypt(const unsigned char *in,
+    unsigned char *out,
+    unsigned char ivec[16],
+    unsigned long length,
+    const aes_encrypt_ctx cx[1]);
+
+AES_RETURN aes_CBC_decrypt(const unsigned char *in,
+    unsigned char *out,
+    unsigned char ivec[16],
+    unsigned long length,
+    const aes_decrypt_ctx cx[1]);
+
+AES_RETURN AES_CTR_encrypt(const unsigned char *in,
+    unsigned char *out,
+    const unsigned char ivec[8],
+    const unsigned char nonce[4],
+    unsigned long length,
+    const aes_encrypt_ctx cx[1]);
+
+#  else
+
+void aes_CBC_encrypt(const unsigned char *in,
+    unsigned char *out,
+    unsigned char ivec[16],
+    unsigned long length,
+    unsigned char *key,
+    int number_of_rounds);
+
+void aes_CBC_decrypt(const unsigned char *in,
+    unsigned char *out,
+    unsigned char ivec[16],
+    unsigned long length,
+    unsigned char *key,
+    int number_of_rounds);
+
+void aes_CTR_encrypt(const unsigned char *in,
+    unsigned char *out,
+    const unsigned char ivec[8],
+    const unsigned char nonce[4],
+    unsigned long length,
+    const unsigned char *key,
+    int number_of_rounds);
+
+#  endif
+#endif
 
 #if defined(__cplusplus)
 }
index b644b5eb401fbc3b2f866b7922918a5b1e9c9fa9..25710f29eea8e97eed864d4c7c86918cfeafc51b 100644 (file)
 
 An AES (Rijndael) Implementation in C/C++ (as specified in FIPS-197)
---------------------------------------------------------------------
-
-The source code files are as follows:
-
-1. aes.h:       the header file required to use AES in C
-2. aescpp.h     the header file required to use AES in C++
-3. aescrypt.c   the main C source code file for encryption and decryption
-4. aeskey.c     the main C source code file for the key schedule
-5. aestab.c     the main file for the AES tables
-6. aesopt.h     the file for common code and for setting build options
-7. aescrypt.asm a faster alternative to 3 above in assembler (using NASM)
-8. uitypes.h    a file for defining fixed length unsigned integer types
-9. aescrypp.c   an alternative to 3 for all Rijndael block and key sizes 
-10.aeskeypp.c   an alternative to 4 for all Rijndael block and key sizes 
-11.aesxam.c     an example of AES use
-
-Source files 9 and 10 are much slower than 4 and 5 for normal use and
-should not be used unless support for 20 and 28 byte blocks and keys
-is necessary.  Files 4 and 5 provide support for block and key sizes
-of 16, 24 and 32 bytes (fixed or variable) but the assemler code in 
-file 7 only supports the 16 byte AES block length. It does, however,
-offer the three key sizes when used with file 4. The use of files 4
-and 5 (or 9 and 10) with variable block size should be avoided since 
-the code is much faster when the block size is fixed.
-
-The VC++ AES Development Project
---------------------------------
-
-The VC++ SOlution contains the following sub-projects
-
-1. aes_asm      this project tests the assembler code implementation
-2. aes_dll      this project builds the DLL version
-3. aes_gav      this project re-creates the test vector files and
-                optionally checks them against a reference set
-4. aes_rav      this project checks the values produced by the code
-                against the values in the test vector files
-5. aes_tmr      this project measures the speed of the code
-6. aes_tst      this project is set up to test the extended version
-                of Rijndael with block and key sizes of 16, 20, 24,
-                28 and 32 bytes
-7. aes_xam      this project builds the example of AES use in a 
-                simple file encryption program
-                
-Note that the paths for the various directories have to be set up in 
-aestst.h
-
-The AES and Rijndael Test Vector Files
---------------------------------------
+====================================================================
+
+Change (26/09/2018)
+===================
+
+1. Changes to test programs to allow them to be built on Linux/GCC
+   (with thanks to Michael Mohr).
+
+2. Rationalisation of the defines DLL_IMPORT, DYNAMIC_DLL and USE_DLL
+   in the test code - now DLL_IMPORT and DLL_DYNAMIC_LOAD
+
+3. Update the test_avs test to allow the testing of static, DLL and
+   dynamically loaded DLL libraries.
+
+Change (21/05/2018)
+===================
+
+1. Properly dectect presence of AESNI when using GCC (my thanks to 
+   Peter Gutmann for this fix)
+
+Changes (6/12/2016)
+====================
+
+1. Changed function definition of has_aes_ni() to has_aes_ni(void), 
+   suggested by Peter Gutmann
+   
+2. Changed the default location for the vsyasm assembler to:
+   C:\Program Files\yasm
+
+Changes (27/09/2015)
+====================
+
+1. Added automatic dynamic table initialisation (my thanks to
+   Henrik S. Gaßmann who proposed this addition).
+
+Changes (09/09/2014)
+====================
+
+1. Added the ability to use Intel's hardware support for AES
+   with GCC on Windows and Linux
+
+Changes (01/09/2014)
+====================
+
+1. Clarify some user choices in the file aes_amd64.asm
+
+2. Change the detection of the x86 and x86_64 processors
+   in aesopt.h to allow assembler code use with GCC
+    
+Changes (14/11/2013)
+====================
+
+1. Added the ability to use Intel's hardware support for AES
+   on Windows using Microsoft Visual Studio.
+
+2. Added the include 'stdint.h' and used the uint<xx>_t instead
+   of the old uint_<xx>t (e.g. uint_32t is now uint32_t).
+
+3. Added a missing .text directive in aes_x86_v2.asm that caused
+   runtime errors in one build configuration.
+
+Changes (16/04/2007)
+====================
+
+These changes remove errors in the VC++ build files and add some 
+improvements in file naming consitency and portability. There are
+no changes to overcome reported bugs in the code.
+
+1. gen_tabs() has been renamed to aes_init() to better decribe its
+   function to those not familiar with AES internals.
+
+2. via_ace.h has been renamed to aes_via_ace.h.
+
+3. Minor changes have been made to aestab.h and aestab.c to enable
+   all the code to be compiled in either C or C++.
+   
+4. The code for detecting memory alignment in aesmdoes.c has been
+   simplified and a new routine has been added:
+   
+       aes_test_alignment_detection()
+   
+   to check that the aligment test is likely to be correct.
+
+5. The addition of support for Structured Exception Handling (SEH) 
+   to YASM (well done Peter and Michael!) has allowed the AMD64 
+   x64 assembler code to be changed to comply with SEH requriements.
+       
+6. Corrections to build files (for win32 debug build).
+
+Overview
+========
+
+This code implements AES for both 32 and 64 bit systems with optional
+assembler support for x86 and AMD64/EM64T (but optimised for AMD64).
+
+The basic AES source code files are as follows:
+
+aes.h           the header file needed to use AES in C
+aescpp.h        the header file required with to use AES in C++
+aesopt.h        the header file for setting options (and some common code)
+aestab.h        the header file for the AES table declaration
+aescrypt.c      the main C source code file for encryption and decryption
+aeskey.c        the main C source code file for the key schedule
+aestab.c        the main file for the AES tables
+brg_types.h     a header defining some standard types and DLL defines
+brg_endian.h    a header containing code to detect or define endianness
+aes_x86_v1.asm  x86 assembler (YASM) alternative to aescrypt.c using
+                large tables
+aes_x86_v2.asm  x86 assembler (YASM) alternative to aescrypt.c using
+                compressed tables
+aes_amd64.asm   AMD64 assembler (YASM) alternative to aescrypt.c using
+                compressed tables
+
+In addition AES modes are implemented in the files:
+
+aes_modes.c     AES modes with optional support for VIA ACE detection and use
+aes_via_ace.h   the header file for VIA ACE support
+
+and Intel hardware support for AES (AES_NI) is implemented in the files
+
+aes_ni.h        defines for AES_NI implementation
+aes_ni.c        the AES_NI implementation
+
+Other associated files for testing and support are:
+
+aesaux.h        header for auxilliary routines for testsing
+aesaux.c        auxilliary routines for testsingt
+aestst.h        header file for setting the testing environment
+rdtsc.h         a header file that provides access to the Time Stamp Counter
+aestst.c        a simple test program for quick tests of the AES code
+aesgav.c        a program to generate and verify the test vector files
+aesrav.c        a program to verify output against the test vector files
+aestmr.c        a program to time the code on x86 systems
+modetest.c      a program to test the AES modes support
+vbxam.doc       a demonstration of AES DLL use from Visual Basic in Microsoft Word
+vb.txt          Visual Basic code from the above example (win32 only)
+aesxam.c        an example of AES use
+tablegen.c      a program to generate a simplified 'aestab.c' file for
+                use with compilers that find aestab.c too complex
+yasm.rules      the YASM build rules file for Microsoft Visual Studio 2005
+via_ace.txt     describes support for the VIA ACE cryptography engine
+aes.txt         this file
+
+Building The AES Libraries
+--------------------------
+
+A. Versions
+-----------
+
+The code can be used to build static and dynamic libraries, each in five
+versions:
+
+ Key scheduling code in C, encrypt/decrypt in:
+
+    C           C source code                        (win32 and x64)
+    ASM_X86_V1C large table x86 assembler code       (win32)
+    ASM_X86_V2C compressed table x86 assembler code  (win32)
+    ASM_AMD64   compressed table x64 assembler code  (x64)
+ Key scheduling and encrypt/decrypt code in assembler:
+    ASM_X86_V2  compressed table x86 assembler       (win32)
+
+The C version can be compiled for Win32 or x64 whereas the x86 and x64 
+assembler versions are for Win32 and x64 respectively. 
+
+If Intel's hardware support for AES (AES_NI) is available, it can be used
+with either the C or the ASM_AMD64 version. If ASM_AMD64 is to be used, it
+is important that the define USE_INTEL_AES_IF_PRESENT in asm_amd64.asm is
+set to the same value as it has in aesopt.h
+
+B. YASM
+-------
+
+If you wish to use the x86 assembler files you will also need the YASM open
+source x86 assembler (r1331 or later) for Windows which can be obtained from:
+
+    http://www.tortall.net/projects/yasm/
+
+This assembler (vsyasm.exe) should be placed in the directory:
+
+    C:\Program Files\yasm
+
+C. Configuration
+----------------
+
+The following configurations are available as projects for Visual Studio
+but the following descriptions should allow them to be built in other x86
+environments
+
+    lib_generic_c       Win32 and x64
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+                               (+ aes_ni.h for AES_NI)
+        C source:       aescrypt.c, aeskey.c, aestab.c, aes_modes.c
+                               (+ aes_ni.c for AES_NI)
+        defines
+
+    dll_generic_c       Win32 and x64
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+                               (+ aes_ni.h for AES_NI)
+        C source:       aescrypt.c, aeskey.c, aestab.c, aes_modes.c
+                               (+ aes_ni.c for AES_NI)
+        defines         DLL_EXPORT
+
+    lib_asm_x86_v1c     Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aeskey.c, aestab.c, aes_modes.c
+        x86 assembler:  aes_x86_v1.asm
+        defines         ASM_X86_V1C (set for C and assembler files)
+    
+       dll_asm_x86_v1c     Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aeskey.c, aestab.c, aes_modes.c
+        x86 assembler:  aes_x86_v1.asm
+        defines         DLL_EXPORT, ASM_X86_V1C (set for C and assembler files)
+
+    lib_asm_x86_v2c     Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aeskey.c, aestab.c, aes_modes.c
+        x86 assembler:  aes_x86_v2.asm
+        defines         ASM_X86_V2C (set for C and assembler files)
+    
+       dll_asm_x86_v2c     Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aeskey.c, aestab.c, aes_modes.c
+        x86 assembler:  aes_x86_v1.asm
+        defines         DLL_EXPORT, ASM_X86_V2C (set for C and assembler files)
+
+    lib_asm_x86_v2      Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aes_modes.c
+        x86 assembler:  aes_x86_v1.asm
+        defines         ASM_X86_V2 (set for C and assembler files)
+    
+       dll_asm_x86_v2      Win32
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+        C source:       aes_modes.c
+        x86 assembler:  aes_x86_v1.asm
+        defines         DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)
+
+    lib_asm_amd64_c     x64
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+                               (+ aes_ni.h for AES_NI)
+        C source:       aes_modes.c (+ aes_ni.c for AES_NI)
+        x86 assembler:  aes_amd64.asm
+        defines         ASM_AMD64_C (set for C and assembler files)
+    
+       dll_asm_amd64_c     x64
+        headers:        aes.h, aesopt.h, aestab.h, brg_endian.h, tdefs.h
+                               (+ aes_ni.h for AES_NI)
+        C source:       aes_modes.c (+ aes_ni.c for AES_NI)
+        x86 assembler:  aes_amd64.asm
+        defines         DLL_EXPORT, ASM_AMD64_C (set for C and assembler files)
+
+Notes:
+
+ASM_X86_V1C is defined if using the version 1 assembler code (aescrypt1.asm).
+            The defines in the assember file must match those in aes.h and
+            aesopt.h).  Also remember to include/exclude the right assembler
+            and C files in the build to avoid undefined or multiply defined
+            symbols - include aes_x86_v1.asm and exclude aescrypt.c
+
+ASM_X86_V2  is defined if using the version 2 assembler code (aes_x86_v2.asm).
+            This version provides a full, self contained assembler version
+            and does not use any C source code files except for the mutiple
+            block encryption modes that are provided by aes_modes.c. The define
+            ASM_X86_V2 must be set on the YASM command line (or in aes_x86_v2.asm)
+            to use this version and all C files except aec_modes.c and, for the
+            DLL build, aestab.c must be excluded from the build.
+
+ASM_X86_V2C is defined when using the version 2 assembler code (aes_x86_v2.asm)
+            with faster key scheduling provided by the in C code (the options in
+            the assember file must match those in aes.h and aesopt.h).  In this
+            case aeskey.c and aestab.c are needed with aes_x86_v2.asm and the
+            define ASM_X86_V2C must be set for both the C files and for
+            aes_x86_v2.asm in the build commands(or in aesopt.h and aes_x86_v2.asm).
+            Include aes_x86_v2.asm, aeskey.c and aestab.c, exclude aescrypt.c for
+            this option.
+
+ASM_AMD64_C is defined when using the AMD64 assembly code because the C key
+            scheduling is used in this case.
+
+DLL_EXPORT  must be defined to generate the DLL version of the code and
+            to run tests on it
+
+DLL_IMPORT  must be defined to use the DLL version of the code in an
+            application program
+
+Directories the paths for the various directories for test vector input and
+            output have to be set in aestst.h
+
+VIA ACE     see the via_ace.txt for this item
+
+Static      The static libraries are named:
+Libraries
+                aes_lib_generic_c.lib
+                aes_lib_asm_x86_v1c.lib
+                aes_lib_asm_x86_v2.lib
+                aes_lib_asm_x86_v2c.lib
+                aes_lib_asm_amd64_c.lib
+
+            and placed in one of the the directories:
+
+                lib\win32\release\
+                lib\win32\debug\
+                lib\x64\release\
+                lib\x64\debug\
+
+            in the aes root directory depending on the platform(win32 or
+            x64) and the build (release or debug). After any of these is
+            built it is then copied into the aes\lib directory, which is
+                       the library location that is subsequently used for testing. 
+                       Hence testing is always for the last static library built.
+
+Dynamic     These libraries are named:
+Libraries
+                aes_lib_generic_c.dll
+                aes_lib_asm_x86_v1c.dll
+                aes_lib_asm_x86_v2.dll
+                aes_lib_asm_x86_v2c.dll
+                aes_lib_asm_amd64_c.dll
+
+            and placed in one of the the directories:
+
+                dll\win32\release\
+                dll\win32\debug\
+                dll\x64\release\
+                dll\x64\debug\
+
+            in the aes root directory depending on the platform(win32 or
+            x64) and the build (release or debug).  Each DLL library:
+
+                aes_<ext>.dll
+
+            has three associated files:
+
+                aes_dll_<ext>.lib   the library file for implicit linking
+                aes_dll_<ext>.exp   the exports file
+                aes_dll_<ext>.pdb   the symbol file
+
+            After any DLL is built it and its three related files are then
+            copied to the aes\dll directory, which is the library location
+                       used in subsequent testing.  Hence testing is always for the 
+                       last DLL built.
+                       
+D. Testing
+----------
+
+These tests require that the test vector files are placed in the 'testvals' 
+subdirectory.  If the AES Algorithm Validation Suite tests are used then
+the *.fax files need to be put in the 'testvals\fax' subdirectory.  This is
+covered in more detail below.
+
+The projects test_lib and time_lib are used to test and time the last static
+library built. They use the files:
+
+    test_lib:       Win32 (x64 for the C and AMD64 versions)
+        headers:    aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
+        C source:   aesaux.c, aesrav.c
+        defines:
+
+    time_lib:       Win32 (x64 for the C and AMD64 versions)
+        headers:    aes.h, aescpp.h, brg_types.h, aesaux.h, aestst.h and rdtsc.h
+        C source:   aesaux.c, aestmr.c
+        defines:
+
+The projects test_dll and time_dll are used to test and time the last DLL
+built.  These use the files:
+
+    test_dll:       Win32 (x64 for the C and AMD64 versions)
+        headers:    aes.h, aescpp.h, brg_types.h, aesaux.h and aestst.h
+        C source:   aesaux.c, aesrav.c
+        defines:    DLL_IMPORT
+
+    time_dll:       Win32 (x64 for the C and AMD64 versions)
+        headers:    aes.h, aescpp.h, brg_types.h, aesaux.h aestst.h and rdtsc.h
+        C source:   aesaux.c, aestmr.c
+        defines:    DLL_IMPORT
+
+and default to linkingto with the AES DLL using dynamic (run-time) linking.  Implicit
+linking can be used by adding the lib file associated with the AES DLL (in the aes\dll
+sub-directory) to the build (under project Properties|Linker in Visual Studio) and 
+removing the DLL_DYNAMIC_LOAD define (under project Properties|C/C++|Preprocessor).
+
+0  Link is linked into this project and the symbol
+DLL_DYNAMIC_LOAD is left undefined, then implicit linking will be used
+
+The above tests take command line arguments that determine which test are run
+as follows:
+
+    test_lib /t:[knec] /k:[468]
+    test_dll /t:[knec] /k:[468]
+
+where the symbols in square brackets can be used in any combination (without
+the brackets) and have the following meanings:
+
+        /t:[knec]   selects which tests are used
+        /k:[468]    selects the key lengths used
+        /c          compares output with reference (see later)
+
+        k: generate ECB Known Answer Test files
+        n: generate ECB Known Answer Test files (new)
+        e: generate ECB Monte Carlo Test files
+        c: generate CBC Monte Carlo Test files
+
+and the characters giving the lengths are digits representing the key lengths
+in 32-bit units (4, 6, 8 for lengths of 128, 192 or 256 bits respectively).
+
+The project test_modes tests the AES modes.  It uses the files:
+
+    test_modes:     Win32 or x64
+        headers:    aes.h, aescpp.h, brg_types.h, aesaux,h and aestst.h
+        C source:   aesaux.c, modetest.c
+        defines:    none for static library test, DLL_IMPORT for DLL test
+
+which again links to the last library built.
+
+E. Other Applications
+---------------------
+
+These are:
+
+    gen_tests       builds the test_vector files. The commad line is
+                        gen_tests /t:knec /k:468 /c
+                    as described earlier
+                    
+    test_aes_avs    run the AES Algorithm Validation Suite tests for
+                    ECB, CBC, CFB and OFB modes
+
+    gen_tables      builds a simple version of aes_tab.c (in aestab2.c)
+                    for compilers that cannot handle the normal version
+    aes_example     provides an example of AES use
+
+These applications are linked to the last static library built or, if
+DLL_IMPORT is defined during compilation, to the last DLL built.
+
+F. Use of the VIA ACE Cryptography Engine (x86 only)
+----------------------------------------------------
+
+The use of the code with the VIA ACE cryptography engine in described in the
+file via_ace.txt. In outline aes_modes.c is used and USE_VIA_ACE_IF_PRESENT
+is defined either in section 2 of aesopt.h or as a compilation option in Visual
+Studio. If in addition ASSUME_VIA_ACE_PRESENT is also defined then all normal
+AES code will be removed if not needed to support VIA ACE use.  If VIA ACE
+support is needed and AES assembler is being used only the ASM_X86_V1C and
+ASM_X86_V2C versions should be used since ASM_X86_V2 and ASM_AMD64 do not
+support the VIA ACE engine.
+
+G. The AES Test Vector Files
+----------------------------
 
 These files fall in the following groups (where <nn> is a two digit
 number):
 
 1. ecbvk<nn>.txt  ECB vectors with variable key
 2. ecbvt<nn>.txt  ECB vectors with variable text
-3. ecbnk<nn>.txt  new ECB vectors with variable key 
+3. ecbnk<nn>.txt  new ECB vectors with variable key
 4. ecbnt<nn>.txt  new ECB vectors with variable text
 5. ecbme<nn>.txt  ECB monte carlo encryption test vectors
 6. ecbmd<nn>.txt  ECB monte carlo decryption test vectors
 7. cbcme<nn>.txt  CBC monte carlo encryption test vectors
 8. cbcmd<nn>.txt  CBC monte carlo decryption test vectors
 
-The first digit of the numeric suffix on the filename gives the 
-block size in 32bit units and the second numeric digit gives the
-key size.  For example, the file ecbvk44.txt provides the test 
-vectors for ECB encryption with a 128 bit block size and a 128 
-bit key size.
+The first digit of the numeric suffix on the filename gives the block size
+in 32 bit units and the second numeric digit gives the key size. For example,
+the file ecbvk44.txt provides the test vectors for ECB encryption with a 128
+bit block size and a 128 bit key size. The test routines expect to find these
+files in the 'testvals' subdirectory within the aes root directory. The
+'outvals' subdirectory is used for outputs that are compared with the files
+in 'testvals'. Note that the monte carlo test vectors are the result of
+applying AES iteratively 10000 times, not just once.
+
+The AES Algorithm Validation Suite tests can be run for ECB, CBC, CFB and 
+OFB modes (CFB1 and CFB8 are not implemented).  The test routine uses the 
+*.fax test files, which should be placed in the 'testvals\fax' subdirectory.
+
+H. The Basic AES Calling Interface
+----------------------------------
+
+The basic AES code keeps its state in a context, there being different 
+contexts for encryption and decryption:
+
+    aes_encrypt_ctx
+    aes_decrypt_ctx
+    
+The AES code is initialised with the call
+
+    aes_init(void)
+    
+although this is only essential if the option to generate the AES tables at 
+run-time has been set in the options (i.e.fixed tables are not being used).
+    
+The AES encryption key is set by one of the calls:
+    aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1])
+    aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1])
+    aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1])
+
+or by:
+
+    aes_encrypt_key(const unsigned char *key, int key_len, 
+                                                aes_encrypt_ctx cx[1])
+
+where the key length is set by 'key_len', which can be the length in bits 
+or bytes.  
+
+Similarly, the AES decryption key is set by one of:
+
+    aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1])
+    aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1])
+    aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1])
+
+or by:
+
+    aes_decrypt_key(const unsigned char *key, int key_len, 
+                                                aes_decrypt_ctx cx[1])
+Encryption and decryption for a single 16 byte block is then achieved using:
+
+    aes_encrypt(const unsigned char *in, unsigned char *out, 
+                                            const aes_encrypt_ctx cx[1])
+    aes_decrypt(const unsigned char *in, unsigned char *out, 
+                                            const aes_decrypt_ctx cx[1])
+                                            
+The above subroutines return a value of EXIT_SUCCESS or EXIT_FAILURE 
+depending on whether the operation succeeded or failed.
+I. The Calling Interface for the AES Modes
+------------------------------------------
+
+The subroutines for the AES modes, ECB, CBC, CFB, OFB and CTR, each process
+blocks of variable length and can also be called several times to complete 
+single mode operations incrementally on long messages (or those messages,
+not all of which are available at the same time).  The calls:
+
+    aes_ecb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, const aes_encrypt_ctx cx[1])
+
+    aes_ecb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, const aes_decrypt_ctx cx[1])
+
+for ECB operations and those for CBC:
+
+    aes_cbc_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, const aes_encrypt_ctx cx[1])
+
+    aes_cbc_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, const aes_decrypt_ctx cx[1])
+can only process blocks whose lengths are multiples of 16 bytes but the calls 
+for CFB, OFB and CTR mode operations:
+
+    aes_cfb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1])
+
+    aes_cfb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1])
+
+    aes_ofb_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1])
+
+    aes_ofb_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+                    int len, unsigned char *iv, aes_encrypt_ctx cx[1])
+
+    aes_ctr_encrypt(const unsigned char *ibuf, unsigned char *obuf,
+            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1])
+
+    aes_ctr_decrypt(const unsigned char *ibuf, unsigned char *obuf,
+            int len, unsigned char *cbuf, cbuf_inc ctr_inc, aes_encrypt_ctx cx[1])
+
+can process blocks of any length.  Note also that CFB, OFB and CTR mode calls only
+use AES encryption contexts even during decryption operations.
+
+The calls CTR mode operations use a buffer (cbuf) which holds the counter value
+together with a function parameter:
+
+    void cbuf_inc(unsigned char *cbuf);
+
+that is ued to update the counter value after each 16 byte AES operation. The 
+counter buffer is updated appropriately to allow for incremental operations.
+
+Please note the following IMPORTANT points about the AES mode subroutines:
 
-   Brian Gladman <brg@gladman.uk.net>
\ No newline at end of file
+    1. All modes are reset when a new AES key is set.
+    
+    2. Incremental calls to the different modes cannot 
+       be mixed. If a change of mode is needed a new 
+       key must be set or a reset must be issued (see 
+       below).
+       
+    3. For modes with IVs, the IV value is an input AND
+       an output since it is updated after each call to 
+       the value needed for any subsequent incremental
+       call(s). If the mode is reset, the IV hence has
+       to be set (or reset) as well.
+       
+    4. ECB operations must be multiples of 16 bytes
+       but do not need to be reset for new operations.
+       
+    5. CBC operations must also be multiples of 16 
+       bytes and are reset for a new operation by 
+       setting the IV.
+       
+    6. CFB, OFB and CTR mode must be reset by setting 
+       a new IV value AND by calling:
+       
+           aes_mode_reset(aes_encrypt_ctx cx[1])
+           
+       For CTR mode the cbuf value also has to be reset.
+       
+    7. CFB, OFB and CTR modes only use AES encryption 
+       operations and contexts and do not need AES
+       decryption operations.
+       
+    8. AES keys remain valid across resets and changes
+       of mode (but encryption and decryption keys must 
+       both be set if they are needed).  
+       
+   Brian Gladman  26/09/2018
\ No newline at end of file
diff --git a/src/lib/crypto/builtin/aes/aescpp.h b/src/lib/crypto/builtin/aes/aescpp.h
deleted file mode 100644 (file)
index d556224..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-/*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * TERMS
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted subject to the following conditions:
- *
- *  1. Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *
- *  2. Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *
- *  3. The copyright holder's name must not be used to endorse or promote
- *     any products derived from this software without his specific prior
- *     written permission.
- *
- * This software is provided 'as is' with no express or implied warranties
- * of correctness or fitness for purpose.
- */
-
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the definitions required to use AES (Rijndael) in C++.
- */
-
-#ifndef _AESCPP_H
-#define _AESCPP_H
-
-#include "aes.h"
-
-class AESclass
-{   aes_ctx cx[1];
-public:
-#if defined(BLOCK_SIZE)
-    AESclass()                          { cx->n_blk = BLOCK_SIZE; cx->n_rnd = 0; }
-#else
-    AESclass(unsigned int blen = 16)    { cx->n_blk = blen; cx->n_rnd = 0; }
-#endif
-    aes_rval blk_len(unsigned int blen) { return aes_blk_len(blen, cx); }
-    aes_rval enc_key(const unsigned char in_key[], unsigned int klen)
-            { return aes_enc_key(in_key, klen, cx); }
-    aes_rval dec_key(const unsigned char in_key[], unsigned int klen)
-            { return aes_dec_key(in_key, klen, cx); }
-    aes_rval enc_blk(const unsigned char in_blk[], unsigned char out_blk[])
-            { return aes_enc_blk(in_blk, out_blk, cx); }
-    aes_rval dec_blk(const unsigned char in_blk[], unsigned char out_blk[])
-            { return aes_dec_blk(in_blk, out_blk, cx); }
-};
-
-#endif
diff --git a/src/lib/crypto/builtin/aes/aescrypp.c b/src/lib/crypto/builtin/aes/aescrypp.c
deleted file mode 100644 (file)
index 1f1cf63..0000000
+++ /dev/null
@@ -1,488 +0,0 @@
-/*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
-
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the code for implementing encryption and decryption
- * for AES (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
- * It can optionally be replaced by code written in assembler using NASM.
- */
-
-#include "aesopt.h"
-
-#define unused  77  /* Sunset Strip */
-
-#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
-
-#if BLOCK_SIZE == 16
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[4],y[4]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
- /*
-   the following defines prevent the compiler requiring the declaration
-   of generated but unused variables in the fwd_var and inv_var macros
- */
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
-
-#elif BLOCK_SIZE == 20
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[5],y[5]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,y##0,y##1,y##2,y##3,y##4
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); s(y,4) = s(x,4);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); si(y,x,k,4)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); so(y,x,4)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); rm(y,x,k,4)
-
-#elif BLOCK_SIZE == 24
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[6],y[6]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5, \
-                        y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-
-#elif BLOCK_SIZE == 28
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[7],y[7]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6 \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6
-#define b07 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);; s(y,6) = s(x,6);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5); si(y,x,k,6)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5); so(y,x,6)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[8],y[8]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5); \
-                        s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-                        si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-                        so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-                        rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{   case 8: si(y,x,k,7); \
-    case 7: si(y,x,k,6); \
-    case 6: si(y,x,k,5); \
-    case 5: si(y,x,k,4); \
-    case 4: si(y,x,k,3); si(y,x,k,2); \
-            si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{   case 8: so(y,x,7); \
-    case 7: so(y,x,6); \
-    case 6: so(y,x,5); \
-    case 5: so(y,x,4); \
-    case 4: so(y,x,3); so(y,x,2); \
-            so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-            rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 7: rm(y,x,k,6); rm(y,x,k,5); \
-            rm(y,x,k,4); rm(y,x,k,3); \
-            rm(y,x,k,2); rm(y,x,k,1); \
-            rm(y,x,k,0); \
-            break; \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 5: rm(y,x,k,4); rm(y,x,k,3); \
-            rm(y,x,k,2); rm(y,x,k,1); \
-            rm(y,x,k,0); \
-            break; \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); \
-    case 7: rm(y,x,k,6); \
-    case 6: rm(y,x,k,5); \
-    case 5: rm(y,x,k,4); \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
-
-#endif
-#endif
-
-#if defined(ENCRYPTION)
-
-/* I am grateful to Frank Yellin for the following construction
-   (and that for decryption) which, given the column (c) of the
-   output state variable, gives the input state variables which
-   are needed for each row (r) of the state.
-
-   For the fixed block size options, compilers should reduce these
-   two expressions to fixed variable references. But for variable
-   block size code conditional clauses will sometimes be returned.
-
-   y = output word, x = input word, r = row, c = column for r = 0,
-   1, 2 and 3 = column accessed for row r.
-*/
-
-#define fwd_var(x,r,c) \
- ( r==0 ?           \
-    ( c==0 ? s(x,0) \
-    : c==1 ? s(x,1) \
-    : c==2 ? s(x,2) \
-    : c==3 ? s(x,3) \
-    : c==4 ? s(x,4) \
-    : c==5 ? s(x,5) \
-    : c==6 ? s(x,6) \
-    : s(x,7))       \
- : r==1 ?           \
-    ( c==0 ? s(x,1) \
-    : c==1 ? s(x,2) \
-    : c==2 ? s(x,3) \
-    : c==3 ? nc==4 ? s(x,0) : s(x,4) \
-    : c==4 ? nc==5 ? s(x,0) : s(x,5) \
-    : c==5 ? nc==6 ? s(x,0) : s(x,6) \
-    : c==6 ? nc==7 ? s(x,0) : s(x,7) \
-    : s(x,0))       \
- : r==2 ?           \
-    ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
-    : c==1 ? nc==8 ? s(x,4) : s(x,3) \
-    : c==2 ? nc==8 ? s(x,5) : nc==4 ? s(x,0) : s(x,4) \
-    : c==3 ? nc==8 ? s(x,6) : nc==5 ? s(x,0) : nc==4 ? s(x,1) : s(x,5) \
-    : c==4 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : nc==6 ? s(x,0) : s(x,1) \
-    : c==5 ? nc==6 ? s(x,1) : s(x,0) \
-    : c==6 ? s(x,1) \
-    : s(x,2))       \
- :                  \
-    ( c==0 ? nc>6  ? s(x,4) : s(x,3) \
-    : c==1 ? nc>6  ? s(x,5) : nc==4 ? s(x,0) : s(x,4) \
-    : c==2 ? nc>6  ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,0) : s(x,1) \
-    : c==3 ? nc==8 ? s(x,7) : nc==5 ? s(x,1) : nc==4 ? s(x,2) : s(x,0) \
-    : c==4 ? nc==8 ? s(x,0) : nc==5 ? s(x,2) : s(x,1) \
-    : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-    : c==6 ? nc==8 ? s(x,2) : s(x,3) \
-    : s(x,3)))
-
-#if defined(FT4_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
-#elif defined(FT1_SET)
-#undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
-#else
-#define fwd_rnd(y,x,k,c)    s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
-#endif
-
-#if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
-#elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
-#else
-#define fwd_lrnd(y,x,k,c)   s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
-#endif
-
-aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
-{   uint32_t        locals(b0, b1);
-    const uint32_t  *kp = cx->k_sch;
-    dec_fmvars  /* declare variables for fwd_mcol() if needed */
-
-    if(!(cx->n_blk & 1)) return aes_bad;
-
-#if (ENC_UNROLL == FULL)
-
-    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
-    kp += (cx->n_rnd - 9) * nc;
-
-    switch(cx->n_rnd)
-    {
-    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc);
-    case 13:    round(fwd_rnd,  b0, b1, kp - 3 * nc);
-    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc);
-    case 11:    round(fwd_rnd,  b0, b1, kp -     nc);
-    case 10:    round(fwd_rnd,  b1, b0, kp         );
-                round(fwd_rnd,  b0, b1, kp +     nc);
-                round(fwd_rnd,  b1, b0, kp + 2 * nc);
-                round(fwd_rnd,  b0, b1, kp + 3 * nc);
-                round(fwd_rnd,  b1, b0, kp + 4 * nc);
-                round(fwd_rnd,  b0, b1, kp + 5 * nc);
-                round(fwd_rnd,  b1, b0, kp + 6 * nc);
-                round(fwd_rnd,  b0, b1, kp + 7 * nc);
-                round(fwd_rnd,  b1, b0, kp + 8 * nc);
-                round(fwd_lrnd, b0, b1, kp + 9 * nc);
-    }
-#else
-    {   uint32_t    rnd;
-
-        state_in(b0, in_blk, kp);
-
-#if (ENC_UNROLL == PARTIAL)
-
-        for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, b1, b0, kp);
-            kp += nc;
-            round(fwd_rnd, b0, b1, kp);
-        }
-
-        if(cx->n_rnd & 1)
-        {
-            l_copy(b1, b0);
-        }
-        else
-        {
-            kp += nc;
-            round(fwd_rnd,  b1, b0, kp);
-        }
-#else
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp += nc;
-            round(fwd_rnd, b1, b0, kp);
-            l_copy(b0, b1);
-        }
-#endif
-        kp += nc;
-        round(fwd_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION)
-
-#define inv_var(x,r,c) \
- ( r==0 ?           \
-    ( c==0 ? s(x,0) \
-    : c==1 ? s(x,1) \
-    : c==2 ? s(x,2) \
-    : c==3 ? s(x,3) \
-    : c==4 ? s(x,4) \
-    : c==5 ? s(x,5) \
-    : c==6 ? s(x,6) \
-    : s(x,7))       \
- : r==1 ?           \
-    ( c==0 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,4) : s(x,3) \
-    : c==1 ? s(x,0) \
-    : c==2 ? s(x,1) \
-    : c==3 ? s(x,2) \
-    : c==4 ? s(x,3) \
-    : c==5 ? s(x,4) \
-    : c==6 ? s(x,5) \
-    : s(x,6))       \
- : r==2 ?           \
-    ( c==0 ? nc>6  ? s(x,5) : nc==6 ? s(x,4) : nc==5 ? s(x,3) : s(x,2) \
-    : c==1 ? nc>6  ? s(x,6) : nc==6 ? s(x,5) : nc==5 ? s(x,4) : s(x,3) \
-    : c==2 ? nc==8 ? s(x,7) : s(x,0) \
-    : c==3 ? nc==8 ? s(x,0) : s(x,1) \
-    : c==4 ? nc==8 ? s(x,1) : s(x,2) \
-    : c==5 ? nc==8 ? s(x,2) : s(x,3) \
-    : c==6 ? nc==8 ? s(x,3) : s(x,4) \
-    : s(x,4))       \
- :                  \
-    ( c==0 ? nc==8 ? s(x,4) : nc==5 ? s(x,2) : nc==4 ? s(x,1) : s(x,3) \
-    : c==1 ? nc==8 ? s(x,5) : nc==5 ? s(x,3) : nc==4 ? s(x,2) : s(x,4) \
-    : c==2 ? nc==8 ? s(x,6) : nc==5 ? s(x,4) : nc==4 ? s(x,3) : s(x,5) \
-    : c==3 ? nc==8 ? s(x,7) : nc==7 ? s(x,6) : s(x,0) \
-    : c==4 ? nc>6  ? s(x,0) : s(x,1) \
-    : c==5 ? nc==6 ? s(x,2) : s(x,1) \
-    : c==6 ? s(x,2) \
-    : s(x,3)))
-
-#if defined(IT4_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
-#elif defined(IT1_SET)
-#undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
-#else
-#define inv_rnd(y,x,k,c)    s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
-#endif
-
-#if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
-#elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
-#else
-#define inv_lrnd(y,x,k,c)   s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
-#endif
-
-aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
-{   uint32_t        locals(b0, b1);
-    const uint32_t  *kp = cx->k_sch + nc * cx->n_rnd;
-    dec_imvars  /* declare variables for inv_mcol() if needed */
-
-    if(!(cx->n_blk & 2)) return aes_bad;
-
-#if (DEC_UNROLL == FULL)
-
-    state_in((cx->n_rnd & 1 ? b1 : b0), in_blk, kp);
-    kp = cx->k_sch + 9 * nc;
-
-    switch(cx->n_rnd)
-    {
-    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
-    case 13:    round(inv_rnd,  b0, b1, kp + 3 * nc);
-    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
-    case 11:    round(inv_rnd,  b0, b1, kp +     nc);
-    case 10:    round(inv_rnd,  b1, b0, kp         );
-                round(inv_rnd,  b0, b1, kp -     nc);
-                round(inv_rnd,  b1, b0, kp - 2 * nc);
-                round(inv_rnd,  b0, b1, kp - 3 * nc);
-                round(inv_rnd,  b1, b0, kp - 4 * nc);
-                round(inv_rnd,  b0, b1, kp - 5 * nc);
-                round(inv_rnd,  b1, b0, kp - 6 * nc);
-                round(inv_rnd,  b0, b1, kp - 7 * nc);
-                round(inv_rnd,  b1, b0, kp - 8 * nc);
-                round(inv_lrnd, b0, b1, kp - 9 * nc);
-    }
-#else
-    {   uint32_t    rnd;
-
-        state_in(b0, in_blk, kp);
-
-#if (DEC_UNROLL == PARTIAL)
-
-        for(rnd = 0; rnd < (cx->n_rnd - 1) >> 1; ++rnd)
-        {
-            kp -= nc;
-            round(inv_rnd, b1, b0, kp);
-            kp -= nc;
-            round(inv_rnd, b0, b1, kp);
-        }
-
-        if(cx->n_rnd & 1)
-        {
-            l_copy(b1, b0);
-        }
-        else
-        {
-            kp -= nc;
-            round(inv_rnd,  b1, b0, kp);
-        }
-#else
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
-        {
-            kp -= nc;
-            round(inv_rnd, b1, b0, kp);
-            l_copy(b0, b1);
-        }
-#endif
-        kp -= nc;
-        round(inv_lrnd, b0, b1, kp);
-    }
-#endif
-
-    state_out(out_blk, b0);
-    return aes_good;
-}
-
-#endif
diff --git a/src/lib/crypto/builtin/aes/aescrypt.asm b/src/lib/crypto/builtin/aes/aescrypt.asm
deleted file mode 100644 (file)
index 25070f0..0000000
+++ /dev/null
@@ -1,402 +0,0 @@
-
-; -------------------------------------------------------------------------
-; Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
-; All rights reserved.
-;
-; LICENSE TERMS
-;
-; The free distribution and use of this software in both source and binary 
-; form is allowed (with or without changes) provided that:
-;
-;   1. distributions of this source code include the above copyright 
-;      notice, this list of conditions and the following disclaimer;
-;
-;   2. distributions in binary form include the above copyright
-;      notice, this list of conditions and the following disclaimer
-;      in the documentation and/or other associated materials;
-;
-;   3. the copyright holder's name is not used to endorse products 
-;      built using this software without specific written permission.
-;
-; DISCLAIMER
-;
-; This software is provided 'as is' with no explcit or implied warranties
-; in respect of any properties, including, but not limited to, correctness 
-; and fitness for purpose.
-; -------------------------------------------------------------------------
-; Issue Date: 15/01/2002
-
-; An AES (Rijndael) implementation for the Pentium MMX family using the NASM
-; assembler <https://www.nasm.us>. This version only implements
-; the standard AES block length (128 bits, 16 bytes) with the same interface
-; as that used in my C/C++ implementation.   This code does not preserve the
-; eax, ecx or edx registers or the artihmetic status flags. However, the ebx, 
-; esi, edi, and ebp registers are preserved across calls.    Only encryption
-; and decryption are implemented here, the key schedule code being that from
-; compiling aes.c with USE_ASM defined.  This code uses VC++ register saving
-; conentions; if it is used with another compiler, its conventions for using
-; and saving registers will need to be checked.
-
-    section .text use32
-
-; aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
-; aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
-
-    global  _aes_enc_blk
-    global  _aes_dec_blk
-    
-    extern  _ft_tab
-    extern  _fl_tab
-    extern  _it_tab
-    extern  _il_tab
-
-;%define USE_MMX   ; include this to use MMX registers for temporary storage
-;%define USE_EMMS    ; include this if you make use of floating point operations
-
-%ifdef  USE_MMX
-%ifdef  USE_EMMS
-%define EMMS_ON
-%endif
-%endif
-
-tlen:   equ  1024   ; length of each of 4 'xor' arrays (256 32-bit words)
-
-; offsets to parameters with one register pushed onto stack
-
-in_blk: equ     8   ; input byte array address parameter
-out_blk:equ    12   ; output byte array address parameter
-ctx:    equ    16   ; AES context structure
-
-; offsets in context structure
-
-ksch:   equ     0   ; encryption key schedule base address
-nrnd:   equ   256   ; number of rounds
-nblk:   equ   260   ; number of rounds
-
-; register mapping for encrypt and decrypt subroutines
-
-%define r0  eax
-%define r1  ebx
-%define r2  ecx
-%define r3  edx
-%define r4  esi
-%define r5  edi
-%define r6  ebp
-
-%define eaxl  al
-%define eaxh  ah
-%define ebxl  bl
-%define ebxh  bh
-%define ecxl  cl
-%define ecxh  ch
-%define edxl  dl
-%define edxh  dh
-
-; This macro takes a 32-bit word representing a column and uses
-; each of its four bytes to index into four tables of 256 32-bit
-; words to obtain values that are then xored into the appropriate
-; output registers r0, r1, r4 or r5.  
-
-; Parameters:
-;   %1  out_state[0]
-;   %2  out_state[1]
-;   %3  out_state[2]
-;   %4  out_state[3]
-;   %5  table base address
-;   %6  input register for the round (destroyed)
-;   %7  scratch register for the round
-
-%macro do_col 7
-
-    movzx   %7,%6l
-    xor     %1,[4*%7+%5]
-    movzx   %7,%6h
-    shr     %6,16
-    xor     %2,[4*%7+%5+tlen]
-    movzx   %7,%6l
-    movzx   %6,%6h
-    xor     %3,[4*%7+%5+2*tlen] 
-    xor     %4,[4*%6+%5+3*tlen]
-
-%endmacro
-
-; initialise output registers from the key schedule
-
-%macro do_fcol 8
-
-    mov     %1,[%8]
-    movzx   %7,%6l
-    mov     %2,[%8+12]
-    xor     %1,[4*%7+%5]
-    mov     %4,[%8+ 4]
-    movzx   %7,%6h
-    shr     %6,16
-    xor     %2,[4*%7+%5+tlen]
-    movzx   %7,%6l
-    movzx   %6,%6h
-    xor     %4,[4*%6+%5+3*tlen]
-    mov     %6,%3
-    mov     %3,[%8+ 8]
-    xor     %3,[4*%7+%5+2*tlen] 
-
-%endmacro
-
-; initialise output registers from the key schedule
-
-%macro do_icol 8
-
-    mov     %1,[%8]
-    movzx   %7,%6l
-    mov     %2,[%8+ 4]
-    xor     %1,[4*%7+%5]
-    mov     %4,[%8+12]
-    movzx   %7,%6h
-    shr     %6,16
-    xor     %2,[4*%7+%5+tlen]
-    movzx   %7,%6l
-    movzx   %6,%6h
-    xor     %4,[4*%6+%5+3*tlen]
-    mov     %6,%3
-    mov     %3,[%8+ 8]
-    xor     %3,[4*%7+%5+2*tlen] 
-
-%endmacro
-
-; These macros implement either MMX or stack based local variables
-
-%ifdef  USE_MMX
-
-%macro  save 2
-    movd    mm%1,%2
-%endmacro
-
-%macro  restore 2
-    movd    %1,mm%2
-%endmacro
-
-%else
-
-%macro  save 2
-    mov     [esp+4*%1],%2
-%endmacro
-
-%macro  restore 2
-    mov     %1,[esp+4*%2]
-%endmacro
-
-%endif
-
-; This macro performs a forward encryption cycle. It is entered with
-; the first previous round column values in r0, r1, r4 and r5 and
-; exits with the final values in the same registers, using the MMX
-; registers mm0-mm1 for temporary storage
-
-%macro fwd_rnd 1-2 _ft_tab
-
-; mov current column values into the MMX registers
-
-    mov     r2,r0
-    save    0,r1
-    save    1,r5
-
-; compute new column values
-
-    do_fcol r0,r5,r4,r1, %2, r2,r3, %1
-    do_col  r4,r1,r0,r5, %2, r2,r3
-    restore r2,0
-    do_col  r1,r0,r5,r4, %2, r2,r3
-    restore r2,1
-    do_col  r5,r4,r1,r0, %2, r2,r3
-
-%endmacro
-
-; This macro performs an inverse encryption cycle. It is entered with
-; the first previous round column values in r0, r1, r4 and r5 and
-; exits with the final values in the same registers, using the MMX
-; registers mm0-mm1 for temporary storage
-
-%macro inv_rnd 1-2 _it_tab
-
-; mov current column values into the MMX registers
-
-    mov     r2,r0
-    save    0,r1
-    save    1,r5
-
-; compute new column values
-
-    do_icol r0,r1,r4,r5, %2, r2,r3, %1
-    do_col  r4,r5,r0,r1, %2, r2,r3
-    restore r2,0
-    do_col  r1,r4,r5,r0, %2, r2,r3
-    restore r2,1
-    do_col  r5,r0,r1,r4, %2, r2,r3
-
-%endmacro
-
-; AES (Rijndael) Encryption Subroutine
-
-_aes_enc_blk:
-    push    ebp
-    mov     ebp,[esp+ctx]       ; pointer to context
-    xor     eax,eax
-    test    [ebp+nblk],byte 1
-    je      .0
-    cmp     eax,[ebp+nrnd]      ; encryption/decryption flags
-    jne     short .1
-.0: pop     ebp
-    ret            
-
-; CAUTION: the order and the values used in these assigns 
-; rely on the register mappings
-
-.1: push    ebx
-    mov     r2,[esp+in_blk+4]
-    push    esi
-    mov     r3,[ebp+nrnd]   ; number of rounds
-    push    edi
-    lea     r6,[ebp+ksch]   ; key pointer
-
-; input four columns and xor in first round key
-
-    mov     r0,[r2]
-    mov     r1,[r2+4]
-    mov     r4,[r2+8]
-    mov     r5,[r2+12]
-    xor     r0,[r6]
-    xor     r1,[r6+4]
-    xor     r4,[r6+8]
-    xor     r5,[r6+12]
-
-%ifndef USE_MMX
-    sub     esp,8           ; space for register saves on stack
-%endif
-    add     r6,16           ; increment to next round key   
-    sub     r3,10          
-    je      .4              ; 10 rounds for 128-bit key
-    add     r6,32  
-    sub     r3,2
-    je      .3              ; 12 rounds for 128-bit key
-    add     r6,32  
-
-.2: fwd_rnd r6-64           ; 14 rounds for 128-bit key
-    fwd_rnd r6-48  
-.3: fwd_rnd r6-32           ; 12 rounds for 128-bit key
-    fwd_rnd r6-16  
-.4: fwd_rnd r6              ; 10 rounds for 128-bit key
-    fwd_rnd r6+ 16 
-    fwd_rnd r6+ 32
-    fwd_rnd r6+ 48
-    fwd_rnd r6+ 64
-    fwd_rnd r6+ 80
-    fwd_rnd r6+ 96
-    fwd_rnd r6+112
-    fwd_rnd r6+128
-    fwd_rnd r6+144,_fl_tab  ; last round uses a different table
-
-; move final values to the output array.  CAUTION: the 
-; order of these assigns rely on the register mappings
-
-%ifndef USE_MMX
-    add     esp,8
-%endif
-    mov     r6,[esp+out_blk+12]
-    mov     [r6+12],r5
-    pop     edi
-    mov     [r6+8],r4
-    pop     esi
-    mov     [r6+4],r1
-    pop     ebx
-    mov     [r6],r0
-    pop     ebp
-    mov     eax,1
-%ifdef  EMMS_ON
-    emms
-%endif
-    ret
-
-; AES (Rijndael) Decryption Subroutine
-
-_aes_dec_blk:
-    push    ebp
-    mov     ebp,[esp+ctx]       ; pointer to context
-    xor     eax,eax
-    test    [ebp+nblk],byte 2
-    je      .0
-    cmp     eax,[ebp+nrnd]      ; encryption/decryption flags
-    jne     short .1
-.0: pop     ebp
-    ret            
-
-; CAUTION: the order and the values used in these assigns 
-; rely on the register mappings
-
-.1: push    ebx
-    mov     r2,[esp+in_blk+4]
-    push    esi
-    mov     r3,[ebp+nrnd]   ; number of rounds
-    push    edi
-    lea     r6,[ebp+ksch]   ; key pointer
-    mov     r0,r3
-    shl     r0,4
-    add     r6,r0
-    
-; input four columns and xor in first round key
-
-    mov     r0,[r2]
-    mov     r1,[r2+4]
-    mov     r4,[r2+8]
-    mov     r5,[r2+12]
-    xor     r0,[r6]
-    xor     r1,[r6+4]
-    xor     r4,[r6+8]
-    xor     r5,[r6+12]
-
-%ifndef USE_MMX
-    sub     esp,8           ; space for register saves on stack
-%endif
-    sub     r6,16           ; increment to next round key   
-    sub     r3,10          
-    je      .4              ; 10 rounds for 128-bit key
-    sub     r6,32  
-    sub     r3,2
-    je      .3              ; 12 rounds for 128-bit key
-    sub     r6,32  
-
-.2: inv_rnd r6+64           ; 14 rounds for 128-bit key 
-    inv_rnd r6+48  
-.3: inv_rnd r6+32           ; 12 rounds for 128-bit key
-    inv_rnd r6+16  
-.4: inv_rnd r6              ; 10 rounds for 128-bit key
-    inv_rnd r6- 16 
-    inv_rnd r6- 32
-    inv_rnd r6- 48
-    inv_rnd r6- 64
-    inv_rnd r6- 80
-    inv_rnd r6- 96
-    inv_rnd r6-112
-    inv_rnd r6-128
-    inv_rnd r6-144,_il_tab  ; last round uses a different table
-
-; move final values to the output array.  CAUTION: the 
-; order of these assigns rely on the register mappings
-
-%ifndef USE_MMX
-    add     esp,8
-%endif
-    mov     r6,[esp+out_blk+12]
-    mov     [r6+12],r5
-    pop     edi
-    mov     [r6+8],r4
-    pop     esi
-    mov     [r6+4],r1
-    pop     ebx
-    mov     [r6],r0
-    pop     ebp
-    mov     eax,1
-%ifdef  EMMS_ON
-    emms
-%endif
-    ret
-
-    end
index 194f8e54dbe4aec7e15df0ee50649f25d4311e33..4c2b0db1c67a575e8cf977349375eaa9acde0943 100644 (file)
 /*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
 
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the code for implementing encryption and decryption
- * for AES (Rijndael) for block and key sizes of 16, 24 and 32 bytes. It
- * can optionally be replaced by code written in assembler using NASM.
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
+
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
+
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 20/12/2007
 */
 
 #include "aesopt.h"
+#include "aestab.h"
 
-#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
-#error An illegal block size has been specified.
+#if defined( USE_INTEL_AES_IF_PRESENT )
+#  include "aes_ni.h"
+#else
+/* map names here to provide the external API ('name' -> 'aes_name') */
+#  define aes_xi(x) aes_ ## x
 #endif
 
-#define unused  77  /* Sunset Strip */
-
-#define si(y,x,k,c) s(y,c) = word_in(x + 4 * c) ^ k[c]
-#define so(y,x,c)   word_out(y + 4 * c, s(x,c))
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
 
-#if BLOCK_SIZE == 16
+#define si(y,x,k,c) (s(y,c) = word_in(x, c) ^ (k)[c])
+#define so(y,x,c)   word_out(y, c, s(x,c))
 
 #if defined(ARRAYS)
 #define locals(y,x)     x[4],y[4]
 #else
 #define locals(y,x)     x##0,x##1,x##2,x##3,y##0,y##1,y##2,y##3
- /*
-   the following defines prevent the compiler requiring the declaration
-   of generated but unused variables in the fwd_var and inv_var macros
- */
-#define b04 unused
-#define b05 unused
-#define b06 unused
-#define b07 unused
-#define b14 unused
-#define b15 unused
-#define b16 unused
-#define b17 unused
 #endif
+
 #define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
                         s(y,2) = s(x,2); s(y,3) = s(x,3);
 #define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3)
 #define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3)
 #define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3)
 
-#elif BLOCK_SIZE == 24
+#if ( FUNCS_IN_C & ENCRYPTION_IN_C )
 
-#if defined(ARRAYS)
-#define locals(y,x)     x[6],y[6]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5, \
-                        y##0,y##1,y##2,y##3,y##4,y##5
-#define b06 unused
-#define b07 unused
-#define b16 unused
-#define b17 unused
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5);
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); \
-                        si(y,x,k,3); si(y,x,k,4); si(y,x,k,5)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); \
-                        so(y,x,3); so(y,x,4); so(y,x,5)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); \
-                        rm(y,x,k,3); rm(y,x,k,4); rm(y,x,k,5)
-#else
-
-#if defined(ARRAYS)
-#define locals(y,x)     x[8],y[8]
-#else
-#define locals(y,x)     x##0,x##1,x##2,x##3,x##4,x##5,x##6,x##7, \
-                        y##0,y##1,y##2,y##3,y##4,y##5,y##6,y##7
-#endif
-#define l_copy(y, x)    s(y,0) = s(x,0); s(y,1) = s(x,1); \
-                        s(y,2) = s(x,2); s(y,3) = s(x,3); \
-                        s(y,4) = s(x,4); s(y,5) = s(x,5); \
-                        s(y,6) = s(x,6); s(y,7) = s(x,7);
-
-#if BLOCK_SIZE == 32
-
-#define state_in(y,x,k) si(y,x,k,0); si(y,x,k,1); si(y,x,k,2); si(y,x,k,3); \
-                        si(y,x,k,4); si(y,x,k,5); si(y,x,k,6); si(y,x,k,7)
-#define state_out(y,x)  so(y,x,0); so(y,x,1); so(y,x,2); so(y,x,3); \
-                        so(y,x,4); so(y,x,5); so(y,x,6); so(y,x,7)
-#define round(rm,y,x,k) rm(y,x,k,0); rm(y,x,k,1); rm(y,x,k,2); rm(y,x,k,3); \
-                        rm(y,x,k,4); rm(y,x,k,5); rm(y,x,k,6); rm(y,x,k,7)
-#else
-
-#define state_in(y,x,k) \
-switch(nc) \
-{   case 8: si(y,x,k,7); si(y,x,k,6); \
-    case 6: si(y,x,k,5); si(y,x,k,4); \
-    case 4: si(y,x,k,3); si(y,x,k,2); \
-            si(y,x,k,1); si(y,x,k,0); \
-}
-
-#define state_out(y,x) \
-switch(nc) \
-{   case 8: so(y,x,7); so(y,x,6); \
-    case 6: so(y,x,5); so(y,x,4); \
-    case 4: so(y,x,3); so(y,x,2); \
-            so(y,x,1); so(y,x,0); \
-}
-
-#if defined(FAST_VARIABLE)
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-            rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-            rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-            break; \
-}
-#else
-
-#define round(rm,y,x,k) \
-switch(nc) \
-{   case 8: rm(y,x,k,7); rm(y,x,k,6); \
-    case 6: rm(y,x,k,5); rm(y,x,k,4); \
-    case 4: rm(y,x,k,3); rm(y,x,k,2); \
-            rm(y,x,k,1); rm(y,x,k,0); \
-}
-
-#endif
+/* Visual C++ .Net v7.1 provides the fastest encryption code when using
+   Pentium optimisation with small code but this is poor for decryption
+   so we need to control this with the following VC++ pragmas
+*/
 
+#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
+#pragma optimize( "s", on )
 #endif
-#endif
-
-#if defined(ENCRYPTION)
-
-/* I am grateful to Frank Yellin for the following construction
-   (and that for decryption) which, given the column (c) of the
-   output state variable, gives the input state variables which
-   are needed in its computation for each row (r) of the state.
-
-   For the fixed block size options, compilers should be able to
-   reduce this complex expression (and the equivalent one for
-   decryption) to a static variable reference at compile time.
-   But for variable block size code, there will be some limbs on
-   which conditional clauses will be returned.
-*/
 
-/* y = output word, x = input word, r = row, c = column for r = 0,
-   1, 2 and 3 = column accessed for row r.
+/* Given the column (c) of the output state variable, the following
+   macros give the input state variables which are needed in its
+   computation for each row (r) of the state. All the alternative
+   macros give the same end values but expand into different ways
+   of calculating these values.  In particular the complex macro
+   used for dynamically variable block sizes is designed to expand
+   to a compile time constant whenever possible but will expand to
+   conditional clauses on some branches (I am grateful to Frank
+   Yellin for this construction)
 */
 
-#define fwd_var(x,r,c) \
- ( r==0 ?           \
-    ( c==0 ? s(x,0) \
-    : c==1 ? s(x,1) \
-    : c==2 ? s(x,2) \
-    : c==3 ? s(x,3) \
-    : c==4 ? s(x,4) \
-    : c==5 ? s(x,5) \
-    : c==6 ? s(x,6) \
-    : s(x,7))       \
- : r==1 ?           \
-    ( c==0 ? s(x,1) \
-    : c==1 ? s(x,2) \
-    : c==2 ? s(x,3) \
-    : c==3 ? nc==4 ? s(x,0) : s(x,4) \
-    : c==4 ? s(x,5) \
-    : c==5 ? nc==8 ? s(x,6) : s(x,0) \
-    : c==6 ? s(x,7) \
-    : s(x,0))       \
- : r==2 ?           \
-    ( c==0 ? nc==8 ? s(x,3) : s(x,2) \
-    : c==1 ? nc==8 ? s(x,4) : s(x,3) \
-    : c==2 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-    : c==3 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-    : c==4 ? nc==8 ? s(x,7) : s(x,0) \
-    : c==5 ? nc==8 ? s(x,0) : s(x,1) \
-    : c==6 ? s(x,1) \
-    : s(x,2))       \
- :                  \
-    ( c==0 ? nc==8 ? s(x,4) : s(x,3) \
-    : c==1 ? nc==4 ? s(x,0) : nc==8 ? s(x,5) : s(x,4) \
-    : c==2 ? nc==4 ? s(x,1) : nc==8 ? s(x,6) : s(x,5) \
-    : c==3 ? nc==4 ? s(x,2) : nc==8 ? s(x,7) : s(x,0) \
-    : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-    : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-    : c==6 ? s(x,2) \
-    : s(x,3)))
+#define fwd_var(x,r,c)\
+ ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
+ : r == 1 ? ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0))\
+ : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
+ :          ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2)))
 
 #if defined(FT4_SET)
 #undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ four_tables(x,ft_tab,fwd_var,rf1,c)
+#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,n),fwd_var,rf1,c))
 #elif defined(FT1_SET)
 #undef  dec_fmvars
-#define dec_fmvars
-#define fwd_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ one_table(x,upr,ft_tab,fwd_var,rf1,c)
+#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(f,n),fwd_var,rf1,c))
 #else
-#define fwd_rnd(y,x,k,c)    s(y,c) = fwd_mcol(no_table(x,s_box,fwd_var,rf1,c)) ^ (k)[c]
+#define fwd_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ fwd_mcol(no_table(x,t_use(s,box),fwd_var,rf1,c)))
 #endif
 
 #if defined(FL4_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ four_tables(x,fl_tab,fwd_var,rf1,c)
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(f,l),fwd_var,rf1,c))
 #elif defined(FL1_SET)
-#define fwd_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ one_table(x,ups,fl_tab,fwd_var,rf1,c)
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(f,l),fwd_var,rf1,c))
 #else
-#define fwd_lrnd(y,x,k,c)   s(y,c) = no_table(x,s_box,fwd_var,rf1,c) ^ (k)[c]
+#define fwd_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(s,box),fwd_var,rf1,c))
 #endif
 
-aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
-{   uint32_t        locals(b0, b1);
-    const uint32_t  *kp = cx->k_sch;
-    dec_fmvars  /* declare variables for fwd_mcol() if needed */
+AES_RETURN aes_xi(encrypt)(const unsigned char *in, unsigned char *out, const aes_encrypt_ctx cx[1])
+{   uint32_t         locals(b0, b1);
+    const uint32_t   *kp;
+#if defined( dec_fmvars )
+    dec_fmvars; /* declare variables for fwd_mcol() if needed */
+#endif
 
-    if(!(cx->n_blk & 1)) return aes_bad;
+       if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
+               return EXIT_FAILURE;
 
-    state_in(b0, in_blk, kp);
+       kp = cx->ks;
+    state_in(b0, in, kp);
 
 #if (ENC_UNROLL == FULL)
 
-    kp += (cx->n_rnd - 9) * nc;
-
-    switch(cx->n_rnd)
+    switch(cx->inf.b[0])
     {
-    case 14:    round(fwd_rnd,  b1, b0, kp - 4 * nc);
-                round(fwd_rnd,  b0, b1, kp - 3 * nc);
-    case 12:    round(fwd_rnd,  b1, b0, kp - 2 * nc);
-                round(fwd_rnd,  b0, b1, kp -     nc);
-    case 10:    round(fwd_rnd,  b1, b0, kp         );
-                round(fwd_rnd,  b0, b1, kp +     nc);
-                round(fwd_rnd,  b1, b0, kp + 2 * nc);
-                round(fwd_rnd,  b0, b1, kp + 3 * nc);
-                round(fwd_rnd,  b1, b0, kp + 4 * nc);
-                round(fwd_rnd,  b0, b1, kp + 5 * nc);
-                round(fwd_rnd,  b1, b0, kp + 6 * nc);
-                round(fwd_rnd,  b0, b1, kp + 7 * nc);
-                round(fwd_rnd,  b1, b0, kp + 8 * nc);
-                round(fwd_lrnd, b0, b1, kp + 9 * nc);
+    case 14 * AES_BLOCK_SIZE:
+        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
+        kp += 2 * N_COLS;
+    case 12 * AES_BLOCK_SIZE:
+        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
+        kp += 2 * N_COLS;
+    case 10 * AES_BLOCK_SIZE:
+        round(fwd_rnd,  b1, b0, kp + 1 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 2 * N_COLS);
+        round(fwd_rnd,  b1, b0, kp + 3 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 4 * N_COLS);
+        round(fwd_rnd,  b1, b0, kp + 5 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 6 * N_COLS);
+        round(fwd_rnd,  b1, b0, kp + 7 * N_COLS);
+        round(fwd_rnd,  b0, b1, kp + 8 * N_COLS);
+        round(fwd_rnd,  b1, b0, kp + 9 * N_COLS);
+        round(fwd_lrnd, b0, b1, kp +10 * N_COLS);
     }
+
 #else
 
 #if (ENC_UNROLL == PARTIAL)
     {   uint32_t    rnd;
-        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd)
         {
-            kp += nc;
+            kp += N_COLS;
             round(fwd_rnd, b1, b0, kp);
-            kp += nc;
+            kp += N_COLS;
             round(fwd_rnd, b0, b1, kp);
         }
-        kp += nc;
+        kp += N_COLS;
         round(fwd_rnd,  b1, b0, kp);
 #else
-    {   uint32_t    rnd, *p0 = b0, *p1 = b1, *pt;
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+    {   uint32_t    rnd;
+        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd)
         {
-            kp += nc;
-            round(fwd_rnd, p1, p0, kp);
-            pt = p0, p0 = p1, p1 = pt;
+            kp += N_COLS;
+            round(fwd_rnd, b1, b0, kp);
+            l_copy(b0, b1);
         }
 #endif
-        kp += nc;
+        kp += N_COLS;
         round(fwd_lrnd, b0, b1, kp);
     }
 #endif
 
-    state_out(out_blk, b0);
-    return aes_good;
+    state_out(out, b0);
+    return EXIT_SUCCESS;
 }
 
 #endif
 
-#if defined(DECRYPTION)
-
-#define inv_var(x,r,c) \
- ( r==0 ?           \
-    ( c==0 ? s(x,0) \
-    : c==1 ? s(x,1) \
-    : c==2 ? s(x,2) \
-    : c==3 ? s(x,3) \
-    : c==4 ? s(x,4) \
-    : c==5 ? s(x,5) \
-    : c==6 ? s(x,6) \
-    : s(x,7))       \
- : r==1 ?           \
-    ( c==0 ? nc==4 ? s(x,3) : nc==8 ? s(x,7) : s(x,5) \
-    : c==1 ? s(x,0) \
-    : c==2 ? s(x,1) \
-    : c==3 ? s(x,2) \
-    : c==4 ? s(x,3) \
-    : c==5 ? s(x,4) \
-    : c==6 ? s(x,5) \
-    : s(x,6))       \
- : r==2 ?           \
-    ( c==0 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-    : c==1 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-    : c==2 ? nc==8 ? s(x,7) : s(x,0) \
-    : c==3 ? nc==8 ? s(x,0) : s(x,1) \
-    : c==4 ? nc==8 ? s(x,1) : s(x,2) \
-    : c==5 ? nc==8 ? s(x,2) : s(x,3) \
-    : c==6 ? s(x,3) \
-    : s(x,4))       \
- :                  \
-    ( c==0 ? nc==4 ? s(x,1) : nc==8 ? s(x,4) : s(x,3) \
-    : c==1 ? nc==4 ? s(x,2) : nc==8 ? s(x,5) : s(x,4) \
-    : c==2 ? nc==4 ? s(x,3) : nc==8 ? s(x,6) : s(x,5) \
-    : c==3 ? nc==8 ? s(x,7) : s(x,0) \
-    : c==4 ? nc==8 ? s(x,0) : s(x,1) \
-    : c==5 ? nc==8 ? s(x,1) : s(x,2) \
-    : c==6 ? s(x,2) \
-    : s(x,3)))
+#if ( FUNCS_IN_C & DECRYPTION_IN_C)
+
+/* Visual C++ .Net v7.1 provides the fastest encryption code when using
+   Pentium optimisation with small code but this is poor for decryption
+   so we need to control this with the following VC++ pragmas
+*/
+
+#if defined( _MSC_VER ) && !defined( _WIN64 ) && !defined( __clang__ )
+#pragma optimize( "t", on )
+#endif
+
+/* Given the column (c) of the output state variable, the following
+   macros give the input state variables which are needed in its
+   computation for each row (r) of the state. All the alternative
+   macros give the same end values but expand into different ways
+   of calculating these values.  In particular the complex macro
+   used for dynamically variable block sizes is designed to expand
+   to a compile time constant whenever possible but will expand to
+   conditional clauses on some branches (I am grateful to Frank
+   Yellin for this construction)
+*/
+
+#define inv_var(x,r,c)\
+ ( r == 0 ? ( c == 0 ? s(x,0) : c == 1 ? s(x,1) : c == 2 ? s(x,2) : s(x,3))\
+ : r == 1 ? ( c == 0 ? s(x,3) : c == 1 ? s(x,0) : c == 2 ? s(x,1) : s(x,2))\
+ : r == 2 ? ( c == 0 ? s(x,2) : c == 1 ? s(x,3) : c == 2 ? s(x,0) : s(x,1))\
+ :          ( c == 0 ? s(x,1) : c == 1 ? s(x,2) : c == 2 ? s(x,3) : s(x,0)))
 
 #if defined(IT4_SET)
 #undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ four_tables(x,it_tab,inv_var,rf1,c)
+#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,n),inv_var,rf1,c))
 #elif defined(IT1_SET)
 #undef  dec_imvars
-#define dec_imvars
-#define inv_rnd(y,x,k,c)    s(y,c)= (k)[c] ^ one_table(x,upr,it_tab,inv_var,rf1,c)
+#define inv_rnd(y,x,k,c)    (s(y,c) = (k)[c] ^ one_table(x,upr,t_use(i,n),inv_var,rf1,c))
 #else
-#define inv_rnd(y,x,k,c)    s(y,c) = inv_mcol(no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c])
+#define inv_rnd(y,x,k,c)    (s(y,c) = inv_mcol((k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c)))
 #endif
 
 #if defined(IL4_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ four_tables(x,il_tab,inv_var,rf1,c)
+#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ four_tables(x,t_use(i,l),inv_var,rf1,c))
 #elif defined(IL1_SET)
-#define inv_lrnd(y,x,k,c)   s(y,c)= (k)[c] ^ one_table(x,ups,il_tab,inv_var,rf1,c)
+#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ one_table(x,ups,t_use(i,l),inv_var,rf1,c))
+#else
+#define inv_lrnd(y,x,k,c)   (s(y,c) = (k)[c] ^ no_table(x,t_use(i,box),inv_var,rf1,c))
+#endif
+
+/* This code can work with the decryption key schedule in the   */
+/* order that is used for encryption (where the 1st decryption  */
+/* round key is at the high end ot the schedule) or with a key  */
+/* schedule that has been reversed to put the 1st decryption    */
+/* round key at the low end of the schedule in memory (when     */
+/* AES_REV_DKS is defined)                                      */
+
+#ifdef AES_REV_DKS
+#define key_ofs     0
+#define rnd_key(n)  (kp + n * N_COLS)
 #else
-#define inv_lrnd(y,x,k,c)   s(y,c) = no_table(x,inv_s_box,inv_var,rf1,c) ^ (k)[c]
+#define key_ofs     1
+#define rnd_key(n)  (kp - n * N_COLS)
 #endif
 
-aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1])
+AES_RETURN aes_xi(decrypt)(const unsigned char *in, unsigned char *out, const aes_decrypt_ctx cx[1])
 {   uint32_t        locals(b0, b1);
-    const uint32_t  *kp = cx->k_sch + nc * cx->n_rnd;
-    dec_imvars  /* declare variables for inv_mcol() if needed */
+#if defined( dec_imvars )
+    dec_imvars; /* declare variables for inv_mcol() if needed */
+#endif
+    const uint32_t *kp;
 
-    if(!(cx->n_blk & 2)) return aes_bad;
+       if(cx->inf.b[0] != 10 * AES_BLOCK_SIZE && cx->inf.b[0] != 12 * AES_BLOCK_SIZE && cx->inf.b[0] != 14 * AES_BLOCK_SIZE)
+               return EXIT_FAILURE;
 
-    state_in(b0, in_blk, kp);
+    kp = cx->ks + (key_ofs ? (cx->inf.b[0] >> 2) : 0);
+    state_in(b0, in, kp);
 
 #if (DEC_UNROLL == FULL)
 
-    kp = cx->k_sch + 9 * nc;
-    switch(cx->n_rnd)
+    kp = cx->ks + (key_ofs ? 0 : (cx->inf.b[0] >> 2));
+    switch(cx->inf.b[0])
     {
-    case 14:    round(inv_rnd,  b1, b0, kp + 4 * nc);
-                round(inv_rnd,  b0, b1, kp + 3 * nc);
-    case 12:    round(inv_rnd,  b1, b0, kp + 2 * nc);
-                round(inv_rnd,  b0, b1, kp + nc    );
-    case 10:    round(inv_rnd,  b1, b0, kp         );
-                round(inv_rnd,  b0, b1, kp -     nc);
-                round(inv_rnd,  b1, b0, kp - 2 * nc);
-                round(inv_rnd,  b0, b1, kp - 3 * nc);
-                round(inv_rnd,  b1, b0, kp - 4 * nc);
-                round(inv_rnd,  b0, b1, kp - 5 * nc);
-                round(inv_rnd,  b1, b0, kp - 6 * nc);
-                round(inv_rnd,  b0, b1, kp - 7 * nc);
-                round(inv_rnd,  b1, b0, kp - 8 * nc);
-                round(inv_lrnd, b0, b1, kp - 9 * nc);
+    case 14 * AES_BLOCK_SIZE:
+        round(inv_rnd,  b1, b0, rnd_key(-13));
+        round(inv_rnd,  b0, b1, rnd_key(-12));
+    case 12 * AES_BLOCK_SIZE:
+        round(inv_rnd,  b1, b0, rnd_key(-11));
+        round(inv_rnd,  b0, b1, rnd_key(-10));
+    case 10 * AES_BLOCK_SIZE:
+        round(inv_rnd,  b1, b0, rnd_key(-9));
+        round(inv_rnd,  b0, b1, rnd_key(-8));
+        round(inv_rnd,  b1, b0, rnd_key(-7));
+        round(inv_rnd,  b0, b1, rnd_key(-6));
+        round(inv_rnd,  b1, b0, rnd_key(-5));
+        round(inv_rnd,  b0, b1, rnd_key(-4));
+        round(inv_rnd,  b1, b0, rnd_key(-3));
+        round(inv_rnd,  b0, b1, rnd_key(-2));
+        round(inv_rnd,  b1, b0, rnd_key(-1));
+        round(inv_lrnd, b0, b1, rnd_key( 0));
     }
+
 #else
 
 #if (DEC_UNROLL == PARTIAL)
     {   uint32_t    rnd;
-        for(rnd = 0; rnd < (cx->n_rnd >> 1) - 1; ++rnd)
+        for(rnd = 0; rnd < (cx->inf.b[0] >> 5) - 1ul; ++rnd)
         {
-            kp -= nc;
+            kp = rnd_key(1);
             round(inv_rnd, b1, b0, kp);
-            kp -= nc;
+            kp = rnd_key(1);
             round(inv_rnd, b0, b1, kp);
         }
-        kp -= nc;
+        kp = rnd_key(1);
         round(inv_rnd, b1, b0, kp);
 #else
-    {   uint32_t    rnd, *p0 = b0, *p1 = b1, *pt;
-        for(rnd = 0; rnd < cx->n_rnd - 1; ++rnd)
+    {   uint32_t    rnd;
+        for(rnd = 0; rnd < (cx->inf.b[0] >> 4) - 1ul; ++rnd)
         {
-            kp -= nc;
-            round(inv_rnd, p1, p0, kp);
-            pt = p0, p0 = p1, p1 = pt;
+            kp = rnd_key(1);
+            round(inv_rnd, b1, b0, kp);
+            l_copy(b0, b1);
         }
 #endif
-        kp -= nc;
+        kp = rnd_key(1);
         round(inv_lrnd, b0, b1, kp);
-    }
+        }
 #endif
 
-    state_out(out_blk, b0);
-    return aes_good;
+    state_out(out, b0);
+    return EXIT_SUCCESS;
 }
 
 #endif
+
+#if defined(__cplusplus)
+}
+#endif
index 8402b50cfedcc91e62b3946b078bd19e0f7da972..11ed11add5d73e092bc954b307b2e295777226e4 100644 (file)
@@ -1,69 +1,53 @@
 /*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
 
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the code for implementing the key schedule for AES
- * (Rijndael) for block and key sizes of 16, 24, and 32 bytes.
- */
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
 
-#include "aesopt.h"
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
 
-#if defined(BLOCK_SIZE) && (BLOCK_SIZE & 7)
-#error An illegal block size has been specified.
-#endif
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
 
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32.
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 20/12/2007
 */
 
-#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH)
+#include "aesopt.h"
+#include "aestab.h"
 
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
-{
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
+#if defined( USE_INTEL_AES_IF_PRESENT )
+#  include "aes_ni.h"
+#else
+/* map names here to provide the external API ('name' -> 'aes_name') */
+#  define aes_xi(x) aes_ ## x
 #endif
 
-    if((blen & 7) || blen < 16 || blen > 32)
-    {
-        cx->n_blk = 0; return aes_bad;
-    }
-
-    cx->n_blk = blen;
-    return aes_good;
-}
+#ifdef USE_VIA_ACE_IF_PRESENT
+#  include "aes_via_ace.h"
+#endif
 
+#if defined(__cplusplus)
+extern "C"
+{
 #endif
 
+/* Use the low bit in the context's inf.b[2] as a flag to
+   indicate whether a context was initialized for encryption
+   or decryption.
+*/
+#define MARK_AS_ENCRYPTION_CTX(cx) (cx)->inf.b[2] |= (uint8_t)0x01
+#define MARK_AS_DECRYPTION_CTX(cx) (cx)->inf.b[2] &= (uint8_t)0xfe
+
 /* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 24 or 32 as appropriate.
-   This corresponds to bit lengths of 128, 192 and 256 bits, and
-   to Nk values of 4, 6 and 8 respectively.
+   length can be specified in bytes, with legal values of 16, 24
+   and 32, or in bits, with legal values of 128, 192 and 256. These
+   values correspond with Nk values of 4, 6 and 8 respectively.
 
    The following macros implement a single cycle in the key
    schedule generation process. The number of cycles needed
@@ -78,293 +62,512 @@ aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
     cx->n_col = 8   29 23 19 17 14
 */
 
-#if defined(ENCRYPTION_KEY_SCHEDULE)
+#if defined( REDUCE_CODE_SIZE )
+#  define ls_box ls_sub
+   uint32_t ls_sub(const uint32_t t, const uint32_t n);
+#  define inv_mcol im_sub
+   uint32_t im_sub(const uint32_t x);
+#  ifdef ENC_KS_UNROLL
+#    undef ENC_KS_UNROLL
+#  endif
+#  ifdef DEC_KS_UNROLL
+#    undef DEC_KS_UNROLL
+#  endif
+#endif
+
+#if (FUNCS_IN_C & ENC_KEYING_IN_C)
+
+#if defined(AES_128) || defined( AES_VAR )
 
 #define ke4(k,i) \
-{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
-    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
+    k[4*(i)+5] = ss[1] ^= ss[0]; \
+    k[4*(i)+6] = ss[2] ^= ss[1]; \
+    k[4*(i)+7] = ss[3] ^= ss[2]; \
 }
-#define kel4(k,i) \
-{   k[4*(i)+4] = ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+5] = ss[1] ^= ss[0]; \
-    k[4*(i)+6] = ss[2] ^= ss[1]; k[4*(i)+7] = ss[3] ^= ss[2]; \
+
+AES_RETURN aes_xi(encrypt_key128)(const unsigned char *key, aes_encrypt_ctx cx[1])
+{   uint32_t    ss[4];
+
+    cx->ks[0] = ss[0] = word_in(key, 0);
+    cx->ks[1] = ss[1] = word_in(key, 1);
+    cx->ks[2] = ss[2] = word_in(key, 2);
+    cx->ks[3] = ss[3] = word_in(key, 3);
+
+#ifdef ENC_KS_UNROLL
+    ke4(cx->ks, 0);  ke4(cx->ks, 1);
+    ke4(cx->ks, 2);  ke4(cx->ks, 3);
+    ke4(cx->ks, 4);  ke4(cx->ks, 5);
+    ke4(cx->ks, 6);  ke4(cx->ks, 7);
+    ke4(cx->ks, 8);
+#else
+    {   uint32_t i;
+        for(i = 0; i < 9; ++i)
+            ke4(cx->ks, i);
+    }
+#endif
+    ke4(cx->ks, 9);
+    cx->inf.l = 0;
+    cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
+
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_ENCRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
+}
+
+#endif
+
+#if defined(AES_192) || defined( AES_VAR )
+
+#define kef6(k,i) \
+{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
+    k[6*(i)+ 7] = ss[1] ^= ss[0]; \
+    k[6*(i)+ 8] = ss[2] ^= ss[1]; \
+    k[6*(i)+ 9] = ss[3] ^= ss[2]; \
 }
 
 #define ke6(k,i) \
-{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
-    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
-    k[6*(i)+10] = ss[4] ^= ss[3]; k[6*(i)+11] = ss[5] ^= ss[4]; \
+{   kef6(k,i); \
+    k[6*(i)+10] = ss[4] ^= ss[3]; \
+    k[6*(i)+11] = ss[5] ^= ss[4]; \
 }
-#define kel6(k,i) \
-{   k[6*(i)+ 6] = ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 7] = ss[1] ^= ss[0]; \
-    k[6*(i)+ 8] = ss[2] ^= ss[1]; k[6*(i)+ 9] = ss[3] ^= ss[2]; \
+
+AES_RETURN aes_xi(encrypt_key192)(const unsigned char *key, aes_encrypt_ctx cx[1])
+{   uint32_t    ss[6];
+
+       cx->ks[0] = ss[0] = word_in(key, 0);
+    cx->ks[1] = ss[1] = word_in(key, 1);
+    cx->ks[2] = ss[2] = word_in(key, 2);
+    cx->ks[3] = ss[3] = word_in(key, 3);
+    cx->ks[4] = ss[4] = word_in(key, 4);
+    cx->ks[5] = ss[5] = word_in(key, 5);
+
+#ifdef ENC_KS_UNROLL
+    ke6(cx->ks, 0);  ke6(cx->ks, 1);
+    ke6(cx->ks, 2);  ke6(cx->ks, 3);
+    ke6(cx->ks, 4);  ke6(cx->ks, 5);
+    ke6(cx->ks, 6);
+#else
+    {   uint32_t i;
+        for(i = 0; i < 7; ++i)
+            ke6(cx->ks, i);
+    }
+#endif
+    kef6(cx->ks, 7);
+    cx->inf.l = 0;
+    cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
+
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_ENCRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
 }
 
-#define ke8(k,i) \
-{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
-    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
-    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); k[8*(i)+13] = ss[5] ^= ss[4]; \
-    k[8*(i)+14] = ss[6] ^= ss[5]; k[8*(i)+15] = ss[7] ^= ss[6]; \
+#endif
+
+#if defined(AES_256) || defined( AES_VAR )
+
+#define kef8(k,i) \
+{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
+    k[8*(i)+ 9] = ss[1] ^= ss[0]; \
+    k[8*(i)+10] = ss[2] ^= ss[1]; \
+    k[8*(i)+11] = ss[3] ^= ss[2]; \
 }
-#define kel8(k,i) \
-{   k[8*(i)+ 8] = ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 9] = ss[1] ^= ss[0]; \
-    k[8*(i)+10] = ss[2] ^= ss[1]; k[8*(i)+11] = ss[3] ^= ss[2]; \
+
+#define ke8(k,i) \
+{   kef8(k,i); \
+    k[8*(i)+12] = ss[4] ^= ls_box(ss[3],0); \
+    k[8*(i)+13] = ss[5] ^= ss[4]; \
+    k[8*(i)+14] = ss[6] ^= ss[5]; \
+    k[8*(i)+15] = ss[7] ^= ss[6]; \
 }
 
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
+AES_RETURN aes_xi(encrypt_key256)(const unsigned char *key, aes_encrypt_ctx cx[1])
 {   uint32_t    ss[8];
 
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3U) | 1;
-
-    cx->k_sch[0] = ss[0] = word_in(in_key     );
-    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
-    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
-    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (ENC_UNROLL != NONE)
-
-    switch(klen)
-    {
-    case 16:    ke4(cx->k_sch, 0); ke4(cx->k_sch, 1);
-                ke4(cx->k_sch, 2); ke4(cx->k_sch, 3);
-                ke4(cx->k_sch, 4); ke4(cx->k_sch, 5);
-                ke4(cx->k_sch, 6); ke4(cx->k_sch, 7);
-                ke4(cx->k_sch, 8); kel4(cx->k_sch, 9);
-                cx->n_rnd = 10; break;
-    case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                ke6(cx->k_sch, 0); ke6(cx->k_sch, 1);
-                ke6(cx->k_sch, 2); ke6(cx->k_sch, 3);
-                ke6(cx->k_sch, 4); ke6(cx->k_sch, 5);
-                ke6(cx->k_sch, 6); kel6(cx->k_sch, 7);
-                cx->n_rnd = 12; break;
-    case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                ke8(cx->k_sch, 0); ke8(cx->k_sch, 1);
-                ke8(cx->k_sch, 2); ke8(cx->k_sch, 3);
-                ke8(cx->k_sch, 4); ke8(cx->k_sch, 5);
-                kel8(cx->k_sch, 6);
-                cx->n_rnd = 14; break;
-    default:    cx->n_rnd = 0; return aes_bad;
-    }
+    cx->ks[0] = ss[0] = word_in(key, 0);
+    cx->ks[1] = ss[1] = word_in(key, 1);
+    cx->ks[2] = ss[2] = word_in(key, 2);
+    cx->ks[3] = ss[3] = word_in(key, 3);
+    cx->ks[4] = ss[4] = word_in(key, 4);
+    cx->ks[5] = ss[5] = word_in(key, 5);
+    cx->ks[6] = ss[6] = word_in(key, 6);
+    cx->ks[7] = ss[7] = word_in(key, 7);
+
+#ifdef ENC_KS_UNROLL
+    ke8(cx->ks, 0); ke8(cx->ks, 1);
+    ke8(cx->ks, 2); ke8(cx->ks, 3);
+    ke8(cx->ks, 4); ke8(cx->ks, 5);
 #else
-    {   uint32_t i, l;
-        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-        l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
-        switch(klen)
-        {
-        case 16:    for(i = 0; i < l; ++i)
-                        ke4(cx->k_sch, i);
-                    break;
-        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    for(i = 0; i < l; ++i)
-                        ke6(cx->k_sch, i);
-                    break;
-        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                    cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                    for(i = 0; i < l; ++i)
-                        ke8(cx->k_sch,  i);
-                    break;
-        default:    cx->n_rnd = 0; return aes_bad;
-        }
+    {   uint32_t i;
+        for(i = 0; i < 6; ++i)
+            ke8(cx->ks,  i);
     }
 #endif
+    kef8(cx->ks, 6);
+    cx->inf.l = 0;
+    cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
 
-    return aes_good;
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_ENCRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
 }
 
 #endif
 
-#if defined(DECRYPTION_KEY_SCHEDULE)
+#endif
 
-#if (DEC_ROUND != NO_TABLES)
-#define d_vars  dec_imvars
-#define ff(x)   inv_mcol(x)
+#if (FUNCS_IN_C & DEC_KEYING_IN_C)
+
+/* this is used to store the decryption round keys  */
+/* in forward or reverse order                      */
+
+#ifdef AES_REV_DKS
+#define v(n,i)  ((n) - (i) + 2 * ((i) & 3))
 #else
+#define v(n,i)  (i)
+#endif
+
+#if DEC_ROUND == NO_TABLES
 #define ff(x)   (x)
-#define d_vars
+#else
+#define ff(x)   inv_mcol(x)
+#if defined( dec_imvars )
+#define d_vars  dec_imvars
 #endif
+#endif
+
+#if defined(AES_128) || defined( AES_VAR )
+
+#define k4e(k,i) \
+{   k[v(40,(4*(i))+4)] = ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; \
+    k[v(40,(4*(i))+5)] = ss[1] ^= ss[0]; \
+    k[v(40,(4*(i))+6)] = ss[2] ^= ss[1]; \
+    k[v(40,(4*(i))+7)] = ss[3] ^= ss[2]; \
+}
 
 #if 1
+
 #define kdf4(k,i) \
-{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; ss[1] = ss[1] ^ ss[3]; ss[2] = ss[2] ^ ss[3]; ss[3] = ss[3]; \
-    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
-    ss[4] ^= k[4*(i)];   k[4*(i)+4] = ff(ss[4]); ss[4] ^= k[4*(i)+1]; k[4*(i)+5] = ff(ss[4]); \
-    ss[4] ^= k[4*(i)+2]; k[4*(i)+6] = ff(ss[4]); ss[4] ^= k[4*(i)+3]; k[4*(i)+7] = ff(ss[4]); \
+{   ss[0] = ss[0] ^ ss[2] ^ ss[1] ^ ss[3]; \
+    ss[1] = ss[1] ^ ss[3]; \
+    ss[2] = ss[2] ^ ss[3]; \
+    ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
+    ss[i % 4] ^= ss[4]; \
+    ss[4] ^= k[v(40,(4*(i)))];   k[v(40,(4*(i))+4)] = ff(ss[4]); \
+    ss[4] ^= k[v(40,(4*(i))+1)]; k[v(40,(4*(i))+5)] = ff(ss[4]); \
+    ss[4] ^= k[v(40,(4*(i))+2)]; k[v(40,(4*(i))+6)] = ff(ss[4]); \
+    ss[4] ^= k[v(40,(4*(i))+3)]; k[v(40,(4*(i))+7)] = ff(ss[4]); \
 }
+
 #define kd4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
-    k[4*(i)+4] = ss[4] ^= k[4*(i)]; k[4*(i)+5] = ss[4] ^= k[4*(i)+1]; \
-    k[4*(i)+6] = ss[4] ^= k[4*(i)+2]; k[4*(i)+7] = ss[4] ^= k[4*(i)+3]; \
+{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; \
+    ss[i % 4] ^= ss[4]; ss[4] = ff(ss[4]); \
+    k[v(40,(4*(i))+4)] = ss[4] ^= k[v(40,(4*(i)))]; \
+    k[v(40,(4*(i))+5)] = ss[4] ^= k[v(40,(4*(i))+1)]; \
+    k[v(40,(4*(i))+6)] = ss[4] ^= k[v(40,(4*(i))+2)]; \
+    k[v(40,(4*(i))+7)] = ss[4] ^= k[v(40,(4*(i))+3)]; \
 }
+
 #define kdl4(k,i) \
-{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ rcon_tab[i]; ss[i % 4] ^= ss[4]; \
-    k[4*(i)+4] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; k[4*(i)+5] = ss[1] ^ ss[3]; \
-    k[4*(i)+6] = ss[0]; k[4*(i)+7] = ss[1]; \
+{   ss[4] = ls_box(ss[(i+3) % 4], 3) ^ t_use(r,c)[i]; ss[i % 4] ^= ss[4]; \
+    k[v(40,(4*(i))+4)] = (ss[0] ^= ss[1]) ^ ss[2] ^ ss[3]; \
+    k[v(40,(4*(i))+5)] = ss[1] ^ ss[3]; \
+    k[v(40,(4*(i))+6)] = ss[0]; \
+    k[v(40,(4*(i))+7)] = ss[1]; \
 }
+
 #else
+
 #define kdf4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ff(ss[0]); ss[1] ^= ss[0]; k[4*(i)+ 5] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ff(ss[2]); ss[3] ^= ss[2]; k[4*(i)+ 7] = ff(ss[3]); \
+{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ff(ss[0]); \
+    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ff(ss[2]); \
+    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ff(ss[3]); \
 }
+
 #define kd4(k,i) \
-{   ss[4] = ls_box(ss[3],3) ^ rcon_tab[i]; \
-    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[4*(i)+ 4] = ss[4] ^= k[4*(i)]; \
-    ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[4] ^= k[4*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[4] ^= k[4*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[4] ^= k[4*(i)+ 3]; \
+{   ss[4] = ls_box(ss[3],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= ss[4]; ss[4] = ff(ss[4]); k[v(40,(4*(i))+ 4)] = ss[4] ^= k[v(40,(4*(i)))]; \
+    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[4] ^= k[v(40,(4*(i))+ 1)]; \
+    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[4] ^= k[v(40,(4*(i))+ 2)]; \
+    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[4] ^= k[v(40,(4*(i))+ 3)]; \
 }
+
 #define kdl4(k,i) \
-{   ss[0] ^= ls_box(ss[3],3) ^ rcon_tab[i]; k[4*(i)+ 4] = ss[0]; ss[1] ^= ss[0]; k[4*(i)+ 5] = ss[1]; \
-    ss[2] ^= ss[1]; k[4*(i)+ 6] = ss[2]; ss[3] ^= ss[2]; k[4*(i)+ 7] = ss[3]; \
+{   ss[0] ^= ls_box(ss[3],3) ^ t_use(r,c)[i]; k[v(40,(4*(i))+ 4)] = ss[0]; \
+    ss[1] ^= ss[0]; k[v(40,(4*(i))+ 5)] = ss[1]; \
+    ss[2] ^= ss[1]; k[v(40,(4*(i))+ 6)] = ss[2]; \
+    ss[3] ^= ss[2]; k[v(40,(4*(i))+ 7)] = ss[3]; \
 }
+
+#endif
+
+AES_RETURN aes_xi(decrypt_key128)(const unsigned char *key, aes_decrypt_ctx cx[1])
+{   uint32_t    ss[5];
+#if defined( d_vars )
+        d_vars;
+#endif
+
+       cx->ks[v(40,(0))] = ss[0] = word_in(key, 0);
+    cx->ks[v(40,(1))] = ss[1] = word_in(key, 1);
+    cx->ks[v(40,(2))] = ss[2] = word_in(key, 2);
+    cx->ks[v(40,(3))] = ss[3] = word_in(key, 3);
+
+#ifdef DEC_KS_UNROLL
+     kdf4(cx->ks, 0); kd4(cx->ks, 1);
+     kd4(cx->ks, 2);  kd4(cx->ks, 3);
+     kd4(cx->ks, 4);  kd4(cx->ks, 5);
+     kd4(cx->ks, 6);  kd4(cx->ks, 7);
+     kd4(cx->ks, 8);  kdl4(cx->ks, 9);
+#else
+    {   uint32_t i;
+        for(i = 0; i < 10; ++i)
+            k4e(cx->ks, i);
+#if !(DEC_ROUND == NO_TABLES)
+        for(i = N_COLS; i < 10 * N_COLS; ++i)
+            cx->ks[i] = inv_mcol(cx->ks[i]);
+#endif
+    }
 #endif
+    cx->inf.l = 0;
+    cx->inf.b[0] = 10 * AES_BLOCK_SIZE;
+
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_DECRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
+}
+
+#endif
+
+#if defined(AES_192) || defined( AES_VAR )
+
+#define k6ef(k,i) \
+{   k[v(48,(6*(i))+ 6)] = ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; \
+    k[v(48,(6*(i))+ 7)] = ss[1] ^= ss[0]; \
+    k[v(48,(6*(i))+ 8)] = ss[2] ^= ss[1]; \
+    k[v(48,(6*(i))+ 9)] = ss[3] ^= ss[2]; \
+}
+
+#define k6e(k,i) \
+{   k6ef(k,i); \
+    k[v(48,(6*(i))+10)] = ss[4] ^= ss[3]; \
+    k[v(48,(6*(i))+11)] = ss[5] ^= ss[4]; \
+}
 
 #define kdf6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ff(ss[0]); ss[1] ^= ss[0]; k[6*(i)+ 7] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ff(ss[2]); ss[3] ^= ss[2]; k[6*(i)+ 9] = ff(ss[3]); \
-    ss[4] ^= ss[3]; k[6*(i)+10] = ff(ss[4]); ss[5] ^= ss[4]; k[6*(i)+11] = ff(ss[5]); \
+{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ff(ss[0]); \
+    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ff(ss[2]); \
+    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ff(ss[3]); \
+    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ff(ss[4]); \
+    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ff(ss[5]); \
 }
+
 #define kd6(k,i) \
-{   ss[6] = ls_box(ss[5],3) ^ rcon_tab[i]; \
-    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[6*(i)+ 6] = ss[6] ^= k[6*(i)]; \
-    ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[6] ^= k[6*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[6] ^= k[6*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[6] ^= k[6*(i)+ 3]; \
-    ss[4] ^= ss[3]; k[6*(i)+10] = ss[6] ^= k[6*(i)+ 4]; \
-    ss[5] ^= ss[4]; k[6*(i)+11] = ss[6] ^= k[6*(i)+ 5]; \
+{   ss[6] = ls_box(ss[5],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= ss[6]; ss[6] = ff(ss[6]); k[v(48,(6*(i))+ 6)] = ss[6] ^= k[v(48,(6*(i)))]; \
+    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[6] ^= k[v(48,(6*(i))+ 1)]; \
+    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[6] ^= k[v(48,(6*(i))+ 2)]; \
+    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[6] ^= k[v(48,(6*(i))+ 3)]; \
+    ss[4] ^= ss[3]; k[v(48,(6*(i))+10)] = ss[6] ^= k[v(48,(6*(i))+ 4)]; \
+    ss[5] ^= ss[4]; k[v(48,(6*(i))+11)] = ss[6] ^= k[v(48,(6*(i))+ 5)]; \
 }
+
 #define kdl6(k,i) \
-{   ss[0] ^= ls_box(ss[5],3) ^ rcon_tab[i]; k[6*(i)+ 6] = ss[0]; ss[1] ^= ss[0]; k[6*(i)+ 7] = ss[1]; \
-    ss[2] ^= ss[1]; k[6*(i)+ 8] = ss[2]; ss[3] ^= ss[2]; k[6*(i)+ 9] = ss[3]; \
+{   ss[0] ^= ls_box(ss[5],3) ^ t_use(r,c)[i]; k[v(48,(6*(i))+ 6)] = ss[0]; \
+    ss[1] ^= ss[0]; k[v(48,(6*(i))+ 7)] = ss[1]; \
+    ss[2] ^= ss[1]; k[v(48,(6*(i))+ 8)] = ss[2]; \
+    ss[3] ^= ss[2]; k[v(48,(6*(i))+ 9)] = ss[3]; \
+}
+
+AES_RETURN aes_xi(decrypt_key192)(const unsigned char *key, aes_decrypt_ctx cx[1])
+{   uint32_t    ss[7];
+#if defined( d_vars )
+        d_vars;
+#endif
+
+    cx->ks[v(48,(0))] = ss[0] = word_in(key, 0);
+    cx->ks[v(48,(1))] = ss[1] = word_in(key, 1);
+    cx->ks[v(48,(2))] = ss[2] = word_in(key, 2);
+    cx->ks[v(48,(3))] = ss[3] = word_in(key, 3);
+
+#ifdef DEC_KS_UNROLL
+    ss[4] = word_in(key, 4);
+    ss[5] = word_in(key, 5);
+    cx->ks[v(48, (4))] = ff(ss[4]);
+    cx->ks[v(48, (5))] = ff(ss[5]);
+    kdf6(cx->ks, 0); kd6(cx->ks, 1);
+    kd6(cx->ks, 2);  kd6(cx->ks, 3);
+    kd6(cx->ks, 4);  kd6(cx->ks, 5);
+    kd6(cx->ks, 6);  kdl6(cx->ks, 7);
+#else
+    cx->ks[v(48,(4))] = ss[4] = word_in(key, 4);
+    cx->ks[v(48,(5))] = ss[5] = word_in(key, 5);
+    {   uint32_t i;
+
+        for(i = 0; i < 7; ++i)
+            k6e(cx->ks, i);
+        k6ef(cx->ks, 7);
+#if !(DEC_ROUND == NO_TABLES)
+        for(i = N_COLS; i < 12 * N_COLS; ++i)
+            cx->ks[i] = inv_mcol(cx->ks[i]);
+#endif
+    }
+#endif
+    cx->inf.l = 0;
+    cx->inf.b[0] = 12 * AES_BLOCK_SIZE;
+
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_DECRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
+}
+
+#endif
+
+#if defined(AES_256) || defined( AES_VAR )
+
+#define k8ef(k,i) \
+{   k[v(56,(8*(i))+ 8)] = ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; \
+    k[v(56,(8*(i))+ 9)] = ss[1] ^= ss[0]; \
+    k[v(56,(8*(i))+10)] = ss[2] ^= ss[1]; \
+    k[v(56,(8*(i))+11)] = ss[3] ^= ss[2]; \
+}
+
+#define k8e(k,i) \
+{   k8ef(k,i); \
+    k[v(56,(8*(i))+12)] = ss[4] ^= ls_box(ss[3],0); \
+    k[v(56,(8*(i))+13)] = ss[5] ^= ss[4]; \
+    k[v(56,(8*(i))+14)] = ss[6] ^= ss[5]; \
+    k[v(56,(8*(i))+15)] = ss[7] ^= ss[6]; \
 }
 
 #define kdf8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ff(ss[0]); ss[1] ^= ss[0]; k[8*(i)+ 9] = ff(ss[1]); \
-    ss[2] ^= ss[1]; k[8*(i)+10] = ff(ss[2]); ss[3] ^= ss[2]; k[8*(i)+11] = ff(ss[3]); \
-    ss[4] ^= ls_box(ss[3],0); k[8*(i)+12] = ff(ss[4]); ss[5] ^= ss[4]; k[8*(i)+13] = ff(ss[5]); \
-    ss[6] ^= ss[5]; k[8*(i)+14] = ff(ss[6]); ss[7] ^= ss[6]; k[8*(i)+15] = ff(ss[7]); \
+{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ff(ss[0]); \
+    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ff(ss[1]); \
+    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ff(ss[2]); \
+    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ff(ss[3]); \
+    ss[4] ^= ls_box(ss[3],0); k[v(56,(8*(i))+12)] = ff(ss[4]); \
+    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ff(ss[5]); \
+    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ff(ss[6]); \
+    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ff(ss[7]); \
 }
+
 #define kd8(k,i) \
-{   uint32_t g = ls_box(ss[7],3) ^ rcon_tab[i]; \
-    ss[0] ^= g; g = ff(g); k[8*(i)+ 8] = g ^= k[8*(i)]; \
-    ss[1] ^= ss[0]; k[8*(i)+ 9] = g ^= k[8*(i)+ 1]; \
-    ss[2] ^= ss[1]; k[8*(i)+10] = g ^= k[8*(i)+ 2]; \
-    ss[3] ^= ss[2]; k[8*(i)+11] = g ^= k[8*(i)+ 3]; \
-    g = ls_box(ss[3],0); \
-    ss[4] ^= g; g = ff(g); k[8*(i)+12] = g ^= k[8*(i)+ 4]; \
-    ss[5] ^= ss[4]; k[8*(i)+13] = g ^= k[8*(i)+ 5]; \
-    ss[6] ^= ss[5]; k[8*(i)+14] = g ^= k[8*(i)+ 6]; \
-    ss[7] ^= ss[6]; k[8*(i)+15] = g ^= k[8*(i)+ 7]; \
+{   ss[8] = ls_box(ss[7],3) ^ t_use(r,c)[i]; \
+    ss[0] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+ 8)] = ss[8] ^= k[v(56,(8*(i)))]; \
+    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[8] ^= k[v(56,(8*(i))+ 1)]; \
+    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[8] ^= k[v(56,(8*(i))+ 2)]; \
+    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[8] ^= k[v(56,(8*(i))+ 3)]; \
+    ss[8] = ls_box(ss[3],0); \
+    ss[4] ^= ss[8]; ss[8] = ff(ss[8]); k[v(56,(8*(i))+12)] = ss[8] ^= k[v(56,(8*(i))+ 4)]; \
+    ss[5] ^= ss[4]; k[v(56,(8*(i))+13)] = ss[8] ^= k[v(56,(8*(i))+ 5)]; \
+    ss[6] ^= ss[5]; k[v(56,(8*(i))+14)] = ss[8] ^= k[v(56,(8*(i))+ 6)]; \
+    ss[7] ^= ss[6]; k[v(56,(8*(i))+15)] = ss[8] ^= k[v(56,(8*(i))+ 7)]; \
 }
+
 #define kdl8(k,i) \
-{   ss[0] ^= ls_box(ss[7],3) ^ rcon_tab[i]; k[8*(i)+ 8] = ss[0]; ss[1] ^= ss[0]; k[8*(i)+ 9] = ss[1]; \
-    ss[2] ^= ss[1]; k[8*(i)+10] = ss[2]; ss[3] ^= ss[2]; k[8*(i)+11] = ss[3]; \
+{   ss[0] ^= ls_box(ss[7],3) ^ t_use(r,c)[i]; k[v(56,(8*(i))+ 8)] = ss[0]; \
+    ss[1] ^= ss[0]; k[v(56,(8*(i))+ 9)] = ss[1]; \
+    ss[2] ^= ss[1]; k[v(56,(8*(i))+10)] = ss[2]; \
+    ss[3] ^= ss[2]; k[v(56,(8*(i))+11)] = ss[3]; \
 }
 
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
-{   uint32_t    ss[8];
-    d_vars
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
+AES_RETURN aes_xi(decrypt_key256)(const unsigned char *key, aes_decrypt_ctx cx[1])
+{   uint32_t    ss[9];
+#if defined( d_vars )
+        d_vars;
 #endif
 
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3U) | 2;
-
-    cx->k_sch[0] = ss[0] = word_in(in_key     );
-    cx->k_sch[1] = ss[1] = word_in(in_key +  4);
-    cx->k_sch[2] = ss[2] = word_in(in_key +  8);
-    cx->k_sch[3] = ss[3] = word_in(in_key + 12);
-
-#if (BLOCK_SIZE == 16) && (DEC_UNROLL != NONE)
-
-    switch(klen)
-    {
-    case 16:    kdf4(cx->k_sch, 0); kd4(cx->k_sch, 1);
-                kd4(cx->k_sch, 2); kd4(cx->k_sch, 3);
-                kd4(cx->k_sch, 4); kd4(cx->k_sch, 5);
-                kd4(cx->k_sch, 6); kd4(cx->k_sch, 7);
-                kd4(cx->k_sch, 8); kdl4(cx->k_sch, 9);
-                cx->n_rnd = 10; break;
-    case 24:    ss[4] = word_in(in_key + 16);
-               cx->k_sch[4] = ff(ss[4]);
-               ss[5] = word_in(in_key + 20);
-                cx->k_sch[5] = ff(ss[5]);
-                kdf6(cx->k_sch, 0); kd6(cx->k_sch, 1);
-                kd6(cx->k_sch, 2); kd6(cx->k_sch, 3);
-                kd6(cx->k_sch, 4); kd6(cx->k_sch, 5);
-                kd6(cx->k_sch, 6); kdl6(cx->k_sch, 7);
-                cx->n_rnd = 12; break;
-    case 32:    ss[4] = word_in(in_key + 16);
-               cx->k_sch[4] = ff(ss[4]);
-               ss[5] = word_in(in_key + 20);
-                cx->k_sch[5] = ff(ss[5]);
-               ss[6] = word_in(in_key + 24);
-                cx->k_sch[6] = ff(ss[6]);
-               ss[7] = word_in(in_key + 28);
-                cx->k_sch[7] = ff(ss[7]);
-                kdf8(cx->k_sch, 0); kd8(cx->k_sch, 1);
-                kd8(cx->k_sch, 2); kd8(cx->k_sch, 3);
-                kd8(cx->k_sch, 4); kd8(cx->k_sch, 5);
-                kdl8(cx->k_sch, 6);
-                cx->n_rnd = 14; break;
-    default:    cx->n_rnd = 0; return aes_bad;
-    }
+    cx->ks[v(56,(0))] = ss[0] = word_in(key, 0);
+    cx->ks[v(56,(1))] = ss[1] = word_in(key, 1);
+    cx->ks[v(56,(2))] = ss[2] = word_in(key, 2);
+    cx->ks[v(56,(3))] = ss[3] = word_in(key, 3);
+
+#ifdef DEC_KS_UNROLL
+    ss[4] = word_in(key, 4);
+    ss[5] = word_in(key, 5);
+    ss[6] = word_in(key, 6);
+    ss[7] = word_in(key, 7);
+    cx->ks[v(56,(4))] = ff(ss[4]);
+    cx->ks[v(56,(5))] = ff(ss[5]);
+    cx->ks[v(56,(6))] = ff(ss[6]);
+    cx->ks[v(56,(7))] = ff(ss[7]);
+    kdf8(cx->ks, 0); kd8(cx->ks, 1);
+    kd8(cx->ks, 2);  kd8(cx->ks, 3);
+    kd8(cx->ks, 4);  kd8(cx->ks, 5);
+    kdl8(cx->ks, 6);
 #else
-    {   uint32_t i, l;
-        cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-        l = (nc * cx->n_rnd + nc - 1) / (klen >> 2);
-
-        switch(klen)
-        {
-        case 16:
-                    for(i = 0; i < l; ++i)
-                        ke4(cx->k_sch, i);
-                    break;
-        case 24:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    for(i = 0; i < l; ++i)
-                        ke6(cx->k_sch, i);
-                    break;
-        case 32:    cx->k_sch[4] = ss[4] = word_in(in_key + 16);
-                    cx->k_sch[5] = ss[5] = word_in(in_key + 20);
-                    cx->k_sch[6] = ss[6] = word_in(in_key + 24);
-                    cx->k_sch[7] = ss[7] = word_in(in_key + 28);
-                    for(i = 0; i < l; ++i)
-                        ke8(cx->k_sch,  i);
-                    break;
-        default:    cx->n_rnd = 0; return aes_bad;
-        }
-#if (DEC_ROUND != NO_TABLES)
-        for(i = nc; i < nc * cx->n_rnd; ++i)
-            cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
+    cx->ks[v(56,(4))] = ss[4] = word_in(key, 4);
+    cx->ks[v(56,(5))] = ss[5] = word_in(key, 5);
+    cx->ks[v(56,(6))] = ss[6] = word_in(key, 6);
+    cx->ks[v(56,(7))] = ss[7] = word_in(key, 7);
+    {   uint32_t i;
+
+        for(i = 0; i < 6; ++i)
+            k8e(cx->ks,  i);
+        k8ef(cx->ks,  6);
+#if !(DEC_ROUND == NO_TABLES)
+        for(i = N_COLS; i < 14 * N_COLS; ++i)
+            cx->ks[i] = inv_mcol(cx->ks[i]);
 #endif
     }
 #endif
+    cx->inf.l = 0;
+    cx->inf.b[0] = 14 * AES_BLOCK_SIZE;
 
-    return aes_good;
+#ifdef USE_VIA_ACE_IF_PRESENT
+    if(VIA_ACE_AVAILABLE)
+        cx->inf.b[1] = 0xff;
+#endif
+    MARK_AS_DECRYPTION_CTX(cx);
+    return EXIT_SUCCESS;
 }
 
 #endif
+
+#endif
+
+#if defined( AES_VAR )
+
+AES_RETURN aes_encrypt_key(const unsigned char *key, int key_len, aes_encrypt_ctx cx[1])
+{
+       switch(key_len)
+       {
+       case 16: case 128: return aes_encrypt_key128(key, cx);
+       case 24: case 192: return aes_encrypt_key192(key, cx);
+       case 32: case 256: return aes_encrypt_key256(key, cx);
+       default: return EXIT_FAILURE;
+       }
+}
+
+AES_RETURN aes_decrypt_key(const unsigned char *key, int key_len, aes_decrypt_ctx cx[1])
+{
+       switch(key_len)
+       {
+       case 16: case 128: return aes_decrypt_key128(key, cx);
+       case 24: case 192: return aes_decrypt_key192(key, cx);
+       case 32: case 256: return aes_decrypt_key256(key, cx);
+       default: return EXIT_FAILURE;
+       }
+}
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
diff --git a/src/lib/crypto/builtin/aes/aeskeypp.c b/src/lib/crypto/builtin/aes/aeskeypp.c
deleted file mode 100644 (file)
index cd9c5a7..0000000
+++ /dev/null
@@ -1,400 +0,0 @@
-/*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
-
-/*
- * Issue Date: 21/01/2002
- *
- * This file contains the code for implementing the key schedule for AES
- * (Rijndael) for block and key sizes of 16, 20, 24, 28 and 32 bytes.
- */
-
-#include "aesopt.h"
-
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32.
-*/
-
-#if !defined(BLOCK_SIZE) && defined(SET_BLOCK_LENGTH)
-
-/* Subroutine to set the block size (if variable) in bytes, legal
-   values being 16, 24 and 32.
-*/
-
-aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1])
-{
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-    if((blen & 3) || blen < 16 || blen > 32)
-    {
-        cx->n_blk = 0; return aes_bad;
-    }
-
-    cx->n_blk = blen;
-    return aes_good;
-}
-
-#endif
-
-/* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 24 or 32 as appropriate.
-   This corresponds to bit lengths of 128, 192 and 256 bits, and
-   to Nk values of 4, 6 and 8 respectively.
-
-   The following macros implement a single cycle in the key
-   schedule generation process. The number of cycles needed
-   for each cx->n_blk and nk value is:
-
-    nk =             4  5  6  7  8
-    ------------------------------
-    cx->n_blk = 4   10  9  8  7  7
-    cx->n_blk = 5   14 11 10  9  9
-    cx->n_blk = 6   19 15 12 11 11
-    cx->n_blk = 7   21 19 16 13 14
-    cx->n_blk = 8   29 23 19 17 14
-*/
-
-/* Initialise the key schedule from the user supplied key. The key
-   length is now specified in bytes - 16, 20, 24, 28 or 32 as
-   appropriate. This corresponds to bit lengths of 128, 160, 192,
-   224 and 256 bits, and to Nk values of 4, 5, 6, 7 & 8 respectively.
- */
-
-#define mx(t,f) (*t++ = inv_mcol(*f),f++)
-#define cp(t,f) *t++ = *f++
-
-#if   BLOCK_SIZE == 16
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 20
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s)
-#elif BLOCK_SIZE == 24
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 28
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s); mx(d,s)
-#elif BLOCK_SIZE == 32
-#define cpy(d,s)    cp(d,s); cp(d,s); cp(d,s); cp(d,s); \
-                    cp(d,s); cp(d,s); cp(d,s); cp(d,s)
-#define mix(d,s)    mx(d,s); mx(d,s); mx(d,s); mx(d,s); \
-                    mx(d,s); mx(d,s); mx(d,s); mx(d,s)
-#else
-
-#define cpy(d,s) \
-switch(nc) \
-{   case 8: cp(d,s); \
-    case 7: cp(d,s); \
-    case 6: cp(d,s); \
-    case 5: cp(d,s); \
-    case 4: cp(d,s); cp(d,s); \
-            cp(d,s); cp(d,s); \
-}
-
-#define mix(d,s) \
-switch(nc) \
-{   case 8: mx(d,s); \
-    case 7: mx(d,s); \
-    case 6: mx(d,s); \
-    case 5: mx(d,s); \
-    case 4: mx(d,s); mx(d,s); \
-            mx(d,s); mx(d,s); \
-}
-
-#endif
-
-/*  The following macros implement a single cycle in the key
-    schedule generation process. The number of cycles needed
-    for each cx->n_blk and nk value is:
-
-    nk =      4  5  6  7  8
-    -----------------------
-    cx->n_blk = 4   10  9  8  7  7
-    cx->n_blk = 5   14 11 10  9  9
-    cx->n_blk = 6   19 15 12 11 11
-    cx->n_blk = 7   21 19 16 13 14
-    cx->n_blk = 8   29 23 19 17 14
-*/
-
-#define ks4(i) \
-{   p ^= ls_box(s,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    cx->k_sch[4*(i)+4] = p; \
-    cx->k_sch[4*(i)+5] = q; \
-    cx->k_sch[4*(i)+6] = r; \
-    cx->k_sch[4*(i)+7] = s; \
-}
-
-#define ks5(i) \
-{   p ^= ls_box(t,3) ^ rcon_tab[i]; q ^= p; \
-    r ^= q; s ^= r; t ^= s; \
-    cx->k_sch[5*(i)+ 5] = p; \
-    cx->k_sch[5*(i)+ 6] = q; \
-    cx->k_sch[5*(i)+ 7] = r; \
-    cx->k_sch[5*(i)+ 8] = s; \
-    cx->k_sch[5*(i)+ 9] = t; \
-}
-
-#define ks6(i) \
-{   p ^= ls_box(u,3) ^ rcon_tab[i]; q ^= p; \
-    r ^= q; s ^= r; t ^= s; u ^= t; \
-    cx->k_sch[6*(i)+ 6] = p; \
-    cx->k_sch[6*(i)+ 7] = q; \
-    cx->k_sch[6*(i)+ 8] = r; \
-    cx->k_sch[6*(i)+ 9] = s; \
-    cx->k_sch[6*(i)+10] = t; \
-    cx->k_sch[6*(i)+11] = u; \
-}
-
-#define ks7(i) \
-{   p ^= ls_box(v,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    t ^= ls_box(s,0); u ^= t; v ^= u; \
-    cx->k_sch[7*(i)+ 7] = p; \
-    cx->k_sch[7*(i)+ 8] = q; \
-    cx->k_sch[7*(i)+ 9] = r; \
-    cx->k_sch[7*(i)+10] = s; \
-    cx->k_sch[7*(i)+11] = t; \
-    cx->k_sch[7*(i)+12] = u; \
-    cx->k_sch[7*(i)+13] = v; \
-}
-
-#define ks8(i) \
-{   p ^= ls_box(w,3) ^ rcon_tab[i]; q ^= p; r ^= q; s ^= r; \
-    t ^= ls_box(s,0); u ^= t; v ^= u; w ^= v; \
-    cx->k_sch[8*(i)+ 8] = p; \
-    cx->k_sch[8*(i)+ 9] = q; \
-    cx->k_sch[8*(i)+10] = r; \
-    cx->k_sch[8*(i)+11] = s; \
-    cx->k_sch[8*(i)+12] = t; \
-    cx->k_sch[8*(i)+13] = u; \
-    cx->k_sch[8*(i)+14] = v; \
-    cx->k_sch[8*(i)+15] = w; \
-}
-
-#if defined(ENCRYPTION_KEY_SCHEDULE)
-
-aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
-{   uint32_t    i,p,q,r,s,t,u,v,w;
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3) | 1;
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-
-    cx->k_sch[0] = p = word_in(in_key     );
-    cx->k_sch[1] = q = word_in(in_key +  4);
-    cx->k_sch[2] = r = word_in(in_key +  8);
-    cx->k_sch[3] = s = word_in(in_key + 12);
-
-#if BLOCK_SIZE == 16 && defined(UNROLL)
-
-    switch(klen >> 2)
-    {
-    case 4: ks4(0); ks4(1); ks4(2); ks4(3);
-            ks4(4); ks4(5); ks4(6); ks4(7);
-            ks4(8); ks4(9);
-            cx->n_rnd = 10; break;
-    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-            ks5(0); ks5(1); ks5(2); ks5(3);
-            ks5(4); ks5(5); ks5(6); ks5(7);
-            ks5(8);
-            cx->n_rnd = 11; break;
-    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            ks6(0); ks6(1); ks6(2); ks6(3);
-            ks6(4); ks6(5); ks6(6); ks6(7);
-            cx->n_rnd = 12; break;
-    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            ks7(0); ks7(1); ks7(2); ks7(3);
-            ks7(4); ks7(5); ks7(6);
-            cx->n_rnd = 13; break;
-    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            cx->k_sch[7] = w = word_in(in_key + 28);
-            ks8(0); ks8(1); ks8(2); ks8(3);
-            ks8(4); ks8(5); ks8(6);
-            cx->n_rnd = 14; break;
-    default:cx->n_rnd = 0; return aes_bad;
-    }
-#else
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-    {
-        uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
-        switch(klen >> 2)
-        {
-        case 4: for(i = 0; i < l; ++i)
-                    ks4(i);
-                break;
-        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-                for(i = 0; i < l; ++i)
-                    ks5(i);
-                break;
-        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                for(i = 0; i < l; ++i)
-                    ks6(i);
-                break;
-        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                for(i = 0; i < l; ++i)
-                    ks7(i);
-                break;
-        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                cx->k_sch[7] = w = word_in(in_key + 28);
-                for(i = 0; i < l; ++i)
-                    ks8(i);
-                break;
-        }
-    }
-#endif
-
-    return aes_good;
-}
-
-#endif
-
-#if defined(DECRYPTION_KEY_SCHEDULE)
-
-aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1])
-{   uint32_t    i,p,q,r,s,t,u,v,w;
-    dec_imvars
-
-#if !defined(FIXED_TABLES)
-    if(!tab_init) gen_tabs();
-#endif
-
-#if !defined(BLOCK_SIZE)
-    if(!cx->n_blk) cx->n_blk = 16;
-#else
-    cx->n_blk = BLOCK_SIZE;
-#endif
-
-    cx->n_blk = (cx->n_blk & ~3) | 2;
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-
-    cx->k_sch[0] = p = word_in(in_key     );
-    cx->k_sch[1] = q = word_in(in_key +  4);
-    cx->k_sch[2] = r = word_in(in_key +  8);
-    cx->k_sch[3] = s = word_in(in_key + 12);
-
-#if BLOCK_SIZE == 16 && defined(UNROLL)
-
-    switch(klen >> 2)
-    {
-    case 4: ks4(0); ks4(1); ks4(2); ks4(3);
-            ks4(4); ks4(5); ks4(6); ks4(7);
-            ks4(8); ks4(9);
-            cx->n_rnd = 10; break;
-    case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-            ks5(0); ks5(1); ks5(2); ks5(3);
-            ks5(4); ks5(5); ks5(6); ks5(7);
-            ks5(8);
-            cx->n_rnd = 11; break;
-    case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            ks6(0); ks6(1); ks6(2); ks6(3);
-            ks6(4); ks6(5); ks6(6); ks6(7);
-            cx->n_rnd = 12; break;
-    case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            ks7(0); ks7(1); ks7(2); ks7(3);
-            ks7(4); ks7(5); ks7(6);
-            cx->n_rnd = 13; break;
-    case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-            cx->k_sch[5] = u = word_in(in_key + 20);
-            cx->k_sch[6] = v = word_in(in_key + 24);
-            cx->k_sch[7] = w = word_in(in_key + 28);
-            ks8(0); ks8(1); ks8(2); ks8(3);
-            ks8(4); ks8(5); ks8(6);
-            cx->n_rnd = 14; break;
-    default:cx->n_rnd = 0; return aes_bad;
-    }
-#else
-    cx->n_rnd = ((klen >> 2) > nc ? (klen >> 2) : nc) + 6;
-    {
-        uint32_t l = (nc * (cx->n_rnd + 1) - 1) / (klen >> 2);
-        switch(klen >> 2)
-        {
-        case 4: for(i = 0; i < l; ++i)
-                    ks4(i);
-                break;
-        case 5: cx->k_sch[4] = t = word_in(in_key + 16);
-                for(i = 0; i < l; ++i)
-                    ks5(i);
-                break;
-        case 6: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                for(i = 0; i < l; ++i)
-                    ks6(i);
-                break;
-        case 7: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                for(i = 0; i < l; ++i)
-                    ks7(i);
-                break;
-        case 8: cx->k_sch[4] = t = word_in(in_key + 16);
-                cx->k_sch[5] = u = word_in(in_key + 20);
-                cx->k_sch[6] = v = word_in(in_key + 24);
-                cx->k_sch[7] = w = word_in(in_key + 28);
-                for(i = 0; i < l; ++i)
-                    ks8(i);
-                break;
-        }
-    }
-#endif
-
-#if (DEC_ROUND != NO_TABLES)
-    for(i = nc; i < nc * cx->n_rnd; ++i)
-        cx->k_sch[i] = inv_mcol(cx->k_sch[i]);
-#endif
-
-    return aes_good;
-}
-
-#endif
index 6588b7fc86869e8fe5650416c07da5acb24aaac2..5d24c8a8bd3c69b243c6a1c3ae3285f055d3c5a2 100644 (file)
 /*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
 
-/*
- Issue Date: 07/02/2002
-
- This file contains the compilation options for AES (Rijndael) and code
- that is common across encryption, key scheduling and table generation.
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
 
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
 
-    OPERATION
-
-    These source code files implement the AES algorithm Rijndael designed by
-    Joan Daemen and Vincent Rijmen. The version in aes.c is designed for
-    block and key sizes of 128, 192 and 256 bits (16, 24 and 32 bytes) while
-    that in aespp.c provides for block and keys sizes of 128, 160, 192, 224
-    and 256 bits (16, 20, 24, 28 and 32 bytes).  This file is a common header
-    file for these two implementations and for aesref.c, which is a reference
-    implementation.
-
-    This version is designed for flexibility and speed using operations on
-    32-bit words rather than operations on bytes.  It provides aes_both fixed
-    and  dynamic block and key lengths and can also run with either big or
-    little endian internal byte order (see aes.h).  It inputs block and key
-    lengths in bytes with the legal values being  16, 24 and 32 for aes.c and
-    16, 20, 24, 28 and 32 for aespp.c
-
-    THE CIPHER INTERFACE
-
-    uint8_t         (an unsigned  8-bit type)
-    uint32_t        (an unsigned 32-bit type)
-    aes_fret        (a signed 16 bit type for function return values)
-    aes_good        (value != 0, a good return)
-    aes_bad         (value == 0, an error return)
-    struct aes_ctx  (structure for the cipher encryption context)
-    struct aes_ctx  (structure for the cipher decryption context)
-    aes_rval        the function return type (aes_fret if not DLL)
-
-    C subroutine calls:
-
-      aes_rval aes_blk_len(unsigned int blen, aes_ctx cx[1]);
-      aes_rval aes_enc_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
-      aes_rval aes_enc_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
-
-      aes_rval aes_dec_len(unsigned int blen, aes_ctx cx[1]);
-      aes_rval aes_dec_key(const unsigned char in_key[], unsigned int klen, aes_ctx cx[1]);
-      aes_rval aes_dec_blk(const unsigned char in_blk[], unsigned char out_blk[], const aes_ctx cx[1]);
-
-    IMPORTANT NOTE: If you are using this C interface and your compiler does
-    not set the memory used for objects to zero before use, you will need to
-    ensure that cx.s_flg is set to zero before using these subroutine calls.
-
-    C++ aes class subroutines:
-
-      class AESclass    for encryption
-      class AESclass    for decryption
-
-      aes_rval len(unsigned int blen = 16);
-      aes_rval key(const unsigned char in_key[], unsigned int klen);
-      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
-
-      aes_rval len(unsigned int blen = 16);
-      aes_rval key(const unsigned char in_key[], unsigned int klen);
-      aes_rval blk(const unsigned char in_blk[], unsigned char out_blk[]);
-
-    The block length inputs to set_block and set_key are in numbers of
-    BYTES, not bits.  The calls to subroutines must be made in the above
-    order but multiple calls can be made without repeating earlier calls
-    if their parameters have not changed. If the cipher block length is
-    variable but set_blk has not been called before cipher operations a
-    value of 16 is assumed (that is, the AES block size). In contrast to
-    earlier versions the block and key length parameters are now checked
-    for correctness and the encryption and decryption routines check to
-    ensure that an appropriate key has been set before they are called.
-
-    COMPILATION
-
-    The files used to provide AES (Rijndael) are
-
-    a. aes.h for the definitions needed for use in C.
-    b. aescpp.h for the definitions needed for use in C++.
-    c. aesopt.h for setting compilation options (also includes common
-       code).
-    d. aescrypt.c for encryption and decrytpion, or
-    e. aescrypt.asm for encryption and decryption using assembler code.
-    f. aeskey.c for key scheduling.
-    g. aestab.c for table loading or generation.
-    h. uitypes.h for defining fixed length unsigned integers.
-
-    The assembler code uses the NASM assembler. The above files provice
-    block and key lengths of 16, 24 and 32 bytes (128, 192 and 256 bits).
-    If aescrypp.c and aeskeypp.c are used instead of aescrypt.c and
-    aeskey.c respectively, the block and key lengths can then be 16, 20,
-    24, 28 or 32 bytes. However this code has not been optimised to the
-    same extent and is hence slower (esepcially for the AES block size
-    of 16 bytes).
-
-    To compile AES (Rijndael) for use in C code use aes.h and exclude
-    the AES_DLL define in aes.h
-
-    To compile AES (Rijndael) for use in in C++ code use aescpp.h and
-    exclude the AES_DLL define in aes.h
-
-    To compile AES (Rijndael) in C as a Dynamic Link Library DLL) use
-    aes.h, include the AES_DLL define and compile the DLL.  If using
-    the test files to test the DLL, exclude aes.c from the test build
-    project and compile it with the same defines as used for the DLL
-    (ensure that the DLL path is correct)
-
-    CONFIGURATION OPTIONS (here and in aes.h)
-
-    a. define BLOCK_SIZE in aes.h to set the cipher block size (16, 24
-       or 32 for the standard code, or 16, 20, 24, 28 or 32 for the
-       extended code) or leave this undefined for dynamically variable
-       block size (this will result in much slower code).
-    b. set AES_DLL in aes.h if AES (Rijndael) is to be compiled as a DLL
-    c. You may need to set PLATFORM_BYTE_ORDER to define the byte order.
-    d. If you want the code to run in a specific internal byte order, then
-       INTERNAL_BYTE_ORDER must be set accordingly.
-    e. set other configuration options decribed below.
-*/
-
-#ifndef _AESOPT_H
-#define _AESOPT_H
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
 
-/*  START OF CONFIGURATION OPTIONS
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 20/12/2007
 
-    USE OF DEFINES
+ This file contains the compilation options for AES (Rijndael) and code
+ that is common across encryption, key scheduling and table generation.
 
-    Later in this section there are a number of defines that control
-    the operation of the code.  In each section, the purpose of each
-    define is explained so that the relevant form can be included or
-    excluded by setting either 1's or 0's respectively on the branches
-    of the related #if clauses.
+ OPERATION
+
+ These source code files implement the AES algorithm Rijndael designed by
+ Joan Daemen and Vincent Rijmen. This version is designed for the standard
+ block size of 16 bytes and for key sizes of 128, 192 and 256 bits (16, 24
+ and 32 bytes).
+
+ This version is designed for flexibility and speed using operations on
+ 32-bit words rather than operations on bytes.  It can be compiled with
+ either big or little endian internal byte order but is faster when the
+ native byte order for the processor is used.
+
+ THE CIPHER INTERFACE
+
+ The cipher interface is implemented as an array of bytes in which lower
+ AES bit sequence indexes map to higher numeric significance within bytes.
+
+  uint8_t                 (an unsigned  8-bit type)
+  uint32_t                (an unsigned 32-bit type)
+  struct aes_encrypt_ctx  (structure for the cipher encryption context)
+  struct aes_decrypt_ctx  (structure for the cipher decryption context)
+  AES_RETURN                the function return type
+
+  C subroutine calls:
+
+  AES_RETURN aes_encrypt_key128(const unsigned char *key, aes_encrypt_ctx cx[1]);
+  AES_RETURN aes_encrypt_key192(const unsigned char *key, aes_encrypt_ctx cx[1]);
+  AES_RETURN aes_encrypt_key256(const unsigned char *key, aes_encrypt_ctx cx[1]);
+  AES_RETURN aes_encrypt(const unsigned char *in, unsigned char *out,
+                                                  const aes_encrypt_ctx cx[1]);
+
+  AES_RETURN aes_decrypt_key128(const unsigned char *key, aes_decrypt_ctx cx[1]);
+  AES_RETURN aes_decrypt_key192(const unsigned char *key, aes_decrypt_ctx cx[1]);
+  AES_RETURN aes_decrypt_key256(const unsigned char *key, aes_decrypt_ctx cx[1]);
+  AES_RETURN aes_decrypt(const unsigned char *in, unsigned char *out,
+                                                  const aes_decrypt_ctx cx[1]);
+
+ IMPORTANT NOTE: If you are using this C interface with dynamic tables make sure that
+ you call aes_init() before AES is used so that the tables are initialised.
+
+ C++ aes class subroutines:
+
+     Class AESencrypt  for encryption
+
+      Constructors:
+          AESencrypt(void)
+          AESencrypt(const unsigned char *key) - 128 bit key
+      Members:
+          AES_RETURN key128(const unsigned char *key)
+          AES_RETURN key192(const unsigned char *key)
+          AES_RETURN key256(const unsigned char *key)
+          AES_RETURN encrypt(const unsigned char *in, unsigned char *out) const
+
+      Class AESdecrypt  for encryption
+      Constructors:
+          AESdecrypt(void)
+          AESdecrypt(const unsigned char *key) - 128 bit key
+      Members:
+          AES_RETURN key128(const unsigned char *key)
+          AES_RETURN key192(const unsigned char *key)
+          AES_RETURN key256(const unsigned char *key)
+          AES_RETURN decrypt(const unsigned char *in, unsigned char *out) const
 */
 
-#include "autoconf.h"
-
-/*  1. PLATFORM SPECIFIC INCLUDES */
-
-#if /* defined(__GNUC__) || */ defined(__GNU_LIBRARY__)
-#  include <endian.h>
-#  include <byteswap.h>
-#elif defined(__CRYPTLIB__)
-#  if defined( INC_ALL )
-#    include "crypt.h"
-#  elif defined( INC_CHILD )
-#    include "../crypt.h"
-#  else
-#    include "crypt.h"
-#  endif
-#  if defined(DATA_LITTLEENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  else
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif defined(_MSC_VER)
-#  include <stdlib.h>
-#elif defined(__m68k__) && defined(__palmos__)
-#  include <FloatMgr.h> /* defines BIG_ENDIAN */
-#elif defined(_MIPSEB)
-#  define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#elif defined(_MIPSEL)
-#  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif defined(_WIN32)
-#  define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif !defined(_WIN32)
-#  include <stdlib.h>
-#  if defined(HAVE_ENDIAN_H)
-#    include <endian.h>
-#  elif defined(HAVE_MACHINE_ENDIAN_H)
-#    include <machine/endian.h>
-#  else
-#    include <sys/param.h>
-#  endif
-#endif
-
-/*  2. BYTE ORDER IN 32-BIT WORDS
+#if !defined( _AESOPT_H )
+#define _AESOPT_H
 
-    To obtain the highest speed on processors with 32-bit words, this code
-    needs to determine the order in which bytes are packed into such words.
-    The following block of code is an attempt to capture the most obvious
-    ways in which various environemnts specify heir endian definitions. It
-    may well fail, in which case the definitions will need to be set by
-    editing at the points marked **** EDIT HERE IF NECESSARY **** below.
-*/
-#define AES_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
-#define AES_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
-
-#if !defined(PLATFORM_BYTE_ORDER)
-#if defined(LITTLE_ENDIAN) || defined(BIG_ENDIAN)
-#  if defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-#    if defined(BYTE_ORDER)
-#      if   (BYTE_ORDER == LITTLE_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#      elif (BYTE_ORDER == BIG_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#      endif
-#    endif
-#  elif defined(LITTLE_ENDIAN) && !defined(BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  elif !defined(LITTLE_ENDIAN) && defined(BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif defined(_LITTLE_ENDIAN) || defined(_BIG_ENDIAN)
-#  if defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
-#    if defined(_BYTE_ORDER)
-#      if   (_BYTE_ORDER == _LITTLE_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#      elif (_BYTE_ORDER == _BIG_ENDIAN)
-#        define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#      endif
-#    endif
-#  elif defined(_LITTLE_ENDIAN) && !defined(_BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#  elif !defined(_LITTLE_ENDIAN) && defined(_BIG_ENDIAN)
-#    define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#  endif
-#elif 0     /* **** EDIT HERE IF NECESSARY **** */
-#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif 0     /* **** EDIT HERE IF NECESSARY **** */
-#define PLATFORM_BYTE_ORDER AES_BIG_ENDIAN
-#elif 1
-#define PLATFORM_BYTE_ORDER AES_LITTLE_ENDIAN
-#define UNKNOWN_BYTE_ORDER     /* we're guessing */
-#endif
+#if defined( __cplusplus )
+#include "aescpp.h"
+#else
+#include "aes.h"
 #endif
 
-/*  3. ASSEMBLER SUPPORT
+/*  PLATFORM SPECIFIC INCLUDES */
 
-    If the assembler code is used for encryption and decryption this file only
-    provides key scheduling so the following defines are used
-*/
-#ifdef  AES_ASM
-#define ENCRYPTION_KEY_SCHEDULE
-#define DECRYPTION_KEY_SCHEDULE
-#endif
+#include "brg_endian.h"
 
-/*  4. FUNCTIONS REQUIRED
+/*  CONFIGURATION - THE USE OF DEFINES
 
-    This implementation provides five main subroutines which provide for
-    setting block length, setting encryption and decryption keys and for
-    encryption and decryption. When the assembler code is not being used
-    the following definition blocks allow the selection of the routines
-    that are to be included in the compilation.
+    Later in this section there are a number of defines that control the
+    operation of the code.  In each section, the purpose of each define is
+    explained so that the relevant form can be included or excluded by
+    setting either 1's or 0's respectively on the branches of the related
+    #if clauses.  The following local defines should not be changed.
 */
-#if 1
-#ifndef AES_ASM
-#define SET_BLOCK_LENGTH
-#endif
-#endif
 
-#if 1
-#ifndef AES_ASM
-#define ENCRYPTION_KEY_SCHEDULE
-#endif
-#endif
-
-#if 1
-#ifndef AES_ASM
-#define DECRYPTION_KEY_SCHEDULE
-#endif
-#endif
+#define ENCRYPTION_IN_C     1
+#define DECRYPTION_IN_C     2
+#define ENC_KEYING_IN_C     4
+#define DEC_KEYING_IN_C     8
 
-#if 1
-#ifndef AES_ASM
-#define ENCRYPTION
-#endif
-#endif
+#define NO_TABLES           0
+#define ONE_TABLE           1
+#define FOUR_TABLES         4
+#define NONE                0
+#define PARTIAL             1
+#define FULL                2
 
-#if 1
-#ifndef AES_ASM
-#define DECRYPTION
-#endif
-#endif
+/*  --- START OF USER CONFIGURED OPTIONS --- */
 
-/*  5. BYTE ORDER WITHIN 32 BIT WORDS
+/*  1. BYTE ORDER WITHIN 32 BIT WORDS
 
     The fundamental data processing units in Rijndael are 8-bit bytes. The
     input, output and key input are all enumerated arrays of bytes in which
     machine on which it runs. Normally the internal byte order will be set
     to the order of the processor on which the code is to be run but this
     define can be used to reverse this in special situations
+
+    WARNING: Assembler code versions rely on PLATFORM_BYTE_ORDER being set.
+    This define will hence be redefined later (in section 4) if necessary
 */
+
 #if 1
-#define INTERNAL_BYTE_ORDER PLATFORM_BYTE_ORDER
-#elif defined(AES_LITTLE_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_LITTLE_ENDIAN
-#elif defined(AES_BIG_ENDIAN)
-#define INTERNAL_BYTE_ORDER AES_BIG_ENDIAN
+#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
+#elif 0
+#  define ALGORITHM_BYTE_ORDER IS_LITTLE_ENDIAN
+#elif 0
+#  define ALGORITHM_BYTE_ORDER IS_BIG_ENDIAN
+#else
+#  error The algorithm byte order is not defined
 #endif
 
-/*  6. FAST INPUT/OUTPUT OPERATIONS.
+/*  2. Intel AES AND VIA ACE SUPPORT */
+
+#if defined( __GNUC__ ) && defined( __i386__ ) && !defined(__BEOS__)  \
+ || defined( _WIN32 ) && defined( _M_IX86 ) && !(defined( _WIN64 ) \
+ || defined( _WIN32_WCE ) || defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
+#  define VIA_ACE_POSSIBLE
+#endif
+
+/* AESNI is supported by all Windows x64 compilers, but for Linux/GCC
+   we have to test for SSE 2, SSE 3, and AES to before enabling it; */
+#if !defined( INTEL_AES_POSSIBLE )
+#  if defined( _WIN64 ) && defined( _MSC_VER ) \
+   || defined( __GNUC__ ) && defined( __x86_64__ ) && \
+         defined( __SSE2__ ) && defined( __SSE3__ ) && \
+         defined( __AES__ )
+#    define INTEL_AES_POSSIBLE
+#  endif
+#endif
+
+/*  Define this option if support for the Intel AESNI is required
+    If USE_INTEL_AES_IF_PRESENT is defined then AESNI will be used
+    if it is detected (both present and enabled).
+
+       AESNI uses a decryption key schedule with the first decryption
+       round key at the high end of the key schedule with the following
+       round keys at lower positions in memory.  So AES_REV_DKS must NOT
+       be defined when AESNI will be used.  Although it is unlikely that
+       assembler code will be used with an AESNI build, if it is then
+       AES_REV_DKS must NOT be defined when the assembler files are
+       built (the definition of USE_INTEL_AES_IF_PRESENT in the assembler
+       code files must match that here if they are used). 
+*/
+
+#if defined( INTEL_AES_POSSIBLE )
+#  if 0 && !defined( USE_INTEL_AES_IF_PRESENT )
+#    define USE_INTEL_AES_IF_PRESENT
+#  endif
+#elif defined( USE_INTEL_AES_IF_PRESENT )
+#  error: AES_NI is not available on this platform
+#endif
+
+/*  Define this option if support for the VIA ACE is required. This uses
+    inline assembler instructions and is only implemented for the Microsoft,
+    Intel and GCC compilers.  If VIA ACE is known to be present, then defining
+    ASSUME_VIA_ACE_PRESENT will remove the ordinary encryption/decryption
+    code.  If USE_VIA_ACE_IF_PRESENT is defined then VIA ACE will be used if
+    it is detected (both present and enabled) but the normal AES code will
+    also be present.
+
+    When VIA ACE is to be used, all AES encryption contexts MUST be 16 byte
+    aligned; other input/output buffers do not need to be 16 byte aligned
+    but there are very large performance gains if this can be arranged.
+    VIA ACE also requires the decryption key schedule to be in reverse
+    order (which later checks below ensure).
+
+       AES_REV_DKS must be set for assembler code used with a VIA ACE build
+*/
+
+#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( USE_VIA_ACE_IF_PRESENT )
+#  define USE_VIA_ACE_IF_PRESENT
+#endif
+
+#if 0 && defined( VIA_ACE_POSSIBLE ) && !defined( ASSUME_VIA_ACE_PRESENT )
+#  define ASSUME_VIA_ACE_PRESENT
+#  endif
+
+/*  3. ASSEMBLER SUPPORT
+
+    This define (which can be on the command line) enables the use of the
+    assembler code routines for encryption, decryption and key scheduling
+    as follows:
+
+    ASM_X86_V1C uses the assembler (aes_x86_v1.asm) with large tables for
+                encryption and decryption and but with key scheduling in C
+    ASM_X86_V2  uses assembler (aes_x86_v2.asm) with compressed tables for
+                encryption, decryption and key scheduling
+    ASM_X86_V2C uses assembler (aes_x86_v2.asm) with compressed tables for
+                encryption and decryption and but with key scheduling in C
+    ASM_AMD64_C uses assembler (aes_amd64.asm) with compressed tables for
+                encryption and decryption and but with key scheduling in C
+
+    Change one 'if 0' below to 'if 1' to select the version or define
+    as a compilation option.
+*/
+
+#if 0 && !defined( ASM_X86_V1C )
+#  define ASM_X86_V1C
+#elif 0 && !defined( ASM_X86_V2  )
+#  define ASM_X86_V2
+#elif 0 && !defined( ASM_X86_V2C )
+#  define ASM_X86_V2C
+#elif 0 && !defined( ASM_AMD64_C )
+#  define ASM_AMD64_C
+#endif
+
+#if defined( __i386 ) || defined( _M_IX86 )
+#  define A32_
+#elif defined( __x86_64__ ) || defined( _M_X64 )
+#  define A64_
+#endif
+
+#if (defined ( ASM_X86_V1C ) || defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )) \
+       && !defined( A32_ )  || defined( ASM_AMD64_C ) && !defined( A64_ )
+#  error Assembler code is only available for x86 and AMD64 systems
+#endif
+
+/*  4. FAST INPUT/OUTPUT OPERATIONS.
 
     On some machines it is possible to improve speed by transferring the
     bytes in the input and output arrays to and from the internal 32-bit
     assumed that access to byte arrays as if they are arrays of 32-bit
     words will not cause problems when such accesses are misaligned.
 */
-#if 1
-#define SAFE_IO
+#if 1 && !defined( _MSC_VER )
+#  define SAFE_IO
 #endif
 
-/*
- * If PLATFORM_BYTE_ORDER does not match the actual machine byte
- * order, the fast word-access code will cause incorrect results.
- * Therefore, SAFE_IO is required when the byte order is unknown.
- */
-#if !defined(SAFE_IO) && defined(UNKNOWN_BYTE_ORDER)
-#  error "SAFE_IO must be defined if machine byte order is unknown."
-#endif
+/*  5. LOOP UNROLLING
 
-/*  7. LOOP UNROLLING
-
-    The code for encryption and decrytpion cycles through a number of rounds
+    The code for encryption and decryption cycles through a number of rounds
     that can be implemented either in a loop or by expanding the code into a
     long sequence of instructions, the latter producing a larger program but
     one that will often be much faster. The latter is called loop unrolling.
     to be set independently for encryption and decryption
 */
 #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
-#define ENC_UNROLL  FULL
+#  define ENC_UNROLL  FULL
 #elif 0
-#define ENC_UNROLL  PARTIAL
+#  define ENC_UNROLL  PARTIAL
 #else
-#define ENC_UNROLL  NONE
+#  define ENC_UNROLL  NONE
 #endif
 
 #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
-#define DEC_UNROLL  FULL
+#  define DEC_UNROLL  FULL
 #elif 0
-#define DEC_UNROLL  PARTIAL
+#  define DEC_UNROLL  PARTIAL
 #else
-#define DEC_UNROLL  NONE
+#  define DEC_UNROLL  NONE
 #endif
 
-/*  8. FIXED OR DYNAMIC TABLES
+#if 1
+#  define ENC_KS_UNROLL
+#endif
 
-    When this section is included the tables used by the code are compiled
-    statically into the binary file.  Otherwise they are computed once when
-    the code is first used.
-*/
 #if 1
-#define FIXED_TABLES
+#  define DEC_KS_UNROLL
 #endif
 
-/*  9. FAST FINITE FIELD OPERATIONS
+/*  6. FAST FINITE FIELD OPERATIONS
 
     If this section is included, tables are used to provide faster finite
-    field arithmetic (this has no effect if FIXED_TABLES is defined).
+    field arithmetic (this has no effect if STATIC_TABLES is defined).
 */
 #if 1
-#define FF_TABLES
+#  define FF_TABLES
 #endif
 
-/*  10. INTERNAL STATE VARIABLE FORMAT
+/*  7. INTERNAL STATE VARIABLE FORMAT
 
     The internal state of Rijndael is stored in a number of local 32-bit
-    word varaibles which can be defined either as an array or as individual
+    word variables which can be defined either as an array or as individual
     names variables. Include this section if you want to store these local
-    varaibles in arrays. Otherwise individual local variables will be used.
+    variables in arrays. Otherwise individual local variables will be used.
 */
 #if 1
-#define ARRAYS
+#  define ARRAYS
 #endif
 
-/* In this implementation the columns of the state array are each held in
-   32-bit words. The state array can be held in various ways: in an array
-   of words, in a number of individual word variables or in a number of
-   processor registers. The following define maps a variable name x and
-   a column number c to the way the state array variable is to be held.
-   The first define below maps the state into an array x[c] whereas the
-   second form maps the state into a number of individual variables x0,
-   x1, etc.  Another form could map individual state colums to machine
-   register names.
+/*  8. FIXED OR DYNAMIC TABLES
+
+    When this section is included the tables used by the code are compiled
+    statically into the binary file.  Otherwise the subroutine aes_init()
+    must be called to compute them before the code is first used.
 */
+#if 1 && !(defined( _MSC_VER ) && ( _MSC_VER <= 800 ))
+#  define STATIC_TABLES
+#endif
+
+/*  9. MASKING OR CASTING FROM LONGER VALUES TO BYTES
 
-#if defined(ARRAYS)
-#define s(x,c) x[c]
+    In some systems it is better to mask longer values to extract bytes
+    rather than using a cast. This option allows this choice.
+*/
+#if 0
+#  define to_byte(x)  ((uint8_t)(x))
 #else
-#define s(x,c) x##c
+#  define to_byte(x)  ((x) & 0xff)
 #endif
 
-/*  11. VARIABLE BLOCK SIZE SPEED
+/*  10. TABLE ALIGNMENT
 
-    This section is only relevant if you wish to use the variable block
-    length feature of the code.  Include this section if you place more
-    emphasis on speed rather than code size.
+    On some systems speed will be improved by aligning the AES large lookup
+    tables on particular boundaries. This define should be set to a power of
+    two giving the desired alignment. It can be left undefined if alignment
+    is not needed.  This option is specific to the Microsoft VC++ compiler -
+    it seems to sometimes cause trouble for the VC++ version 6 compiler.
 */
-#if 1
-#define FAST_VARIABLE
+
+#if 1 && defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
+#  define TABLE_ALIGN 32
 #endif
 
-/*  12. INTERNAL TABLE CONFIGURATION
+/*  11.  REDUCE CODE AND TABLE SIZE
+
+    This replaces some expanded macros with function calls if AES_ASM_V2 or
+    AES_ASM_V2C are defined
+*/
+
+#if 1 && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C ))
+#  define REDUCE_CODE_SIZE
+#endif
+
+/*  12. TABLE OPTIONS
 
     This cipher proceeds by repeating in a number of cycles known as 'rounds'
     which are implemented by a round function which can optionally be speeded
     up using tables.  The basic tables are each 256 32-bit words, with either
     one or four tables being required for each round function depending on
     how much speed is required. The encryption and decryption round functions
-    are different and the last encryption and decrytpion round functions are
+    are different and the last encryption and decryption round functions are
     different again making four different round functions in all.
 
     This means that:
 */
 
 #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)   /* set tables for the normal encryption round */
-#define ENC_ROUND   FOUR_TABLES
+#  define ENC_ROUND   FOUR_TABLES
 #elif 0
-#define ENC_ROUND   ONE_TABLE
+#  define ENC_ROUND   ONE_TABLE
 #else
-#define ENC_ROUND   NO_TABLES
+#  define ENC_ROUND   NO_TABLES
 #endif
 
-#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)       /* set tables for the last encryption round */
-#define LAST_ENC_ROUND  FOUR_TABLES
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)   /* set tables for the last encryption round */
+#  define LAST_ENC_ROUND  FOUR_TABLES
 #elif 0
-#define LAST_ENC_ROUND  ONE_TABLE
+#  define LAST_ENC_ROUND  ONE_TABLE
 #else
-#define LAST_ENC_ROUND  NO_TABLES
+#  define LAST_ENC_ROUND  NO_TABLES
 #endif
 
 #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)   /* set tables for the normal decryption round */
-#define DEC_ROUND   FOUR_TABLES
+#  define DEC_ROUND   FOUR_TABLES
 #elif 0
-#define DEC_ROUND   ONE_TABLE
+#  define DEC_ROUND   ONE_TABLE
 #else
-#define DEC_ROUND   NO_TABLES
+#  define DEC_ROUND   NO_TABLES
 #endif
 
-#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)       /* set tables for the last decryption round */
-#define LAST_DEC_ROUND  FOUR_TABLES
+#if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)   /* set tables for the last decryption round */
+#  define LAST_DEC_ROUND  FOUR_TABLES
 #elif 0
-#define LAST_DEC_ROUND  ONE_TABLE
+#  define LAST_DEC_ROUND  ONE_TABLE
 #else
-#define LAST_DEC_ROUND  NO_TABLES
+#  define LAST_DEC_ROUND  NO_TABLES
 #endif
 
 /*  The decryption key schedule can be speeded up with tables in the same
     defines to set this requirement.
 */
 #if !defined(CONFIG_SMALL) || defined(CONFIG_SMALL_NO_CRYPTO)
-#define KEY_SCHED   FOUR_TABLES
+#  define KEY_SCHED   FOUR_TABLES
 #elif 0
-#define KEY_SCHED   ONE_TABLE
+#  define KEY_SCHED   ONE_TABLE
 #else
-#define KEY_SCHED   NO_TABLES
+#  define KEY_SCHED   NO_TABLES
 #endif
 
-/* END OF CONFIGURATION OPTIONS */
+/*  ---- END OF USER CONFIGURED OPTIONS ---- */
 
-#define NO_TABLES   0   /* DO NOT CHANGE */
-#define ONE_TABLE   1   /* DO NOT CHANGE */
-#define FOUR_TABLES 4   /* DO NOT CHANGE */
-#define NONE        0   /* DO NOT CHANGE */
-#define PARTIAL     1   /* DO NOT CHANGE */
-#define FULL        2   /* DO NOT CHANGE */
+/* VIA ACE support is only available for VC++ and GCC */
 
-#if defined(BLOCK_SIZE) && ((BLOCK_SIZE & 3) || BLOCK_SIZE < 16 || BLOCK_SIZE > 32)
-#error An illegal block size has been specified.
+#if !defined( _MSC_VER ) && !defined( __GNUC__ )
+#  if defined( ASSUME_VIA_ACE_PRESENT )
+#    undef ASSUME_VIA_ACE_PRESENT
+#  endif
+#  if defined( USE_VIA_ACE_IF_PRESENT )
+#    undef USE_VIA_ACE_IF_PRESENT
+#  endif
 #endif
 
-#if !defined(BLOCK_SIZE)
-#define RC_LENGTH    29
-#else
-#define RC_LENGTH   5 * BLOCK_SIZE / 4 - (BLOCK_SIZE == 16 ? 10 : 11)
+#if defined( ASSUME_VIA_ACE_PRESENT ) && !defined( USE_VIA_ACE_IF_PRESENT )
+#  define USE_VIA_ACE_IF_PRESENT
 #endif
 
-/* Disable at least some poor combinations of options */
-
-#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
-#undef  LAST_ENC_ROUND
-#define LAST_ENC_ROUND  NO_TABLES
-#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
-#undef  LAST_ENC_ROUND
-#define LAST_ENC_ROUND  ONE_TABLE
+/* define to reverse decryption key schedule    */
+#if 1 || defined( USE_VIA_ACE_IF_PRESENT ) && !defined ( AES_REV_DKS )
+#  define AES_REV_DKS
 #endif
 
-#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
-#undef  ENC_UNROLL
-#define ENC_UNROLL  NONE
+/* Intel AESNI uses a decryption key schedule in the encryption order */
+#if defined( USE_INTEL_AES_IF_PRESENT ) && defined ( AES_REV_DKS )
+#  undef AES_REV_DKS
 #endif
 
-#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
-#undef  LAST_DEC_ROUND
-#define LAST_DEC_ROUND  NO_TABLES
-#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
-#undef  LAST_DEC_ROUND
-#define LAST_DEC_ROUND  ONE_TABLE
-#endif
+/* Assembler support requires the use of platform byte order */
 
-#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
-#undef  DEC_UNROLL
-#define DEC_UNROLL  NONE
+#if ( defined( ASM_X86_V1C ) || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C ) ) \
+    && (ALGORITHM_BYTE_ORDER != PLATFORM_BYTE_ORDER)
+#  undef  ALGORITHM_BYTE_ORDER
+#  define ALGORITHM_BYTE_ORDER PLATFORM_BYTE_ORDER
 #endif
 
-#include "aes.h"
+/* In this implementation the columns of the state array are each held in
+   32-bit words. The state array can be held in various ways: in an array
+   of words, in a number of individual word variables or in a number of
+   processor registers. The following define maps a variable name x and
+   a column number c to the way the state array variable is to be held.
+   The first define below maps the state into an array x[c] whereas the
+   second form maps the state into a number of individual variables x0,
+   x1, etc.  Another form could map individual state columns to machine
+   register names.
+*/
 
- /*
-   upr(x,n):  rotates bytes within words by n positions, moving bytes to
-              higher index positions with wrap around into low positions
-   ups(x,n):  moves bytes by n positions to higher index positions in
-              words but without wrap around
-   bval(x,n): extracts a byte from a word
- */
-
-#if (INTERNAL_BYTE_ORDER == AES_LITTLE_ENDIAN)
-#if defined(_MSC_VER)
-#define upr(x,n)        _lrotl((x), 8 * (n))
+#if defined( ARRAYS )
+#  define s(x,c) x[c]
 #else
-#define upr(x,n)        (((x) << (8 * (n))) | ((x) >> (32 - 8 * (n))))
-#endif
-#define ups(x,n)        ((x) << (8 * (n)))
-#define bval(x,n)       ((uint8_t)((x) >> (8 * (n))))
-#define bytes2word(b0, b1, b2, b3)  \
-        (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
-#endif
-
-#if (INTERNAL_BYTE_ORDER == AES_BIG_ENDIAN)
-#define upr(x,n)        (((x) >> (8 * (n))) | ((x) << (32 - 8 * (n))))
-#define ups(x,n)        ((x) >> (8 * (n))))
-#define bval(x,n)       ((uint8_t)((x) >> (24 - 8 * (n))))
-#define bytes2word(b0, b1, b2, b3)  \
-        (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
+#  define s(x,c) x##c
 #endif
 
-#if defined(SAFE_IO)
-
-#define word_in(x)      bytes2word((x)[0], (x)[1], (x)[2], (x)[3])
-#define word_out(x,v)   { (x)[0] = bval(v,0); (x)[1] = bval(v,1);   \
-                          (x)[2] = bval(v,2); (x)[3] = bval(v,3);   }
-
-#elif (INTERNAL_BYTE_ORDER == PLATFORM_BYTE_ORDER)
-
-#define word_in(x)      *(uint32_t*)(x)
-#define word_out(x,v)   *(uint32_t*)(x) = (v)
+/*  This implementation provides subroutines for encryption, decryption
+    and for setting the three key lengths (separately) for encryption
+    and decryption. Since not all functions are needed, masks are set
+    up here to determine which will be implemented in C
+*/
 
+#if !defined( AES_ENCRYPT )
+#  define EFUNCS_IN_C   0
+#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
+    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
+#  define EFUNCS_IN_C   ENC_KEYING_IN_C
+#elif !defined( ASM_X86_V2 )
+#  define EFUNCS_IN_C   ( ENCRYPTION_IN_C | ENC_KEYING_IN_C )
 #else
-
-#if !defined(bswap_32)
-#if !defined(_MSC_VER)
-#define _lrotl(x,n)     (((x) <<  n) | ((x) >> (32 - n)))
-#endif
-#define bswap_32(x)     ((_lrotl((x),8) & 0x00ff00ff) | (_lrotl((x),24) & 0xff00ff00))
+#  define EFUNCS_IN_C   0
 #endif
 
-#define word_in(x)      bswap_32(*(uint32_t*)(x))
-#define word_out(x,v)   *(uint32_t*)(x) = bswap_32(v)
-
+#if !defined( AES_DECRYPT )
+#  define DFUNCS_IN_C   0
+#elif defined( ASSUME_VIA_ACE_PRESENT ) || defined( ASM_X86_V1C ) \
+    || defined( ASM_X86_V2C ) || defined( ASM_AMD64_C )
+#  define DFUNCS_IN_C   DEC_KEYING_IN_C
+#elif !defined( ASM_X86_V2 )
+#  define DFUNCS_IN_C   ( DECRYPTION_IN_C | DEC_KEYING_IN_C )
+#else
+#  define DFUNCS_IN_C   0
 #endif
 
-/* the finite field modular polynomial and elements */
-
-#define WPOLY   0x011b
-#define BPOLY     0x1b
-
-/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
-
-#define m1  0x80808080
-#define m2  0x7f7f7f7f
-#define FFmulX(x)  ((((x) & m2) << 1) ^ ((((x) & m1) >> 7) * BPOLY))
+#define FUNCS_IN_C  ( EFUNCS_IN_C | DFUNCS_IN_C )
 
-/* The following defines provide alternative definitions of FFmulX that might
-   give improved performance if a fast 32-bit multiply is not available. Note
-   that a temporary variable u needs to be defined where FFmulX is used.
+/* END OF CONFIGURATION OPTIONS */
 
-#define FFmulX(x) (u = (x) & m1, u |= (u >> 1), ((x) & m2) << 1) ^ ((u >> 3) | (u >> 6))
-#define m4  (0x01010101 * BPOLY)
-#define FFmulX(x) (u = (x) & m1, ((x) & m2) << 1) ^ ((u - (u >> 7)) & m4)
-*/
+#define RC_LENGTH   (5 * (AES_BLOCK_SIZE / 4 - 2))
 
-/* Work out which tables are needed for the different options   */
+/* Disable or report errors on some combinations of options */
 
-#ifdef  AES_ASM
-#ifdef  ENC_ROUND
-#undef  ENC_ROUND
-#endif
-#define ENC_ROUND   FOUR_TABLES
-#ifdef  LAST_ENC_ROUND
-#undef  LAST_ENC_ROUND
-#endif
-#define LAST_ENC_ROUND  FOUR_TABLES
-#ifdef  DEC_ROUND
-#undef  DEC_ROUND
-#endif
-#define DEC_ROUND   FOUR_TABLES
-#ifdef  LAST_DEC_ROUND
-#undef  LAST_DEC_ROUND
-#endif
-#define LAST_DEC_ROUND  FOUR_TABLES
-#ifdef  KEY_SCHED
-#undef  KEY_SCHED
-#define KEY_SCHED   FOUR_TABLES
-#endif
+#if ENC_ROUND == NO_TABLES && LAST_ENC_ROUND != NO_TABLES
+#  undef  LAST_ENC_ROUND
+#  define LAST_ENC_ROUND  NO_TABLES
+#elif ENC_ROUND == ONE_TABLE && LAST_ENC_ROUND == FOUR_TABLES
+#  undef  LAST_ENC_ROUND
+#  define LAST_ENC_ROUND  ONE_TABLE
 #endif
 
-#if defined(ENCRYPTION) || defined(AES_ASM)
-#if ENC_ROUND == ONE_TABLE
-#define FT1_SET
-#elif ENC_ROUND == FOUR_TABLES
-#define FT4_SET
-#else
-#define SBX_SET
-#endif
-#if LAST_ENC_ROUND == ONE_TABLE
-#define FL1_SET
-#elif LAST_ENC_ROUND == FOUR_TABLES
-#define FL4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
+#if ENC_ROUND == NO_TABLES && ENC_UNROLL != NONE
+#  undef  ENC_UNROLL
+#  define ENC_UNROLL  NONE
 #endif
 
-#if defined(DECRYPTION) || defined(AES_ASM)
-#if DEC_ROUND == ONE_TABLE
-#define IT1_SET
-#elif DEC_ROUND == FOUR_TABLES
-#define IT4_SET
-#else
-#define ISB_SET
-#endif
-#if LAST_DEC_ROUND == ONE_TABLE
-#define IL1_SET
-#elif LAST_DEC_ROUND == FOUR_TABLES
-#define IL4_SET
-#elif !defined(ISB_SET)
-#define ISB_SET
-#endif
+#if DEC_ROUND == NO_TABLES && LAST_DEC_ROUND != NO_TABLES
+#  undef  LAST_DEC_ROUND
+#  define LAST_DEC_ROUND  NO_TABLES
+#elif DEC_ROUND == ONE_TABLE && LAST_DEC_ROUND == FOUR_TABLES
+#  undef  LAST_DEC_ROUND
+#  define LAST_DEC_ROUND  ONE_TABLE
 #endif
 
-#if defined(ENCRYPTION_KEY_SCHEDULE) || defined(DECRYPTION_KEY_SCHEDULE)
-#if KEY_SCHED == ONE_TABLE
-#define LS1_SET
-#define IM1_SET
-#elif KEY_SCHED == FOUR_TABLES
-#define LS4_SET
-#define IM4_SET
-#elif !defined(SBX_SET)
-#define SBX_SET
-#endif
+#if DEC_ROUND == NO_TABLES && DEC_UNROLL != NONE
+#  undef  DEC_UNROLL
+#  define DEC_UNROLL  NONE
 #endif
 
-#ifdef  FIXED_TABLES
-#define prefx   extern const
+#if defined( bswap32 )
+#  define aes_sw32    bswap32
+#elif defined( bswap_32 )
+#  define aes_sw32    bswap_32
 #else
-#define prefx   extern
-extern uint8_t  tab_init;
-void gen_tabs(void);
+#  define brot(x,n)   (((uint32_t)(x) <<  n) | ((uint32_t)(x) >> (32 - n)))
+#  define aes_sw32(x) ((brot((x),8) & 0x00ff00ff) | (brot((x),24) & 0xff00ff00))
 #endif
 
-prefx uint32_t  rcon_tab[29];
+/*  upr(x,n):  rotates bytes within words by n positions, moving bytes to
+               higher index positions with wrap around into low positions
+    ups(x,n):  moves bytes by n positions to higher index positions in
+               words but without wrap around
+    bval(x,n): extracts a byte from a word
 
-#ifdef  SBX_SET
-prefx uint8_t s_box[256];
-#endif
+    WARNING:   The definitions given here are intended only for use with
+               unsigned variables and with shift counts that are compile
+               time constants
+*/
 
-#ifdef  ISB_SET
-prefx uint8_t inv_s_box[256];
+#if ( ALGORITHM_BYTE_ORDER == IS_LITTLE_ENDIAN )
+#  define upr(x,n)      (((uint32_t)(x) << (8 * (n))) | ((uint32_t)(x) >> (32 - 8 * (n))))
+#  define ups(x,n)      ((uint32_t) (x) << (8 * (n)))
+#  define bval(x,n)     to_byte((x) >> (8 * (n)))
+#  define bytes2word(b0, b1, b2, b3)  \
+        (((uint32_t)(b3) << 24) | ((uint32_t)(b2) << 16) | ((uint32_t)(b1) << 8) | (b0))
 #endif
 
-#ifdef  FT1_SET
-prefx uint32_t ft_tab[256];
+#if ( ALGORITHM_BYTE_ORDER == IS_BIG_ENDIAN )
+#  define upr(x,n)      (((uint32_t)(x) >> (8 * (n))) | ((uint32_t)(x) << (32 - 8 * (n))))
+#  define ups(x,n)      ((uint32_t) (x) >> (8 * (n)))
+#  define bval(x,n)     to_byte((x) >> (24 - 8 * (n)))
+#  define bytes2word(b0, b1, b2, b3)  \
+        (((uint32_t)(b0) << 24) | ((uint32_t)(b1) << 16) | ((uint32_t)(b2) << 8) | (b3))
 #endif
 
-#ifdef  FT4_SET
-prefx uint32_t ft_tab[4][256];
+#if defined( SAFE_IO )
+#  define word_in(x,c)    bytes2word(((const uint8_t*)(x)+4*c)[0], ((const uint8_t*)(x)+4*c)[1], \
+                                   ((const uint8_t*)(x)+4*c)[2], ((const uint8_t*)(x)+4*c)[3])
+#  define word_out(x,c,v) { ((uint8_t*)(x)+4*c)[0] = bval(v,0); ((uint8_t*)(x)+4*c)[1] = bval(v,1); \
+                          ((uint8_t*)(x)+4*c)[2] = bval(v,2); ((uint8_t*)(x)+4*c)[3] = bval(v,3); }
+#elif ( ALGORITHM_BYTE_ORDER == PLATFORM_BYTE_ORDER )
+#  define word_in(x,c)    (*((uint32_t*)(x)+(c)))
+#  define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = (v))
+#else
+#  define word_in(x,c)    aes_sw32(*((uint32_t*)(x)+(c)))
+#  define word_out(x,c,v) (*((uint32_t*)(x)+(c)) = aes_sw32(v))
 #endif
 
-#ifdef  FL1_SET
-prefx uint32_t fl_tab[256];
-#endif
+/* the finite field modular polynomial and elements */
 
-#ifdef  FL4_SET
-prefx uint32_t fl_tab[4][256];
-#endif
+#define WPOLY   0x011b
+#define BPOLY     0x1b
 
-#ifdef  IT1_SET
-prefx uint32_t it_tab[256];
-#endif
+/* multiply four bytes in GF(2^8) by 'x' {02} in parallel */
 
-#ifdef  IT4_SET
-prefx uint32_t it_tab[4][256];
-#endif
+#define gf_c1  0x80808080
+#define gf_c2  0x7f7f7f7f
+#define gf_mulx(x)  ((((x) & gf_c2) << 1) ^ ((((x) & gf_c1) >> 7) * BPOLY))
 
-#ifdef  IL1_SET
-prefx uint32_t il_tab[256];
-#endif
+/* The following defines provide alternative definitions of gf_mulx that might
+   give improved performance if a fast 32-bit multiply is not available. Note
+   that a temporary variable u needs to be defined where gf_mulx is used.
 
-#ifdef  IL4_SET
-prefx uint32_t il_tab[4][256];
-#endif
+#define gf_mulx(x) (u = (x) & gf_c1, u |= (u >> 1), ((x) & gf_c2) << 1) ^ ((u >> 3) | (u >> 6))
+#define gf_c4  (0x01010101 * BPOLY)
+#define gf_mulx(x) (u = (x) & gf_c1, ((x) & gf_c2) << 1) ^ ((u - (u >> 7)) & gf_c4)
+*/
 
-#ifdef  LS1_SET
-#ifdef  FL1_SET
-#undef  LS1_SET
-#else
-prefx uint32_t ls_tab[256];
-#endif
-#endif
+/* Work out which tables are needed for the different options   */
 
-#ifdef  LS4_SET
-#ifdef  FL4_SET
-#undef  LS4_SET
-#else
-prefx uint32_t ls_tab[4][256];
-#endif
+#if defined( ASM_X86_V1C )
+#  if defined( ENC_ROUND )
+#    undef  ENC_ROUND
+#  endif
+#  define ENC_ROUND   FOUR_TABLES
+#  if defined( LAST_ENC_ROUND )
+#    undef  LAST_ENC_ROUND
+#  endif
+#  define LAST_ENC_ROUND  FOUR_TABLES
+#  if defined( DEC_ROUND )
+#    undef  DEC_ROUND
+#  endif
+#  define DEC_ROUND   FOUR_TABLES
+#  if defined( LAST_DEC_ROUND )
+#    undef  LAST_DEC_ROUND
+#  endif
+#  define LAST_DEC_ROUND  FOUR_TABLES
+#  if defined( KEY_SCHED )
+#    undef  KEY_SCHED
+#    define KEY_SCHED   FOUR_TABLES
+#  endif
 #endif
 
-#ifdef  IM1_SET
-prefx uint32_t im_tab[256];
+#if ( FUNCS_IN_C & ENCRYPTION_IN_C ) || defined( ASM_X86_V1C )
+#  if ENC_ROUND == ONE_TABLE
+#    define FT1_SET
+#  elif ENC_ROUND == FOUR_TABLES
+#    define FT4_SET
+#  else
+#    define SBX_SET
+#  endif
+#  if LAST_ENC_ROUND == ONE_TABLE
+#    define FL1_SET
+#  elif LAST_ENC_ROUND == FOUR_TABLES
+#    define FL4_SET
+#  elif !defined( SBX_SET )
+#    define SBX_SET
+#  endif
 #endif
 
-#ifdef  IM4_SET
-prefx uint32_t im_tab[4][256];
+#if ( FUNCS_IN_C & DECRYPTION_IN_C ) || defined( ASM_X86_V1C )
+#  if DEC_ROUND == ONE_TABLE
+#    define IT1_SET
+#  elif DEC_ROUND == FOUR_TABLES
+#    define IT4_SET
+#  else
+#    define ISB_SET
+#  endif
+#  if LAST_DEC_ROUND == ONE_TABLE
+#    define IL1_SET
+#  elif LAST_DEC_ROUND == FOUR_TABLES
+#    define IL4_SET
+#  elif !defined(ISB_SET)
+#    define ISB_SET
+#  endif
 #endif
 
-/* Set the number of columns in nc.  Note that it is important  */
-/* that nc is a constant which is known at compile time if the  */
-/* highest speed version of the code is needed                  */
-
-#if defined(BLOCK_SIZE)
-#define nc  (BLOCK_SIZE >> 2)
-#else
-#define nc  (cx->n_blk >> 2)
+#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
+#  if ((FUNCS_IN_C & ENC_KEYING_IN_C) || (FUNCS_IN_C & DEC_KEYING_IN_C))
+#    if KEY_SCHED == ONE_TABLE
+#      if !defined( FL1_SET )  && !defined( FL4_SET )
+#        define LS1_SET
+#      endif
+#    elif KEY_SCHED == FOUR_TABLES
+#      if !defined( FL4_SET )
+#        define LS4_SET
+#      endif
+#    elif !defined( SBX_SET )
+#      define SBX_SET
+#    endif
+#  endif
+#  if (FUNCS_IN_C & DEC_KEYING_IN_C)
+#    if KEY_SCHED == ONE_TABLE
+#      define IM1_SET
+#    elif KEY_SCHED == FOUR_TABLES
+#      define IM4_SET
+#    elif !defined( SBX_SET )
+#      define SBX_SET
+#    endif
+#  endif
 #endif
 
-/* generic definitions of Rijndael macros that use of tables    */
+/* generic definitions of Rijndael macros that use tables    */
 
 #define no_table(x,box,vf,rf,c) bytes2word( \
     box[bval(vf(x,0,c),rf(0,c))], \
@@ -808,45 +739,48 @@ prefx uint32_t im_tab[4][256];
 
 #define vf1(x,r,c)  (x)
 #define rf1(r,c)    (r)
-#define rf2(r,c)    ((r-c)&3)
+#define rf2(r,c)    ((8+r-c)&3)
 
 /* perform forward and inverse column mix operation on four bytes in long word x in */
 /* parallel. NOTE: x must be a simple variable, NOT an expression in these macros.  */
 
-#define dec_fmvars
-#if defined(FM4_SET)    /* not currently used */
-#define fwd_mcol(x)     four_tables(x,fm_tab,vf1,rf1,0)
-#elif defined(FM1_SET)  /* not currently used */
-#define fwd_mcol(x)     one_table(x,upr,fm_tab,vf1,rf1,0)
+#if !(defined( REDUCE_CODE_SIZE ) && (defined( ASM_X86_V2 ) || defined( ASM_X86_V2C )))
+
+#if defined( FM4_SET )      /* not currently used */
+#  define fwd_mcol(x)       four_tables(x,t_use(f,m),vf1,rf1,0)
+#elif defined( FM1_SET )    /* not currently used */
+#  define fwd_mcol(x)       one_table(x,upr,t_use(f,m),vf1,rf1,0)
 #else
-#undef  dec_fmvars
-#define dec_fmvars      uint32_t f1, f2;
-#define fwd_mcol(x)     (f1 = (x), f2 = FFmulX(f1), f2 ^ upr(f1 ^ f2, 3) ^ upr(f1, 2) ^ upr(f1, 1))
+#  define dec_fmvars        uint32_t g2
+#  define fwd_mcol(x)       (g2 = gf_mulx(x), g2 ^ upr((x) ^ g2, 3) ^ upr((x), 2) ^ upr((x), 1))
 #endif
 
-#define dec_imvars
-#if defined(IM4_SET)
-#define inv_mcol(x)     four_tables(x,im_tab,vf1,rf1,0)
-#elif defined(IM1_SET)
-#define inv_mcol(x)     one_table(x,upr,im_tab,vf1,rf1,0)
+#if defined( IM4_SET )
+#  define inv_mcol(x)       four_tables(x,t_use(i,m),vf1,rf1,0)
+#elif defined( IM1_SET )
+#  define inv_mcol(x)       one_table(x,upr,t_use(i,m),vf1,rf1,0)
 #else
-#undef  dec_imvars
-#define dec_imvars      uint32_t    f2, f4, f8, f9;
-#define inv_mcol(x) \
-    (f9 = (x), f2 = FFmulX(f9), f4 = FFmulX(f2), f8 = FFmulX(f4), f9 ^= f8, \
-    f2 ^= f4 ^ f8 ^ upr(f2 ^ f9,3) ^ upr(f4 ^ f9,2) ^ upr(f9,1))
-#endif
-
-#if defined(FL4_SET)
-#define ls_box(x,c)     four_tables(x,fl_tab,vf1,rf2,c)
-#elif   defined(LS4_SET)
-#define ls_box(x,c)     four_tables(x,ls_tab,vf1,rf2,c)
-#elif defined(FL1_SET)
-#define ls_box(x,c)     one_table(x,upr,fl_tab,vf1,rf2,c)
-#elif defined(LS1_SET)
-#define ls_box(x,c)     one_table(x,upr,ls_tab,vf1,rf2,c)
+#  define dec_imvars        uint32_t g2, g4, g9
+#  define inv_mcol(x)       (g2 = gf_mulx(x), g4 = gf_mulx(g2), g9 = (x) ^ gf_mulx(g4), g4 ^= g9, \
+                            (x) ^ g2 ^ g4 ^ upr(g2 ^ g9, 3) ^ upr(g4, 2) ^ upr(g9, 1))
+#endif
+
+#if defined( FL4_SET )
+#  define ls_box(x,c)       four_tables(x,t_use(f,l),vf1,rf2,c)
+#elif defined( LS4_SET )
+#  define ls_box(x,c)       four_tables(x,t_use(l,s),vf1,rf2,c)
+#elif defined( FL1_SET )
+#  define ls_box(x,c)       one_table(x,upr,t_use(f,l),vf1,rf2,c)
+#elif defined( LS1_SET )
+#  define ls_box(x,c)       one_table(x,upr,t_use(l,s),vf1,rf2,c)
 #else
-#define ls_box(x,c)     no_table(x,s_box,vf1,rf2,c)
+#  define ls_box(x,c)       no_table(x,t_use(s,box),vf1,rf2,c)
+#endif
+
+#endif
+
+#if defined( ASM_X86_V1C ) && defined( AES_DECRYPT ) && !defined( ISB_SET )
+#  define ISB_SET
 #endif
 
 #endif
diff --git a/src/lib/crypto/builtin/aes/aessrc.url b/src/lib/crypto/builtin/aes/aessrc.url
deleted file mode 100644 (file)
index 874dd3d..0000000
+++ /dev/null
@@ -1 +0,0 @@
-https://github.com/BrianGladman/AES
index ef182d641c0df1ed8f7cd98d0ecf392438fcf6e2..3d48edf3e1c25a78d2492adec4c757c2328c6175 100644 (file)
@@ -1,52 +1,31 @@
 /*
- * Copyright (c) 2001, Dr Brian Gladman <brg@gladman.uk.net>, Worcester, UK.
- * All rights reserved.
- *
- * LICENSE TERMS
- *
- * The free distribution and use of this software in both source and binary
- * form is allowed (with or without changes) provided that:
- *
- *   1. distributions of this source code include the above copyright
- *      notice, this list of conditions and the following disclaimer;
- *
- *   2. distributions in binary form include the above copyright
- *      notice, this list of conditions and the following disclaimer
- *      in the documentation and/or other associated materials;
- *
- *   3. the copyright holder's name is not used to endorse products
- *      built using this software without specific written permission.
- *
- * DISCLAIMER
- *
- * This software is provided 'as is' with no explcit or implied warranties
- * in respect of any properties, including, but not limited to, correctness
- * and fitness for purpose.
- */
-
-/* Issue Date: 07/02/2002 */
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
 
-#include "aesopt.h"
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
 
-#if defined(FIXED_TABLES) || !defined(FF_TABLES)
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
 
-/*  finite field arithmetic operations */
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
 
-#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))
-#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
-#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
-                        ^ (((x>>5) & 4) * WPOLY))
-#define f3(x)   (f2(x) ^ x)
-#define f9(x)   (f8(x) ^ x)
-#define fb(x)   (f8(x) ^ f2(x) ^ x)
-#define fd(x)   (f8(x) ^ f4(x) ^ x)
-#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 20/12/2007
+*/
 
-#endif
+#define DO_TABLES
+
+#include "aes.h"
+#include "aesopt.h"
 
-#if defined(FIXED_TABLES)
+#if defined(STATIC_TABLES)
 
-#define sb_data(w) \
+#define sb_data(w) {\
     w(0x63), w(0x7c), w(0x77), w(0x7b), w(0xf2), w(0x6b), w(0x6f), w(0xc5),\
     w(0x30), w(0x01), w(0x67), w(0x2b), w(0xfe), w(0xd7), w(0xab), w(0x76),\
     w(0xca), w(0x82), w(0xc9), w(0x7d), w(0xfa), w(0x59), w(0x47), w(0xf0),\
@@ -78,9 +57,9 @@
     w(0xe1), w(0xf8), w(0x98), w(0x11), w(0x69), w(0xd9), w(0x8e), w(0x94),\
     w(0x9b), w(0x1e), w(0x87), w(0xe9), w(0xce), w(0x55), w(0x28), w(0xdf),\
     w(0x8c), w(0xa1), w(0x89), w(0x0d), w(0xbf), w(0xe6), w(0x42), w(0x68),\
-    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16)
+    w(0x41), w(0x99), w(0x2d), w(0x0f), w(0xb0), w(0x54), w(0xbb), w(0x16) }
 
-#define isb_data(w) \
+#define isb_data(w) {\
     w(0x52), w(0x09), w(0x6a), w(0xd5), w(0x30), w(0x36), w(0xa5), w(0x38),\
     w(0xbf), w(0x40), w(0xa3), w(0x9e), w(0x81), w(0xf3), w(0xd7), w(0xfb),\
     w(0x7c), w(0xe3), w(0x39), w(0x82), w(0x9b), w(0x2f), w(0xff), w(0x87),\
     w(0xa0), w(0xe0), w(0x3b), w(0x4d), w(0xae), w(0x2a), w(0xf5), w(0xb0),\
     w(0xc8), w(0xeb), w(0xbb), w(0x3c), w(0x83), w(0x53), w(0x99), w(0x61),\
     w(0x17), w(0x2b), w(0x04), w(0x7e), w(0xba), w(0x77), w(0xd6), w(0x26),\
-    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d),
+    w(0xe1), w(0x69), w(0x14), w(0x63), w(0x55), w(0x21), w(0x0c), w(0x7d) }
 
-#define mm_data(w) \
+#define mm_data(w) {\
     w(0x00), w(0x01), w(0x02), w(0x03), w(0x04), w(0x05), w(0x06), w(0x07),\
     w(0x08), w(0x09), w(0x0a), w(0x0b), w(0x0c), w(0x0d), w(0x0e), w(0x0f),\
     w(0x10), w(0x11), w(0x12), w(0x13), w(0x14), w(0x15), w(0x16), w(0x17),\
     w(0xe0), w(0xe1), w(0xe2), w(0xe3), w(0xe4), w(0xe5), w(0xe6), w(0xe7),\
     w(0xe8), w(0xe9), w(0xea), w(0xeb), w(0xec), w(0xed), w(0xee), w(0xef),\
     w(0xf0), w(0xf1), w(0xf2), w(0xf3), w(0xf4), w(0xf5), w(0xf6), w(0xf7),\
-    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff)
+    w(0xf8), w(0xf9), w(0xfa), w(0xfb), w(0xfc), w(0xfd), w(0xfe), w(0xff) }
 
-#define h0(x)   (x)
+#define rc_data(w) {\
+    w(0x01), w(0x02), w(0x04), w(0x08), w(0x10),w(0x20), w(0x40), w(0x80),\
+    w(0x1b), w(0x36) }
 
-/*  These defines are used to ensure tables are generated in the
-    right format depending on the internal byte order required
-*/
+#define h0(x)   (x)
 
 #define w0(p)   bytes2word(p, 0, 0, 0)
 #define w1(p)   bytes2word(0, p, 0, 0)
 #define w2(p)   bytes2word(0, 0, p, 0)
 #define w3(p)   bytes2word(0, 0, 0, p)
 
-/*  Number of elements required in this table for different
-    block and key lengths is:
-
-    Rcon Table      key length (bytes)
-    Length          16  20  24  28  32
-                ---------------------
-    block     16 |  10   9   8   7   7
-    length    20 |  14  11  10   9   9
-    (bytes)   24 |  19  15  12  11  11
-              28 |  24  19  16  13  13
-              32 |  29  23  19  17  14
-
-    this table can be a table of bytes if the key schedule
-    code is adjusted accordingly
-*/
-
 #define u0(p)   bytes2word(f2(p), p, p, f3(p))
 #define u1(p)   bytes2word(f3(p), f2(p), p, p)
 #define u2(p)   bytes2word(p, f3(p), f2(p), p)
 #define v2(p)   bytes2word(fd(p), fb(p), fe(p), f9(p))
 #define v3(p)   bytes2word(f9(p), fd(p), fb(p), fe(p))
 
-const uint32_t rcon_tab[29] =
-{
-    w0(0x01), w0(0x02), w0(0x04), w0(0x08),
-    w0(0x10), w0(0x20), w0(0x40), w0(0x80),
-    w0(0x1b), w0(0x36), w0(0x6c), w0(0xd8),
-    w0(0xab), w0(0x4d), w0(0x9a), w0(0x2f),
-    w0(0x5e), w0(0xbc), w0(0x63), w0(0xc6),
-    w0(0x97), w0(0x35), w0(0x6a), w0(0xd4),
-    w0(0xb3), w0(0x7d), w0(0xfa), w0(0xef),
-    w0(0xc5)
-};
-
-#ifdef  SBX_SET
-const uint8_t s_box[256] = { sb_data(h0) };
-#endif
-#ifdef  ISB_SET
-const uint8_t inv_s_box[256] = { isb_data(h0) };
-#endif
-
-#ifdef  FT1_SET
-const uint32_t ft_tab[256] = { sb_data(u0) };
-#endif
-#ifdef  FT4_SET
-const uint32_t ft_tab[4][256] =
-    { {  sb_data(u0) }, {  sb_data(u1) }, {  sb_data(u2) }, {  sb_data(u3) } };
 #endif
 
-#ifdef  FL1_SET
-const uint32_t fl_tab[256] = { sb_data(w0) };
-#endif
-#ifdef  FL4_SET
-const uint32_t fl_tab[4][256] =
-    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
-#endif
+#if defined(STATIC_TABLES) || !defined(FF_TABLES)
 
-#ifdef  IT1_SET
-const uint32_t it_tab[256] = { isb_data(v0) };
-#endif
-#ifdef  IT4_SET
-const uint32_t it_tab[4][256] =
-    { { isb_data(v0) }, { isb_data(v1) }, { isb_data(v2) }, { isb_data(v3) } };
-#endif
+#define f2(x)   ((x<<1) ^ (((x>>7) & 1) * WPOLY))
+#define f4(x)   ((x<<2) ^ (((x>>6) & 1) * WPOLY) ^ (((x>>6) & 2) * WPOLY))
+#define f8(x)   ((x<<3) ^ (((x>>5) & 1) * WPOLY) ^ (((x>>5) & 2) * WPOLY) \
+                        ^ (((x>>5) & 4) * WPOLY))
+#define f3(x)   (f2(x) ^ x)
+#define f9(x)   (f8(x) ^ x)
+#define fb(x)   (f8(x) ^ f2(x) ^ x)
+#define fd(x)   (f8(x) ^ f4(x) ^ x)
+#define fe(x)   (f8(x) ^ f4(x) ^ f2(x))
 
-#ifdef  IL1_SET
-const uint32_t il_tab[256] = { isb_data(w0) };
-#endif
-#ifdef  IL4_SET
-const uint32_t il_tab[4][256] =
-    { { isb_data(w0) }, { isb_data(w1) }, { isb_data(w2) }, { isb_data(w3) } };
-#endif
+#else
 
-#ifdef  LS1_SET
-const uint32_t ls_tab[256] = { sb_data(w0) };
-#endif
-#ifdef  LS4_SET
-const uint32_t ls_tab[4][256] =
-    { {  sb_data(w0) }, {  sb_data(w1) }, {  sb_data(w2) }, {  sb_data(w3) } };
-#endif
+#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
+#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
+#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
+#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
+#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
+#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
 
-#ifdef  IM1_SET
-const uint32_t im_tab[256] = { mm_data(v0) };
-#endif
-#ifdef  IM4_SET
-const uint32_t im_tab[4][256] =
-    { {  mm_data(v0) }, {  mm_data(v1) }, {  mm_data(v2) }, {  mm_data(v3) } };
 #endif
 
-#else   /* dynamic table generation */
-
-uint8_t tab_init = 0;
-
-#define const
-
-uint32_t  rcon_tab[RC_LENGTH];
+#include "aestab.h"
 
-#ifdef  SBX_SET
-uint8_t s_box[256];
-#endif
-#ifdef  ISB_SET
-uint8_t inv_s_box[256];
+#if defined(__cplusplus)
+extern "C"
+{
 #endif
 
-#ifdef  FT1_SET
-uint32_t ft_tab[256];
-#endif
-#ifdef  FT4_SET
-uint32_t ft_tab[4][256];
-#endif
+#if defined(STATIC_TABLES)
 
-#ifdef  FL1_SET
-uint32_t fl_tab[256];
-#endif
-#ifdef  FL4_SET
-uint32_t fl_tab[4][256];
-#endif
+/* implemented in case of wrong call for fixed tables */
 
-#ifdef  IT1_SET
-uint32_t it_tab[256];
-#endif
-#ifdef  IT4_SET
-uint32_t it_tab[4][256];
-#endif
+AES_RETURN aes_init(void)
+{
+    return EXIT_SUCCESS;
+}
 
-#ifdef  IL1_SET
-uint32_t il_tab[256];
-#endif
-#ifdef  IL4_SET
-uint32_t il_tab[4][256];
-#endif
+#else   /*  Generate the tables for the dynamic table option */
 
-#ifdef  LS1_SET
-uint32_t ls_tab[256];
-#endif
-#ifdef  LS4_SET
-uint32_t ls_tab[4][256];
-#endif
-
-#ifdef  IM1_SET
-uint32_t im_tab[256];
-#endif
-#ifdef  IM4_SET
-uint32_t im_tab[4][256];
-#endif
+#if defined(FF_TABLES)
 
-#if !defined(FF_TABLES)
+#define gf_inv(x)   ((x) ? pow[ 255 - log[x]] : 0)
 
-/*  Generate the tables for the dynamic table option
+#else
 
-    It will generally be sensible to use tables to compute finite
+/*  It will generally be sensible to use tables to compute finite
     field multiplies and inverses but where memory is scarse this
     code might sometimes be better. But it only has effect during
     initialisation so its pretty unimportant in overall terms.
@@ -334,58 +218,64 @@ static uint8_t hibit(const uint32_t x)
 
 /* return the inverse of the finite field element x */
 
-static uint8_t fi(const uint8_t x)
+static uint8_t gf_inv(const uint8_t x)
 {   uint8_t p1 = x, p2 = BPOLY, n1 = hibit(x), n2 = 0x80, v1 = 1, v2 = 0;
 
-    if(x < 2) return x;
+    if(x < 2)
+        return x;
 
-    for(;;)
+    for( ; ; )
     {
-        if(!n1) return v1;
-
-        while(n2 >= n1)
-        {
-            n2 /= n1; p2 ^= p1 * n2; v2 ^= v1 * n2; n2 = hibit(p2);
-        }
-
-        if(!n2) return v2;
-
-        while(n1 >= n2)
-        {
-            n1 /= n2; p1 ^= p2 * n1; v1 ^= v2 * n1; n1 = hibit(p1);
-        }
+        if(n1)
+            while(n2 >= n1)             /* divide polynomial p2 by p1    */
+            {
+                n2 /= n1;               /* shift smaller polynomial left */
+                p2 ^= (p1 * n2) & 0xff; /* and remove from larger one    */
+                v2 ^= v1 * n2;          /* shift accumulated value and   */
+                n2 = hibit(p2);         /* add into result               */
+            }
+        else
+            return v1;
+
+        if(n2)                          /* repeat with values swapped    */
+            while(n1 >= n2)
+            {
+                n1 /= n2;
+                p1 ^= p2 * n1;
+                v1 ^= v2 * n1;
+                n1 = hibit(p1);
+            }
+        else
+            return v2;
     }
 }
 
-#else
-
-/* define the finite field multiplies required for Rijndael */
-
-#define f2(x) ((x) ? pow[log[x] + 0x19] : 0)
-#define f3(x) ((x) ? pow[log[x] + 0x01] : 0)
-#define f9(x) ((x) ? pow[log[x] + 0xc7] : 0)
-#define fb(x) ((x) ? pow[log[x] + 0x68] : 0)
-#define fd(x) ((x) ? pow[log[x] + 0xee] : 0)
-#define fe(x) ((x) ? pow[log[x] + 0xdf] : 0)
-#define fi(x) ((x) ?   pow[255 - log[x]]: 0)
-
 #endif
 
 /* The forward and inverse affine transformations used in the S-box */
+uint8_t fwd_affine(const uint8_t x)
+{   uint32_t w = x;
+    w ^= (w << 1) ^ (w << 2) ^ (w << 3) ^ (w << 4);
+    return 0x63 ^ ((w ^ (w >> 8)) & 0xff);
+}
 
-#define fwd_affine(x) \
-    (w = (uint32_t)x, w ^= (w<<1)^(w<<2)^(w<<3)^(w<<4), 0x63^(uint8_t)(w^(w>>8)))
+uint8_t inv_affine(const uint8_t x)
+{   uint32_t w = x;
+    w = (w << 1) ^ (w << 3) ^ (w << 6);
+    return 0x05 ^ ((w ^ (w >> 8)) & 0xff);
+}
 
-#define inv_affine(x) \
-    (w = (uint32_t)x, w = (w<<1)^(w<<3)^(w<<6), 0x05^(uint8_t)(w^(w>>8)))
+static int init = 0;
 
-void gen_tabs(void)
+AES_RETURN aes_init(void)
 {   uint32_t  i, w;
 
 #if defined(FF_TABLES)
 
     uint8_t  pow[512], log[256];
 
+    if(init)
+        return EXIT_SUCCESS;
     /*  log and power tables for GF(2^8) finite field with
         WPOLY as modular polynomial - the simplest primitive
         root is 0x03, used here to generate the tables
@@ -401,93 +291,128 @@ void gen_tabs(void)
     }
     while (w != 1);
 
+#else
+    if(init)
+        return EXIT_SUCCESS;
 #endif
 
     for(i = 0, w = 1; i < RC_LENGTH; ++i)
     {
-        rcon_tab[i] = bytes2word(w, 0, 0, 0);
+        t_set(r,c)[i] = bytes2word(w, 0, 0, 0);
         w = f2(w);
     }
 
     for(i = 0; i < 256; ++i)
     {   uint8_t    b;
 
-        b = fwd_affine(fi((uint8_t)i));
+        b = fwd_affine(gf_inv((uint8_t)i));
         w = bytes2word(f2(b), b, b, f3(b));
 
-#ifdef  SBX_SET
-        s_box[i] = b;
+#if defined( SBX_SET )
+        t_set(s,box)[i] = b;
 #endif
 
-#ifdef  FT1_SET                 /* tables for a normal encryption round */
-        ft_tab[i] = w;
+#if defined( FT1_SET )                 /* tables for a normal encryption round */
+        t_set(f,n)[i] = w;
 #endif
-#ifdef  FT4_SET
-        ft_tab[0][i] = w;
-        ft_tab[1][i] = upr(w,1);
-        ft_tab[2][i] = upr(w,2);
-        ft_tab[3][i] = upr(w,3);
+#if defined( FT4_SET )
+        t_set(f,n)[0][i] = w;
+        t_set(f,n)[1][i] = upr(w,1);
+        t_set(f,n)[2][i] = upr(w,2);
+        t_set(f,n)[3][i] = upr(w,3);
 #endif
         w = bytes2word(b, 0, 0, 0);
 
-#ifdef  FL1_SET                 /* tables for last encryption round (may also   */
-        fl_tab[i] = w;          /* be used in the key schedule)                 */
+#if defined( FL1_SET )            /* tables for last encryption round (may also   */
+        t_set(f,l)[i] = w;        /* be used in the key schedule)                 */
 #endif
-#ifdef  FL4_SET
-        fl_tab[0][i] = w;
-        fl_tab[1][i] = upr(w,1);
-        fl_tab[2][i] = upr(w,2);
-        fl_tab[3][i] = upr(w,3);
+#if defined( FL4_SET )
+        t_set(f,l)[0][i] = w;
+        t_set(f,l)[1][i] = upr(w,1);
+        t_set(f,l)[2][i] = upr(w,2);
+        t_set(f,l)[3][i] = upr(w,3);
 #endif
 
-#ifdef  LS1_SET                 /* table for key schedule if fl_tab above is    */
-        ls_tab[i] = w;          /* not of the required form                     */
+#if defined( LS1_SET )                 /* table for key schedule if t_set(f,l) above is*/
+        t_set(l,s)[i] = w;      /* not of the required form                     */
 #endif
-#ifdef  LS4_SET
-        ls_tab[0][i] = w;
-        ls_tab[1][i] = upr(w,1);
-        ls_tab[2][i] = upr(w,2);
-        ls_tab[3][i] = upr(w,3);
+#if defined( LS4_SET )
+        t_set(l,s)[0][i] = w;
+        t_set(l,s)[1][i] = upr(w,1);
+        t_set(l,s)[2][i] = upr(w,2);
+        t_set(l,s)[3][i] = upr(w,3);
 #endif
 
-        b = fi(inv_affine((uint8_t)i));
+        b = gf_inv(inv_affine((uint8_t)i));
         w = bytes2word(fe(b), f9(b), fd(b), fb(b));
 
-#ifdef  IM1_SET                 /* tables for the inverse mix column operation  */
-        im_tab[b] = w;
+#if defined( IM1_SET )                 /* tables for the inverse mix column operation  */
+        t_set(i,m)[b] = w;
 #endif
-#ifdef  IM4_SET
-        im_tab[0][b] = w;
-        im_tab[1][b] = upr(w,1);
-        im_tab[2][b] = upr(w,2);
-        im_tab[3][b] = upr(w,3);
+#if defined( IM4_SET )
+        t_set(i,m)[0][b] = w;
+        t_set(i,m)[1][b] = upr(w,1);
+        t_set(i,m)[2][b] = upr(w,2);
+        t_set(i,m)[3][b] = upr(w,3);
 #endif
 
-#ifdef  ISB_SET
-        inv_s_box[i] = b;
+#if defined( ISB_SET )
+        t_set(i,box)[i] = b;
 #endif
-#ifdef  IT1_SET                 /* tables for a normal decryption round */
-        it_tab[i] = w;
+#if defined( IT1_SET )                 /* tables for a normal decryption round */
+        t_set(i,n)[i] = w;
 #endif
-#ifdef  IT4_SET
-        it_tab[0][i] = w;
-        it_tab[1][i] = upr(w,1);
-        it_tab[2][i] = upr(w,2);
-        it_tab[3][i] = upr(w,3);
+#if defined( IT4_SET )
+        t_set(i,n)[0][i] = w;
+        t_set(i,n)[1][i] = upr(w,1);
+        t_set(i,n)[2][i] = upr(w,2);
+        t_set(i,n)[3][i] = upr(w,3);
 #endif
         w = bytes2word(b, 0, 0, 0);
-#ifdef  IL1_SET                 /* tables for last decryption round */
-        il_tab[i] = w;
+#if defined( IL1_SET )                 /* tables for last decryption round */
+        t_set(i,l)[i] = w;
 #endif
-#ifdef  IL4_SET
-        il_tab[0][i] = w;
-        il_tab[1][i] = upr(w,1);
-        il_tab[2][i] = upr(w,2);
-        il_tab[3][i] = upr(w,3);
+#if defined( IL4_SET )
+        t_set(i,l)[0][i] = w;
+        t_set(i,l)[1][i] = upr(w,1);
+        t_set(i,l)[2][i] = upr(w,2);
+        t_set(i,l)[3][i] = upr(w,3);
 #endif
     }
+    init = 1;
+    return EXIT_SUCCESS;
+}
+
+/* 
+   Automatic code initialisation (suggested by by Henrik S. Gaßmann)
+   based on code provided by Joe Lowe and placed in the public domain at:
+   http://stackoverflow.com/questions/1113409/attribute-constructor-equivalent-in-vc
+*/
+
+#ifdef _MSC_VER
+
+#pragma section(".CRT$XCU", read)
 
-    tab_init = 1;
+__declspec(allocate(".CRT$XCU")) void (__cdecl *aes_startup)(void) = aes_init;
+
+#elif defined(__GNUC__)
+
+static void aes_startup(void) __attribute__((constructor));
+
+static void aes_startup(void)
+{
+    aes_init();
 }
 
+#else
+
+#pragma message( "dynamic tables must be initialised manually on your system" )
+
 #endif
+
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
diff --git a/src/lib/crypto/builtin/aes/aestab.h b/src/lib/crypto/builtin/aes/aestab.h
new file mode 100644 (file)
index 0000000..8fe32d1
--- /dev/null
@@ -0,0 +1,173 @@
+/*
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
+
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
+
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
+
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 20/12/2007
+
+ This file contains the code for declaring the tables needed to implement
+ AES. The file aesopt.h is assumed to be included before this header file.
+ If there are no global variables, the definitions here can be used to put
+ the AES tables in a structure so that a pointer can then be added to the
+ AES context to pass them to the AES routines that need them.   If this
+ facility is used, the calling program has to ensure that this pointer is
+ managed appropriately.  In particular, the value of the t_dec(in,it) item
+ in the table structure must be set to zero in order to ensure that the
+ tables are initialised. In practice the three code sequences in aeskey.c
+ that control the calls to aes_init() and the aes_init() routine itself will
+ have to be changed for a specific implementation. If global variables are
+ available it will generally be preferable to use them with the precomputed
+ STATIC_TABLES option that uses static global tables.
+
+ The following defines can be used to control the way the tables
+ are defined, initialised and used in embedded environments that
+ require special features for these purposes
+
+    the 't_dec' construction is used to declare fixed table arrays
+    the 't_set' construction is used to set fixed table values
+    the 't_use' construction is used to access fixed table values
+
+    256 byte tables:
+
+        t_xxx(s,box)    => forward S box
+        t_xxx(i,box)    => inverse S box
+
+    256 32-bit word OR 4 x 256 32-bit word tables:
+
+        t_xxx(f,n)      => forward normal round
+        t_xxx(f,l)      => forward last round
+        t_xxx(i,n)      => inverse normal round
+        t_xxx(i,l)      => inverse last round
+        t_xxx(l,s)      => key schedule table
+        t_xxx(i,m)      => key schedule table
+
+    Other variables and tables:
+
+        t_xxx(r,c)      => the rcon table
+*/
+
+#if !defined( _AESTAB_H )
+#define _AESTAB_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#define t_dec(m,n) t_##m##n
+#define t_set(m,n) t_##m##n
+#define t_use(m,n) t_##m##n
+
+#if defined(STATIC_TABLES)
+#  if !defined( __GNUC__ ) && (defined( __MSDOS__ ) || defined( __WIN16__ ))
+/*   make tables far data to avoid using too much DGROUP space (PG) */
+#    define CONST const far
+#  else
+#    define CONST const
+#  endif
+#else
+#  define CONST
+#endif
+
+#if defined(DO_TABLES)
+#  define EXTERN
+#else
+#  define EXTERN extern
+#endif
+
+#if defined(_MSC_VER) && defined(TABLE_ALIGN)
+#define ALIGN __declspec(align(TABLE_ALIGN))
+#else
+#define ALIGN
+#endif
+
+#if defined( __WATCOMC__ ) && ( __WATCOMC__ >= 1100 )
+#  define XP_DIR __cdecl
+#else
+#  define XP_DIR
+#endif
+
+#if defined(DO_TABLES) && defined(STATIC_TABLES)
+#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]    =   b(e)
+#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256] = { b(e), b(f), b(g), b(h) }
+EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH] = rc_data(w0);
+#else
+#define d_1(t,n,b,e)       EXTERN ALIGN CONST XP_DIR t n[256]
+#define d_4(t,n,b,e,f,g,h) EXTERN ALIGN CONST XP_DIR t n[4][256]
+EXTERN ALIGN CONST uint32_t t_dec(r,c)[RC_LENGTH];
+#endif
+
+#if defined( SBX_SET )
+    d_1(uint8_t, t_dec(s,box), sb_data, h0);
+#endif
+#if defined( ISB_SET )
+    d_1(uint8_t, t_dec(i,box), isb_data, h0);
+#endif
+
+#if defined( FT1_SET )
+    d_1(uint32_t, t_dec(f,n), sb_data, u0);
+#endif
+#if defined( FT4_SET )
+    d_4(uint32_t, t_dec(f,n), sb_data, u0, u1, u2, u3);
+#endif
+
+#if defined( FL1_SET )
+    d_1(uint32_t, t_dec(f,l), sb_data, w0);
+#endif
+#if defined( FL4_SET )
+    d_4(uint32_t, t_dec(f,l), sb_data, w0, w1, w2, w3);
+#endif
+
+#if defined( IT1_SET )
+    d_1(uint32_t, t_dec(i,n), isb_data, v0);
+#endif
+#if defined( IT4_SET )
+    d_4(uint32_t, t_dec(i,n), isb_data, v0, v1, v2, v3);
+#endif
+
+#if defined( IL1_SET )
+    d_1(uint32_t, t_dec(i,l), isb_data, w0);
+#endif
+#if defined( IL4_SET )
+    d_4(uint32_t, t_dec(i,l), isb_data, w0, w1, w2, w3);
+#endif
+
+#if defined( LS1_SET )
+#if defined( FL1_SET )
+#undef  LS1_SET
+#else
+    d_1(uint32_t, t_dec(l,s), sb_data, w0);
+#endif
+#endif
+
+#if defined( LS4_SET )
+#if defined( FL4_SET )
+#undef  LS4_SET
+#else
+    d_4(uint32_t, t_dec(l,s), sb_data, w0, w1, w2, w3);
+#endif
+#endif
+
+#if defined( IM1_SET )
+    d_1(uint32_t, t_dec(i,m), mm_data, v0);
+#endif
+#if defined( IM4_SET )
+    d_4(uint32_t, t_dec(i,m), mm_data, v0, v1, v2, v3);
+#endif
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/brg_endian.h b/src/lib/crypto/builtin/aes/brg_endian.h
new file mode 100644 (file)
index 0000000..c0e32b7
--- /dev/null
@@ -0,0 +1,144 @@
+/*
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
+
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
+
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
+
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 10/09/2018
+*/
+
+#ifndef _BRG_ENDIAN_H
+#define _BRG_ENDIAN_H
+
+#define IS_BIG_ENDIAN      4321 /* byte 0 is most significant (mc68k) */
+#define IS_LITTLE_ENDIAN   1234 /* byte 0 is least significant (i386) */
+
+/* This is needed when using clang with MSVC to avoid including */
+/* endian.h and byteswap.h which are not present on Windows     */
+#if defined( _MSC_VER ) && defined( __clang__ )
+#  undef __GNUC__
+#endif
+
+/* Include files where endian defines and byteswap functions may reside */
+#if defined( __sun )
+#  include <sys/isa_defs.h>
+#elif defined( __FreeBSD__ ) || defined( __OpenBSD__ ) || defined( __NetBSD__ )
+#  include <sys/endian.h>
+#elif defined( BSD ) && ( BSD >= 199103 ) || defined( __APPLE__ ) || \
+      defined( __CYGWIN32__ ) || defined( __DJGPP__ ) || defined( __osf__ )
+#  include <machine/endian.h>
+#elif defined( __linux__ ) || defined( __GNUC__ ) || defined( __GNU_LIBRARY__ )
+#  if !defined( __MINGW32__ ) && !defined( _AIX )
+#    include <endian.h>
+#    if !defined( __BEOS__ )
+#      include <byteswap.h>
+#    endif
+#  endif
+#endif
+
+/* Now attempt to set the define for platform byte order using any  */
+/* of the four forms SYMBOL, _SYMBOL, __SYMBOL & __SYMBOL__, ...    */
+/* which seem to encompass most endian symbol definitions           */
+
+#if defined( __ORDER_BIG_ENDIAN__ ) && defined( __ORDER_LITTLE_ENDIAN__ )
+#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __ORDER_BIG_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __ORDER_LITTLE_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( BIG_ENDIAN ) && defined( LITTLE_ENDIAN )
+#  if defined( BYTE_ORDER ) && BYTE_ORDER == BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( BYTE_ORDER ) && BYTE_ORDER == LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( _BIG_ENDIAN ) && defined( _LITTLE_ENDIAN )
+#  if defined( _BYTE_ORDER ) && _BYTE_ORDER == _BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( _BYTE_ORDER ) && _BYTE_ORDER == _LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( _BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( _LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN ) && defined( __LITTLE_ENDIAN )
+#  if defined( __BYTE_ORDER ) && __BYTE_ORDER == __BIG_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER ) && __BYTE_ORDER == __LITTLE_ENDIAN
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+#if defined( __BIG_ENDIAN__ ) && defined( __LITTLE_ENDIAN__ )
+#  if defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __BIG_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#  elif defined( __BYTE_ORDER__ ) && __BYTE_ORDER__ == __LITTLE_ENDIAN__
+#    define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#  endif
+#elif defined( __BIG_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#elif defined( __LITTLE_ENDIAN__ )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#endif
+
+/*  if the platform byte order could not be determined, then try to */
+/*  set this define using common machine defines                    */
+#if !defined(PLATFORM_BYTE_ORDER)
+
+#if   defined( __alpha__ ) || defined( __alpha ) || defined( i386 )       || \
+      defined( __i386__ )  || defined( _M_I86 )  || defined( _M_IX86 )    || \
+      defined( __OS2__ )   || defined( sun386 )  || defined( __TURBOC__ ) || \
+      defined( vax )       || defined( vms )     || defined( VMS )        || \
+      defined( __VMS )     || defined( _M_X64 )
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+
+#elif defined( AMIGA )   || defined( applec )    || defined( __AS400__ )  || \
+      defined( _CRAY )   || defined( __hppa )    || defined( __hp9000 )   || \
+      defined( ibm370 )  || defined( mc68000 )   || defined( m68k )       || \
+      defined( __MRC__ ) || defined( __MVS__ )   || defined( __MWERKS__ ) || \
+      defined( sparc )   || defined( __sparc)    || defined( SYMANTEC_C ) || \
+      defined( __VOS__ ) || defined( __TIGCC__ ) || defined( __TANDEM )   || \
+      defined( THINK_C ) || defined( __VMCMS__ ) || defined( _AIX )
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_LITTLE_ENDIAN
+#elif 0     /* **** EDIT HERE IF NECESSARY **** */
+#  define PLATFORM_BYTE_ORDER IS_BIG_ENDIAN
+#else
+#  error Please edit lines 126 or 128 in brg_endian.h to set the platform byte order
+#endif
+
+#endif
+
+#endif
diff --git a/src/lib/crypto/builtin/aes/brg_types.h b/src/lib/crypto/builtin/aes/brg_types.h
new file mode 100644 (file)
index 0000000..ce3a1e7
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+---------------------------------------------------------------------------
+Copyright (c) 1998-2013, Brian Gladman, Worcester, UK. All rights reserved.
+
+The redistribution and use of this software (with or without changes)
+is allowed without the payment of fees or royalties provided that:
+
+  source code distributions include the above copyright notice, this
+  list of conditions and the following disclaimer;
+
+  binary distributions include the above copyright notice, this list
+  of conditions and the following disclaimer in their documentation.
+
+This software is provided 'as is' with no explicit or implied warranties
+in respect of its operation, including, but not limited to, correctness
+and fitness for purpose.
+---------------------------------------------------------------------------
+Issue Date: 30/09/2017
+*/
+
+#ifndef _BRG_TYPES_H
+#define _BRG_TYPES_H
+
+#if defined(__cplusplus)
+extern "C" {
+#endif
+
+#include <limits.h>
+#include <stdint.h>
+
+#if defined( _MSC_VER ) && ( _MSC_VER >= 1300 )
+#  include <stddef.h>
+#  define ptrint_t intptr_t
+#elif defined( __ECOS__ )
+#  define intptr_t unsigned int
+#  define ptrint_t intptr_t
+#elif defined( __GNUC__ ) && ( __GNUC__ >= 3 ) && !(defined( __HAIKU__ ) || defined( __VxWorks__ ))
+#  define ptrint_t intptr_t
+#else
+#  define ptrint_t int
+#endif
+
+/* define unsigned 8-bit type if not available in stdint.h */
+#if !defined(UINT8_MAX)
+  typedef unsigned char uint8_t;
+#endif
+
+/* define unsigned 16-bit type if not available in stdint.h */
+#if !defined(UINT16_MAX)
+  typedef unsigned short uint16_t;
+#endif
+
+/* define unsigned 32-bit type if not available in stdint.h and define the
+   macro li_32(h) which converts a sequence of eight hexadecimal characters
+   into a 32 bit constant 
+*/
+#if defined(UINT_MAX) && UINT_MAX == 4294967295u
+#  define li_32(h) 0x##h##u
+#  if !defined(UINT32_MAX)
+     typedef unsigned int uint32_t;
+#  endif
+#elif defined(ULONG_MAX) && ULONG_MAX == 4294967295u
+#  define li_32(h) 0x##h##ul
+#  if !defined(UINT32_MAX)
+     typedef unsigned long uint32_t;
+#  endif
+#elif defined( _CRAY )
+#  error This code needs 32-bit data types, which Cray machines do not provide
+#else
+#  error Please define uint32_t as a 32-bit unsigned integer type in brg_types.h
+#endif
+
+/* define unsigned 64-bit type if not available in stdint.h and define the
+   macro li_64(h) which converts a sequence of eight hexadecimal characters
+   into a 64 bit constant 
+*/
+#if defined( __BORLANDC__ ) && !defined( __MSDOS__ )
+#  define li_64(h) 0x##h##ui64
+#  if !defined(UINT64_MAX)
+     typedef unsigned __int64 uint64_t;  
+#  endif
+#elif defined( _MSC_VER ) && ( _MSC_VER < 1300 )    /* 1300 == VC++ 7.0 */
+#  define li_64(h) 0x##h##ui64
+#  if !defined(UINT64_MAX)
+     typedef unsigned __int64 uint64_t;
+#  endif
+#elif defined( __sun ) && defined( ULONG_MAX ) && ULONG_MAX == 0xfffffffful
+#  define li_64(h) 0x##h##ull
+#  if !defined(UINT64_MAX)
+     typedef unsigned long long uint64_t;
+#  endif
+#elif defined( __MVS__ )
+#  define li_64(h) 0x##h##ull
+#  if !defined(UINT64_MAX)
+     typedef unsigned long long uint64_t;
+#  endif
+#elif defined( UINT_MAX ) && UINT_MAX > 4294967295u
+#  if UINT_MAX == 18446744073709551615u
+#    define li_64(h) 0x##h##u
+#    if !defined(UINT64_MAX)
+       typedef unsigned int uint64_t;
+#    endif
+#  endif
+#elif defined( ULONG_MAX ) && ULONG_MAX > 4294967295u
+#  if ULONG_MAX == 18446744073709551615ul
+#    define li_64(h) 0x##h##ul
+#    if !defined(UINT64_MAX) && !defined(_UINT64_T)
+       typedef unsigned long uint64_t;
+#    endif
+#  endif
+#elif defined( ULLONG_MAX ) && ULLONG_MAX > 4294967295u
+#  if ULLONG_MAX == 18446744073709551615ull
+#    define li_64(h) 0x##h##ull
+#    if !defined(UINT64_MAX) && !defined( __HAIKU__ )
+       typedef unsigned long long uint64_t;
+#    endif
+#  endif
+#elif defined( ULONG_LONG_MAX ) && ULONG_LONG_MAX > 4294967295u
+#  if ULONG_LONG_MAX == 18446744073709551615ull
+#    define li_64(h) 0x##h##ull
+#    if !defined(UINT64_MAX)
+       typedef unsigned long long uint64_t;
+#    endif
+#  endif
+#endif
+
+#if !defined( li_64 )
+#  if defined( NEED_UINT_64T )
+#    error Please define uint64_t as an unsigned 64 bit type in brg_types.h
+#  endif
+#endif
+
+#ifndef RETURN_VALUES
+#  define RETURN_VALUES
+#  if defined( DLL_EXPORT )
+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
+#      define VOID_RETURN    __declspec( dllexport ) void __stdcall
+#      define INT_RETURN     __declspec( dllexport ) int  __stdcall
+#    elif defined( __GNUC__ )
+#      define VOID_RETURN    __declspec( __dllexport__ ) void
+#      define INT_RETURN     __declspec( __dllexport__ ) int
+#    else
+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
+#    endif
+#  elif defined( DLL_IMPORT )
+#    if defined( _MSC_VER ) || defined ( __INTEL_COMPILER )
+#      define VOID_RETURN    __declspec( dllimport ) void __stdcall
+#      define INT_RETURN     __declspec( dllimport ) int  __stdcall
+#    elif defined( __GNUC__ )
+#      define VOID_RETURN    __declspec( __dllimport__ ) void
+#      define INT_RETURN     __declspec( __dllimport__ ) int
+#    else
+#      error Use of the DLL is only available on the Microsoft, Intel and GCC compilers
+#    endif
+#  elif defined( __WATCOMC__ )
+#    define VOID_RETURN  void __cdecl
+#    define INT_RETURN   int  __cdecl
+#  else
+#    define VOID_RETURN  void
+#    define INT_RETURN   int
+#  endif
+#endif
+
+/*     These defines are used to detect and set the memory alignment of pointers.
+    Note that offsets are in bytes.
+
+    ALIGN_OFFSET(x,n)                  return the positive or zero offset of 
+                                the memory addressed by the pointer 'x' 
+                                from an address that is aligned on an 
+                                'n' byte boundary ('n' is a power of 2)
+
+    ALIGN_FLOOR(x,n)                   return a pointer that points to memory
+                                that is aligned on an 'n' byte boundary 
+                                and is not higher than the memory address
+                                pointed to by 'x' ('n' is a power of 2)
+
+    ALIGN_CEIL(x,n)                            return a pointer that points to memory
+                                that is aligned on an 'n' byte boundary 
+                                and is not lower than the memory address
+                                pointed to by 'x' ('n' is a power of 2)
+*/
+
+#define ALIGN_OFFSET(x,n)      (((ptrint_t)(x)) & ((n) - 1))
+#define ALIGN_FLOOR(x,n)       ((uint8_t*)(x) - ( ((ptrint_t)(x)) & ((n) - 1)))
+#define ALIGN_CEIL(x,n)                ((uint8_t*)(x) + (-((ptrint_t)(x)) & ((n) - 1)))
+
+/*  These defines are used to declare buffers in a way that allows
+    faster operations on longer variables to be used.  In all these
+    defines 'size' must be a power of 2 and >= 8. NOTE that the 
+    buffer size is in bytes but the type length is in bits
+
+    UNIT_TYPEDEF(x,size)        declares a variable 'x' of length 
+                                'size' bits
+
+    BUFR_TYPEDEF(x,size,bsize)  declares a buffer 'x' of length 'bsize' 
+                                bytes defined as an array of variables
+                                each of 'size' bits (bsize must be a 
+                                multiple of size / 8)
+
+    UNIT_CAST(x,size)           casts a variable to a type of 
+                                length 'size' bits
+
+    UPTR_CAST(x,size)           casts a pointer to a pointer to a 
+                                variable of length 'size' bits
+*/
+
+#define UI_TYPE(size)               uint##size##_t
+#define UNIT_TYPEDEF(x,size)        typedef UI_TYPE(size) x
+#define BUFR_TYPEDEF(x,size,bsize)  typedef UI_TYPE(size) x[bsize / (size >> 3)]
+#define UNIT_CAST(x,size)           ((UI_TYPE(size) )(x))  
+#define UPTR_CAST(x,size)           ((UI_TYPE(size)*)(x))
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
index fcd5520cd7d358dc14a0706532157a2605d6afc4..5acef42be4b30c2ea51942f980578859274fc384 100644 (file)
@@ -2,8 +2,10 @@
 # Generated makefile dependencies follow.
 #
 aescrypt.so aescrypt.po $(OUTPRE)aescrypt.$(OBJEXT): \
-  $(BUILDTOP)/include/autoconf.h aes.h aescrypt.c aesopt.h
-aestab.so aestab.po $(OUTPRE)aestab.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-  aes.h aesopt.h aestab.c
-aeskey.so aeskey.po $(OUTPRE)aeskey.$(OBJEXT): $(BUILDTOP)/include/autoconf.h \
-  aes.h aeskey.c aesopt.h
+  aes.h aescrypt.c aesopt.h aestab.h brg_endian.h brg_types.h
+aestab.so aestab.po $(OUTPRE)aestab.$(OBJEXT): aes.h \
+  aesopt.h aestab.c aestab.h brg_endian.h brg_types.h
+aeskey.so aeskey.po $(OUTPRE)aeskey.$(OBJEXT): aes.h \
+  aeskey.c aesopt.h aestab.h brg_endian.h brg_types.h
+aes_ni.so aes_ni.po $(OUTPRE)aes_ni.$(OBJEXT): aes.h \
+  aes_ni.c aes_ni.h aesopt.h brg_endian.h brg_types.h
diff --git a/src/lib/crypto/builtin/aes/kresults.expected b/src/lib/crypto/builtin/aes/kresults.expected
new file mode 100644 (file)
index 0000000..443d5c4
--- /dev/null
@@ -0,0 +1,223 @@
+FIPS test:
+key:
+    00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
+input:
+    00 11 22 33 44 55 66 77 88 99 AA BB CC DD EE FF
+output:
+    69 C4 E0 D8 6A 7B 04 30 D8 CD B7 80 70 B4 C5 5A
+ok.
+
+ECB tests:
+key:
+    46 64 31 29 64 86 ED 9C D7 1F C2 07 25 48 20 A2
+test 0 - 32 bytes
+input:
+    C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13
+    94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+output:
+    1B 39 DA 37 40 D3 DF FE AC 89 D6 BB 4C 29 F1 0A
+    E1 43 64 CB 16 D3 FF CF E8 FA 6A 2C EC A2 69 34
+
+test 1 - 32 bytes
+input:
+    22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50
+    6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A 00
+output:
+    F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9 90
+    83 FE B6 7B 73 4F CE DB 8E 97 D4 06 96 11 B7 23
+
+test 2 - 32 bytes
+input:
+    E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E
+    94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B
+output:
+    25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50
+    A3 D1 6F E1 EF 7B 6D 2F 4F 93 48 90 02 0D F1 8A
+
+test 3 - 48 bytes
+input:
+    54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33
+    68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54
+    D7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+output:
+    D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0
+    86 D8 A3 C0 E5 6D BB 39 5F C0 CC 0A DA 8F 87 C6
+    14 C1 8E 34 7A A8 2F BB EA 53 F0 7A 64 53 5B 28
+
+test 4 - 48 bytes
+input:
+    39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1
+    03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B
+    72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39 00
+output:
+    AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E
+    B5 76 2B EE F3 A1 04 A1 E0 3F FE CA 17 7B 4C 91
+    53 2F B3 16 33 48 27 D6 49 62 E8 77 10 DC 46 E6
+
+test 5 - 48 bytes
+input:
+    E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB
+    1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4
+    09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A
+output:
+    1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D
+    FE 7A E7 E7 DF 7F 12 C6 5E 29 F9 A2 55 C0 93 F1
+    FF AC 97 44 E1 C0 C7 39 F8 7A 4B F8 ED 01 58 6B
+
+test 6 - 64 bytes
+input:
+    D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE
+    FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11
+    2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8
+    77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29
+output:
+    D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43
+    4D C5 13 1B B5 3E 8F 4E B4 75 FC A5 E5 47 94 7F
+    14 68 15 F7 6D F1 9E 12 B8 81 39 06 3C 3D F5 44
+    83 BE 19 E3 3E 68 15 A0 50 93 03 73 0C 99 52 C3
+
+CBC tests:
+initial vector:
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+test 0 - 32 bytes
+input:
+    C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13
+    94 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+output:
+    1B 39 DA 37 40 D3 DF FE AC 89 D6 BB 4C 29 F1 0A
+    D4 3C 74 F5 5B 8B 3E CF 67 F8 F7 00 03 27 8A 91
+
+test 1 - 32 bytes
+input:
+    22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50
+    6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A 00
+output:
+    F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9 90
+    54 03 C8 DF 5F 11 82 94 93 4E B3 4B F9 B5 39 D1
+
+test 2 - 32 bytes
+input:
+    E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E
+    94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B
+output:
+    25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50
+    D7 7C 5F B0 DA F7 80 2E 3F 3A 2E B7 5D F0 B3 23
+
+test 3 - 48 bytes
+input:
+    54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33
+    68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54
+    D7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+output:
+    D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0
+    88 D0 90 16 44 A7 38 01 63 5D BE 56 9E C3 78 7A
+    51 6F 31 69 BF 9C 75 AD A1 C6 66 A6 1B A2 38 0D
+
+test 4 - 48 bytes
+input:
+    39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1
+    03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B
+    72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39 00
+output:
+    AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E
+    F0 68 8B 66 32 FE 41 EF 11 51 1B 6E F0 C0 17 96
+    A1 BD F6 34 5D F3 BC 03 86 72 D0 C3 13 FE C3 95
+
+test 5 - 48 bytes
+input:
+    E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB
+    1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4
+    09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A
+output:
+    1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D
+    22 F4 2B 92 92 D4 D5 E7 EA 90 72 9F 03 31 10 1F
+    65 DE 01 93 8B 51 17 F8 32 6F 4B 05 AF 02 E2 3D
+
+test 6 - 64 bytes
+input:
+    D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE
+    FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11
+    2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8
+    77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29
+output:
+    D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43
+    F7 43 1B BF 3C 7D A0 21 1E 3D 3F 6A 4D 8A CE 08
+    37 9D EB CD 52 52 3B C5 76 02 7D 35 19 76 05 7D
+    76 22 5A 42 DF 73 CB 5D CE 88 C3 4C CE 92 00 E6
+
+CTS tests:
+initial vector:
+    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
+test 0 - 17 bytes
+input:
+    C4 A8 5A EB 0B 20 41 49 4F 8B F1 F8 CD 30 F1 13
+    94
+(did CBC mode for 0)
+output:
+    D4 3C 74 F5 5B 8B 3E CF 67 F8 F7 00 03 27 8A 91
+    1B
+
+test 1 - 31 bytes
+input:
+    22 3C F8 A8 29 95 80 49 57 87 6E 9F A7 11 63 50
+    6B 4E 5B 8C 8F A4 DB 1B 95 D3 E8 C5 C5 FB 5A
+(did CBC mode for 0)
+output:
+    54 03 C8 DF 5F 11 82 94 93 4E B3 4B F9 B5 39 D1
+    F3 B2 BB 53 D6 F4 A3 AE 9E EB B1 3D B2 F7 E9
+
+test 2 - 32 bytes
+input:
+    E7 37 52 90 60 E7 10 A9 3E 97 18 DD 3E 29 41 8E
+    94 8F E9 20 1F 8D FB 3A 22 CF 22 E8 94 1D 42 7B
+(did CBC mode for 0)
+output:
+    D7 7C 5F B0 DA F7 80 2E 3F 3A 2E B7 5D F0 B3 23
+    25 4F 90 96 01 9B 09 27 5E FF 95 69 E0 70 DC 50
+
+test 3 - 33 bytes
+input:
+    54 94 0B B4 7C 1B 5E BA B2 76 98 F1 9F D9 7F 33
+    68 69 54 87 F6 4F C1 19 1E E3 01 B2 00 43 2E 54
+    D7
+(did CBC mode for 16)
+output:
+    D3 7F 6D 39 57 32 A6 C5 A4 49 F4 4B C6 EE 0A E0
+    51 6F 31 69 BF 9C 75 AD A1 C6 66 A6 1B A2 38 0D
+    88
+
+test 4 - 47 bytes
+input:
+    39 09 53 55 67 0E 07 DD A6 F8 7C 7F 78 AF E7 E1
+    03 6F D7 53 30 F0 71 14 F1 24 14 34 52 69 0C 8B
+    72 5F E0 D9 6D E8 B6 13 E0 32 92 58 E1 7A 39
+(did CBC mode for 16)
+output:
+    AD 96 1C 40 05 54 CB 0E 37 32 AE 2C 64 DB EF 8E
+    A1 BD F6 34 5D F3 BC 03 86 72 D0 C3 13 FE C3 95
+    F0 68 8B 66 32 FE 41 EF 11 51 1B 6E F0 C0 17
+
+test 5 - 48 bytes
+input:
+    E5 E9 11 38 19 01 A9 2D F3 CD 42 27 1F AB 33 AB
+    1D 93 8B F6 00 73 AC 14 54 DE A6 AC BF 20 E6 A4
+    09 F7 DC 23 F8 86 50 EB 53 92 13 73 3D 46 1E 5A
+(did CBC mode for 16)
+output:
+    1A 03 F3 10 7A F0 62 07 D1 22 60 2B 9E 07 D0 8D
+    65 DE 01 93 8B 51 17 F8 32 6F 4B 05 AF 02 E2 3D
+    22 F4 2B 92 92 D4 D5 E7 EA 90 72 9F 03 31 10 1F
+
+test 6 - 64 bytes
+input:
+    D9 A9 50 DA 1D FC EE 71 DA 94 1D 9A B5 03 3E BE
+    FA 1B E1 F3 A1 32 DE F4 C4 F1 67 02 38 85 5C 11
+    2F AD EB 4C A9 D9 BD 84 6E DA 1E 23 DE 5C E1 D8
+    77 C3 CB 18 F5 AA 0D B9 9B 74 BB D3 FA 18 E5 29
+(did CBC mode for 32)
+output:
+    D0 18 22 59 85 05 AB 87 0D 9D D0 99 7B 15 CC 43
+    F7 43 1B BF 3C 7D A0 21 1E 3D 3F 6A 4D 8A CE 08
+    76 22 5A 42 DF 73 CB 5D CE 88 C3 4C CE 92 00 E6
+    37 9D EB CD 52 52 3B C5 76 02 7D 35 19 76 05 7D
+
index 2a5d8e39775d3984a94df248f9dee787cc9adf86..92c170202748a0a873835917e0d1e76c870ede22 100644 (file)
@@ -35,7 +35,8 @@
  * we've initialized each half.
  */
 struct aes_key_info_cache {
-    aes_ctx enc_ctx, dec_ctx;
+    aes_encrypt_ctx enc_ctx;
+    aes_decrypt_ctx dec_ctx;
     krb5_boolean aesni;
 };
 #define CACHE(X) ((struct aes_key_info_cache *)((X)->cache))
@@ -85,10 +86,10 @@ aesni_expand_enc_key(krb5_key key)
     struct aes_key_info_cache *cache = CACHE(key);
 
     if (key->keyblock.length == 16)
-        k5_iEncExpandKey128(key->keyblock.contents, cache->enc_ctx.k_sch);
+        k5_iEncExpandKey128(key->keyblock.contents, cache->enc_ctx.ks);
     else
-        k5_iEncExpandKey256(key->keyblock.contents, cache->enc_ctx.k_sch);
-    cache->enc_ctx.n_rnd = 1;
+        k5_iEncExpandKey256(key->keyblock.contents, cache->enc_ctx.ks);
+    cache->enc_ctx.inf.l = 1;
 }
 
 static void
@@ -97,10 +98,10 @@ aesni_expand_dec_key(krb5_key key)
     struct aes_key_info_cache *cache = CACHE(key);
 
     if (key->keyblock.length == 16)
-        k5_iDecExpandKey128(key->keyblock.contents, cache->dec_ctx.k_sch);
+        k5_iDecExpandKey128(key->keyblock.contents, cache->dec_ctx.ks);
     else
-        k5_iDecExpandKey256(key->keyblock.contents, cache->dec_ctx.k_sch);
-    cache->dec_ctx.n_rnd = 1;
+        k5_iDecExpandKey256(key->keyblock.contents, cache->dec_ctx.ks);
+    cache->dec_ctx.inf.l = 1;
 }
 
 static inline void
@@ -111,7 +112,7 @@ aesni_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
 
     d.in_block = data;
     d.out_block = data;
-    d.expanded_key = cache->enc_ctx.k_sch;
+    d.expanded_key = cache->enc_ctx.ks;
     d.iv = iv;
     d.num_blocks = nblocks;
     if (key->keyblock.length == 16)
@@ -128,7 +129,7 @@ aesni_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
 
     d.in_block = data;
     d.out_block = data;
-    d.expanded_key = cache->dec_ctx.k_sch;
+    d.expanded_key = cache->dec_ctx.ks;
     d.iv = iv;
     d.num_blocks = nblocks;
     if (key->keyblock.length == 16)
@@ -154,7 +155,7 @@ xorblock(const unsigned char *in, unsigned char *out)
 {
     size_t q;
 
-    for (q = 0; q < BLOCK_SIZE; q += 4)
+    for (q = 0; q < AES_BLOCK_SIZE; q += 4)
         store_32_n(load_32_n(out + q) ^ load_32_n(in + q), out + q);
 }
 
@@ -166,7 +167,7 @@ init_key_cache(krb5_key key)
     key->cache = malloc(sizeof(struct aes_key_info_cache));
     if (key->cache == NULL)
         return ENOMEM;
-    CACHE(key)->enc_ctx.n_rnd = CACHE(key)->dec_ctx.n_rnd = 0;
+    CACHE(key)->enc_ctx.inf.l = CACHE(key)->dec_ctx.inf.l = 0;
     CACHE(key)->aesni = aesni_supported_by_cpu();
     return 0;
 }
@@ -174,24 +175,24 @@ init_key_cache(krb5_key key)
 static inline void
 expand_enc_key(krb5_key key)
 {
-    if (CACHE(key)->enc_ctx.n_rnd)
+    if (CACHE(key)->enc_ctx.inf.l != 0)
         return;
     if (aesni_supported(key))
         aesni_expand_enc_key(key);
-    else if (aes_enc_key(key->keyblock.contents, key->keyblock.length,
-                         &CACHE(key)->enc_ctx) != aes_good)
+    else if (aes_encrypt_key(key->keyblock.contents, key->keyblock.length,
+                             &CACHE(key)->enc_ctx) != EXIT_SUCCESS)
         abort();
 }
 
 static inline void
 expand_dec_key(krb5_key key)
 {
-    if (CACHE(key)->dec_ctx.n_rnd)
+    if (CACHE(key)->dec_ctx.inf.l != 0)
         return;
     if (aesni_supported(key))
         aesni_expand_dec_key(key);
-    else if (aes_dec_key(key->keyblock.contents, key->keyblock.length,
-                         &CACHE(key)->dec_ctx) != aes_good)
+    else if (aes_decrypt_key(key->keyblock.contents, key->keyblock.length,
+                             &CACHE(key)->dec_ctx) != EXIT_SUCCESS)
         abort();
 }
 
@@ -203,11 +204,11 @@ cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
         aesni_enc(key, data, nblocks, iv);
         return;
     }
-    for (; nblocks > 0; nblocks--, data += BLOCK_SIZE) {
+    for (; nblocks > 0; nblocks--, data += AES_BLOCK_SIZE) {
         xorblock(iv, data);
-        if (aes_enc_blk(data, data, &CACHE(key)->enc_ctx) != aes_good)
+        if (aes_encrypt(data, data, &CACHE(key)->enc_ctx) != EXIT_SUCCESS)
             abort();
-        memcpy(iv, data, BLOCK_SIZE);
+        memcpy(iv, data, AES_BLOCK_SIZE);
     }
 }
 
@@ -215,29 +216,29 @@ cbc_enc(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
 static inline void
 cbc_dec(krb5_key key, unsigned char *data, size_t nblocks, unsigned char *iv)
 {
-    unsigned char last_cipherblock[BLOCK_SIZE];
+    unsigned char last_cipherblock[AES_BLOCK_SIZE];
 
     if (aesni_supported(key)) {
         aesni_dec(key, data, nblocks, iv);
         return;
     }
     assert(nblocks > 0);
-    data += (nblocks - 1) * BLOCK_SIZE;
-    memcpy(last_cipherblock, data, BLOCK_SIZE);
-    for (; nblocks > 0; nblocks--, data -= BLOCK_SIZE) {
-        if (aes_dec_blk(data, data, &CACHE(key)->dec_ctx) != aes_good)
+    data += (nblocks - 1) * AES_BLOCK_SIZE;
+    memcpy(last_cipherblock, data, AES_BLOCK_SIZE);
+    for (; nblocks > 0; nblocks--, data -= AES_BLOCK_SIZE) {
+        if (aes_decrypt(data, data, &CACHE(key)->dec_ctx) != EXIT_SUCCESS)
             abort();
-        xorblock(nblocks == 1 ? iv : data - BLOCK_SIZE, data);
+        xorblock(nblocks == 1 ? iv : data - AES_BLOCK_SIZE, data);
     }
-    memcpy(iv, last_cipherblock, BLOCK_SIZE);
+    memcpy(iv, last_cipherblock, AES_BLOCK_SIZE);
 }
 
 krb5_error_code
 krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
                     size_t num_data)
 {
-    unsigned char iv[BLOCK_SIZE], block[BLOCK_SIZE];
-    unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+    unsigned char iv[AES_BLOCK_SIZE], block[AES_BLOCK_SIZE];
+    unsigned char blockN2[AES_BLOCK_SIZE], blockN1[AES_BLOCK_SIZE];
     size_t input_length, nblocks, ncontig;
     struct iov_cursor cursor;
 
@@ -245,22 +246,22 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
         return ENOMEM;
     expand_enc_key(key);
 
-    k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+    k5_iov_cursor_init(&cursor, data, num_data, AES_BLOCK_SIZE, FALSE);
 
     input_length = iov_total_length(data, num_data, FALSE);
-    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
+    nblocks = (input_length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
     if (nblocks == 1) {
         k5_iov_cursor_get(&cursor, block);
-        memset(iv, 0, BLOCK_SIZE);
+        memset(iv, 0, AES_BLOCK_SIZE);
         cbc_enc(key, block, 1, iv);
         k5_iov_cursor_put(&cursor, block);
         return 0;
     }
 
     if (ivec != NULL)
-        memcpy(iv, ivec->data, BLOCK_SIZE);
+        memcpy(iv, ivec->data, AES_BLOCK_SIZE);
     else
-        memset(iv, 0, BLOCK_SIZE);
+        memset(iv, 0, AES_BLOCK_SIZE);
 
     while (nblocks > 2) {
         ncontig = iov_cursor_contig_blocks(&cursor);
@@ -289,7 +290,7 @@ krb5int_aes_encrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     k5_iov_cursor_put(&cursor, blockN2);
 
     if (ivec != NULL)
-        memcpy(ivec->data, iv, BLOCK_SIZE);
+        memcpy(ivec->data, iv, AES_BLOCK_SIZE);
 
     return 0;
 }
@@ -298,8 +299,9 @@ krb5_error_code
 krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
                     size_t num_data)
 {
-    unsigned char iv[BLOCK_SIZE], dummy_iv[BLOCK_SIZE], block[BLOCK_SIZE];
-    unsigned char blockN2[BLOCK_SIZE], blockN1[BLOCK_SIZE];
+    unsigned char iv[AES_BLOCK_SIZE], dummy_iv[AES_BLOCK_SIZE];
+    unsigned char block[AES_BLOCK_SIZE];
+    unsigned char blockN2[AES_BLOCK_SIZE], blockN1[AES_BLOCK_SIZE];
     size_t input_length, last_len, nblocks, ncontig;
     struct iov_cursor cursor;
 
@@ -307,23 +309,23 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
         return ENOMEM;
     expand_dec_key(key);
 
-    k5_iov_cursor_init(&cursor, data, num_data, BLOCK_SIZE, FALSE);
+    k5_iov_cursor_init(&cursor, data, num_data, AES_BLOCK_SIZE, FALSE);
 
     input_length = iov_total_length(data, num_data, FALSE);
-    nblocks = (input_length + BLOCK_SIZE - 1) / BLOCK_SIZE;
-    last_len = input_length - (nblocks - 1) * BLOCK_SIZE;
+    nblocks = (input_length + AES_BLOCK_SIZE - 1) / AES_BLOCK_SIZE;
+    last_len = input_length - (nblocks - 1) * AES_BLOCK_SIZE;
     if (nblocks == 1) {
         k5_iov_cursor_get(&cursor, block);
-        memset(iv, 0, BLOCK_SIZE);
+        memset(iv, 0, AES_BLOCK_SIZE);
         cbc_dec(key, block, 1, iv);
         k5_iov_cursor_put(&cursor, block);
         return 0;
     }
 
     if (ivec != NULL)
-        memcpy(iv, ivec->data, BLOCK_SIZE);
+        memcpy(iv, ivec->data, AES_BLOCK_SIZE);
     else
-        memset(iv, 0, BLOCK_SIZE);
+        memset(iv, 0, AES_BLOCK_SIZE);
 
     while (nblocks > 2) {
         ncontig = iov_cursor_contig_blocks(&cursor);
@@ -346,7 +348,7 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
     k5_iov_cursor_get(&cursor, blockN2);
     k5_iov_cursor_get(&cursor, blockN1);
     if (ivec != NULL)
-        memcpy(ivec->data, blockN2, BLOCK_SIZE);
+        memcpy(ivec->data, blockN2, AES_BLOCK_SIZE);
 
     /* Decrypt the second-to-last ciphertext block, using the final ciphertext
      * block as the CBC IV.  This produces the final plaintext block. */
@@ -355,7 +357,7 @@ krb5int_aes_decrypt(krb5_key key, const krb5_data *ivec, krb5_crypto_iov *data,
 
     /* Use the final bits of the decrypted plaintext to pad the last ciphertext
      * block, and decrypt it to produce the second-to-last plaintext block. */
-    memcpy(blockN1 + last_len, blockN2 + last_len, BLOCK_SIZE - last_len);
+    memcpy(blockN1 + last_len, blockN2 + last_len, AES_BLOCK_SIZE - last_len);
     cbc_dec(key, blockN1, 1, iv);
 
     /* Put the last two plaintext blocks back into the iovec. */
index ba693f8a4126856bc73f8b920cf7ae07e4153279..19f808749f5a67807a5215775240d36cd7ec5440 100644 (file)
@@ -490,9 +490,9 @@ void krb5int_crypto_impl_cleanup(void);
  * the default PRNG module (prng_fortuna.c), crypto_mod.h must #define or
  * prototype the following symbols:
  *
- *   aes_ctx - Stack-allocatable type for an AES-128 or AES-256 key schedule
- *   krb5int_aes_enc_key(key, keybits, ctxptr) -- initialize a key schedule
- *   krb5int_aes_enc_blk(in, out, ctxptr) -- encrypt a block
+ *   aes_encrypt_ctx - Stack-allocatable type for an AES-256 key schedule
+ *   k5_aes_encrypt_key256(key, ctxptr) -- initialize an AES-256 key schedule
+ *   k5_aes_encrypt(in, out, ctxptr) -- encrypt a block
  *   SHA256_CTX - Stack-allocatable type for a SHA-256 hash state
  *   k5_sha256_init(ctxptr) - Initialize a hash state
  *   k5_sha256_update(ctxptr, data, size) -- Hash some data
index 017a119cc460022c48c0b0c6fd1292883c4788ff..e73a5019bf7b265f6a71ca08a719228b3fa15d67 100644 (file)
@@ -106,7 +106,7 @@ struct fortuna_state
     /* Generator state. */
     unsigned char counter[AES256_BLOCKSIZE];
     unsigned char key[AES256_KEYSIZE];
-    aes_ctx ciph;
+    aes_encrypt_ctx ciph;
 
     /* Accumulator state. */
     SHA256_CTX pool[NUM_POOLS];
@@ -179,7 +179,7 @@ inc_counter(struct fortuna_state *st)
 static void
 encrypt_counter(struct fortuna_state *st, unsigned char *dst)
 {
-    krb5int_aes_enc_blk(st->counter, dst, &st->ciph);
+    k5_aes_encrypt(st->counter, dst, &st->ciph);
     inc_counter(st);
 }
 
@@ -197,7 +197,7 @@ generator_reseed(struct fortuna_state *st, const unsigned char *data,
     shad256_update(&ctx, data, len);
     shad256_result(&ctx, st->key);
     zap(&ctx, sizeof(ctx));
-    krb5int_aes_enc_key(st->key, AES256_KEYSIZE, &st->ciph);
+    k5_aes_encrypt_key256(st->key, &st->ciph);
 
     /* Increment counter. */
     inc_counter(st);
@@ -209,7 +209,7 @@ change_key(struct fortuna_state *st)
 {
     encrypt_counter(st, st->key);
     encrypt_counter(st, st->key + AES256_BLOCKSIZE);
-    krb5int_aes_enc_key(st->key, AES256_KEYSIZE, &st->ciph);
+    k5_aes_encrypt_key256(st->key, &st->ciph);
 }
 
 /* Output pseudo-random data from the generator. */
index 451d5e03531150254021075c75503396a602ba89..d6cc1b423ad72c69b3a76d4c6ae74e4e9c098c90 100644 (file)
@@ -96,8 +96,8 @@ krb5int_enc_camellia128
 krb5int_enc_camellia256
 krb5int_derive_key
 krb5int_derive_random
-krb5int_aes_enc_blk
-krb5int_aes_enc_key
+k5_aes_encrypt
+k5_aes_encrypt_key256
 k5_sha256
 k5_sha256_final
 k5_sha256_init
index 6f6badbe5ae8d0dabf9a100dbcc640ed4ed5aa2e..cbf2f9e869002ba9e35613a3babcf046214e21e6 100644 (file)
@@ -44,9 +44,9 @@
 #define EVP_MD_CTX_free EVP_MD_CTX_destroy
 #endif
 
-#define aes_ctx AES_KEY
-#define krb5int_aes_enc_key(k, len, ctx) AES_set_encrypt_key(k, 8*(len), ctx)
-#define krb5int_aes_enc_blk(in, out, ctx) AES_encrypt(in, out, ctx)
+#define aes_encrypt_ctx AES_KEY
+#define k5_aes_encrypt_key256(k, ctx) AES_set_encrypt_key(k, 256, ctx)
+#define k5_aes_encrypt(in, out, ctx) AES_encrypt(in, out, ctx)
 #define k5_sha256_init SHA256_Init
 #define k5_sha256_update SHA256_Update
 #define k5_sha256_final SHA256_Final
index 1ee4d7b35f68d565b13bd25ce0bc012f23b6b13c..2f48d8ef80952b73e30f6c62e5e61a6868674212 100644 (file)
  * defined to OpenSSL equivalents when the OpenSSL back end headers are
  * used.
  */
-void krb5int_aes_enc_blk(void);
-void krb5int_aes_enc_key(void);
+void k5_aes_encrypt(void);
+void k5_aes_encrypt_key256(void);
 void k5_sha256_final(void);
 void k5_sha256_init(void);
 void k5_sha256_update(void);
 
-void krb5int_aes_enc_blk(void)
+void k5_aes_encrypt(void)
 {
     abort();
 }
 
-void krb5int_aes_enc_key(void)
+void k5_aes_encrypt_key256(void)
 {
     abort();
 }