aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2020-10-10 11:18:12 -0400
committerGreg Hudson <ghudson@mit.edu>2020-10-17 16:25:10 -0400
commitcb5f190056ef4d123c5fe5d4923982b830288438 (patch)
tree3ed48b6b5d1f02964291bbbca5e011cddfaab1be /src
parentad1c56d9b7dc3ce37b50cb3d72ff98513bf84073 (diff)
downloadkrb5-cb5f190056ef4d123c5fe5d4923982b830288438.zip
krb5-cb5f190056ef4d123c5fe5d4923982b830288438.tar.gz
krb5-cb5f190056ef4d123c5fe5d4923982b830288438.tar.bz2
Update Gladman AES code
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
Diffstat (limited to 'src')
-rw-r--r--src/lib/crypto/builtin/aes/Makefile.in1
-rw-r--r--src/lib/crypto/builtin/aes/aes-gen.c61
-rw-r--r--src/lib/crypto/builtin/aes/aes.h343
-rw-r--r--src/lib/crypto/builtin/aes/aes.txt662
-rw-r--r--src/lib/crypto/builtin/aes/aescpp.h55
-rw-r--r--src/lib/crypto/builtin/aes/aescrypp.c488
-rw-r--r--src/lib/crypto/builtin/aes/aescrypt.asm402
-rw-r--r--src/lib/crypto/builtin/aes/aescrypt.c507
-rw-r--r--src/lib/crypto/builtin/aes/aeskey.c753
-rw-r--r--src/lib/crypto/builtin/aes/aeskeypp.c400
-rw-r--r--src/lib/crypto/builtin/aes/aesopt.h1138
-rw-r--r--src/lib/crypto/builtin/aes/aessrc.url1
-rw-r--r--src/lib/crypto/builtin/aes/aestab.c445
-rw-r--r--src/lib/crypto/builtin/aes/aestab.h173
-rw-r--r--src/lib/crypto/builtin/aes/brg_endian.h144
-rw-r--r--src/lib/crypto/builtin/aes/brg_types.h217
-rw-r--r--src/lib/crypto/builtin/aes/deps12
-rw-r--r--src/lib/crypto/builtin/aes/kresults.expected223
-rw-r--r--src/lib/crypto/builtin/enc_provider/aes.c92
-rw-r--r--src/lib/crypto/krb/crypto_int.h6
-rw-r--r--src/lib/crypto/krb/prng_fortuna.c8
-rw-r--r--src/lib/crypto/libk5crypto.exports4
-rw-r--r--src/lib/crypto/openssl/crypto_mod.h6
-rw-r--r--src/lib/crypto/openssl/stubs.c8
24 files changed, 3125 insertions, 3024 deletions
diff --git a/src/lib/crypto/builtin/aes/Makefile.in b/src/lib/crypto/builtin/aes/Makefile.in
index 11a1107..05c7bd5 100644
--- a/src/lib/crypto/builtin/aes/Makefile.in
+++ b/src/lib/crypto/builtin/aes/Makefile.in
@@ -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
diff --git a/src/lib/crypto/builtin/aes/aes-gen.c b/src/lib/crypto/builtin/aes/aes-gen.c
index e33c193..07d94b8 100644
--- a/src/lib/crypto/builtin/aes/aes-gen.c
+++ b/src/lib/crypto/builtin/aes/aes-gen.c
@@ -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);
diff --git a/src/lib/crypto/builtin/aes/aes.h b/src/lib/crypto/builtin/aes/aes.h
index 8f6f426..9b5215e 100644
--- a/src/lib/crypto/builtin/aes/aes.h
+++ b/src/lib/crypto/builtin/aes/aes.h
@@ -1,95 +1,286 @@
/*
- * 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)
}
diff --git a/src/lib/crypto/builtin/aes/aes.txt b/src/lib/crypto/builtin/aes/aes.txt
index b644b5e..25710f2 100644
--- a/src/lib/crypto/builtin/aes/aes.txt
+++ b/src/lib/crypto/builtin/aes/aes.txt
@@ -1,70 +1,622 @@
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
index d556224..0000000
--- a/src/lib/crypto/builtin/aes/aescpp.h
+++ /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
index 1f1cf63..0000000
--- a/src/lib/crypto/builtin/aes/aescrypp.c
+++ /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
index 25070f0..0000000
--- a/src/lib/crypto/builtin/aes/aescrypt.asm
+++ /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
diff --git a/src/lib/crypto/builtin/aes/aescrypt.c b/src/lib/crypto/builtin/aes/aescrypt.c
index 194f8e5..4c2b0db 100644
--- a/src/lib/crypto/builtin/aes/aescrypt.c
+++ b/src/lib/crypto/builtin/aes/aescrypt.c
@@ -1,422 +1,301 @@
/*
- * 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
diff --git a/src/lib/crypto/builtin/aes/aeskey.c b/src/lib/crypto/builtin/aes/aeskey.c
index 8402b50..11ed11a 100644
--- a/src/lib/crypto/builtin/aes/aeskey.c
+++ b/src/lib/crypto/builtin/aes/aeskey.c
@@ -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
index cd9c5a7..0000000
--- a/src/lib/crypto/builtin/aes/aeskeypp.c
+++ /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
diff --git a/src/lib/crypto/builtin/aes/aesopt.h b/src/lib/crypto/builtin/aes/aesopt.h
index 6588b7f..5d24c8a 100644
--- a/src/lib/crypto/builtin/aes/aesopt.h
+++ b/src/lib/crypto/builtin/aes/aesopt.h
@@ -1,303 +1,126 @@
/*
- * 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
@@ -323,16 +146,128 @@
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
@@ -348,22 +283,13 @@
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.
@@ -373,86 +299,101 @@
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:
@@ -466,35 +407,35 @@
*/
#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
@@ -502,291 +443,281 @@
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
index 874dd3d..0000000
--- a/src/lib/crypto/builtin/aes/aessrc.url
+++ /dev/null
@@ -1 +0,0 @@
-https://github.com/BrianGladman/AES
diff --git a/src/lib/crypto/builtin/aes/aestab.c b/src/lib/crypto/builtin/aes/aestab.c
index ef182d6..3d48edf 100644
--- a/src/lib/crypto/builtin/aes/aestab.c
+++ b/src/lib/crypto/builtin/aes/aestab.c
@@ -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),\
@@ -112,9 +91,9 @@
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),\
@@ -146,35 +125,19 @@
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)
@@ -185,135 +148,56 @@
#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
index 0000000..8fe32d1
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/aestab.h
@@ -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
index 0000000..c0e32b7
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/brg_endian.h
@@ -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
index 0000000..ce3a1e7
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/brg_types.h
@@ -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
diff --git a/src/lib/crypto/builtin/aes/deps b/src/lib/crypto/builtin/aes/deps
index fcd5520..5acef42 100644
--- a/src/lib/crypto/builtin/aes/deps
+++ b/src/lib/crypto/builtin/aes/deps
@@ -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
index 0000000..443d5c4
--- /dev/null
+++ b/src/lib/crypto/builtin/aes/kresults.expected
@@ -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
+
diff --git a/src/lib/crypto/builtin/enc_provider/aes.c b/src/lib/crypto/builtin/enc_provider/aes.c
index 2a5d8e3..92c1702 100644
--- a/src/lib/crypto/builtin/enc_provider/aes.c
+++ b/src/lib/crypto/builtin/enc_provider/aes.c
@@ -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. */
diff --git a/src/lib/crypto/krb/crypto_int.h b/src/lib/crypto/krb/crypto_int.h
index ba693f8..19f8087 100644
--- a/src/lib/crypto/krb/crypto_int.h
+++ b/src/lib/crypto/krb/crypto_int.h
@@ -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
diff --git a/src/lib/crypto/krb/prng_fortuna.c b/src/lib/crypto/krb/prng_fortuna.c
index 017a119..e73a501 100644
--- a/src/lib/crypto/krb/prng_fortuna.c
+++ b/src/lib/crypto/krb/prng_fortuna.c
@@ -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. */
diff --git a/src/lib/crypto/libk5crypto.exports b/src/lib/crypto/libk5crypto.exports
index 451d5e0..d6cc1b4 100644
--- a/src/lib/crypto/libk5crypto.exports
+++ b/src/lib/crypto/libk5crypto.exports
@@ -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
diff --git a/src/lib/crypto/openssl/crypto_mod.h b/src/lib/crypto/openssl/crypto_mod.h
index 6f6badb..cbf2f9e 100644
--- a/src/lib/crypto/openssl/crypto_mod.h
+++ b/src/lib/crypto/openssl/crypto_mod.h
@@ -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
diff --git a/src/lib/crypto/openssl/stubs.c b/src/lib/crypto/openssl/stubs.c
index 1ee4d7b..2f48d8e 100644
--- a/src/lib/crypto/openssl/stubs.c
+++ b/src/lib/crypto/openssl/stubs.c
@@ -37,18 +37,18 @@
* 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();
}