introduce separate aes_desc

`aes_desc` and `aes_enc_desc` now do auto-detection of the best suitable
AES implementation for the platform.

Signed-off-by: Steffen Jaeckel <s@jaeckel.eu>
This commit is contained in:
Steffen Jaeckel 2021-09-30 14:49:26 +02:00 committed by Jamie Reece Wilson
parent 2a8e6a229c
commit 33a26c4959
16 changed files with 306 additions and 100 deletions

View File

@ -614,7 +614,10 @@ As of this release the current cipher\_descriptors elements are the following:
\hline SAFER+ & saferp\_desc &16 & 16, 24, 32 & 8, 12, 16 & 4 \\
\hline AES & aes\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& aes\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& aesni\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& rijndael\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
& rijndael\_enc\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
\hline AES & aesni\_desc & 16 & 16, 24, 32 & 10, 12, 14 & 6 \\
(only on x86 with SSE4.1) &&&&& \\
\hline Twofish & twofish\_desc & 16 & 16, 24, 32 & 16 & 7 \\
\hline DES & des\_desc & 8 & 8 & 16 & 13 \\
\hline 3DES (EDE mode) & des3\_desc & 8 & 16, 24 & 16 & 14 \\
@ -640,24 +643,30 @@ As of this release the current cipher\_descriptors elements are the following:
\begin{small}
\begin{enumerate}
\item
For AES, (also known as Rijndael) there are four descriptors which complicate issues a little. The descriptors
rijndael\_desc and rijndael\_enc\_desc provide the cipher named \textit{rijndael}. The descriptors aes\_desc and
aes\_enc\_desc provide the cipher name \textit{aes}. Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The
For AES, (also known as Rijndael) there are multiple descriptors which complicate issues a little. As of FIXME-version-next
the library also integrates hardware-accelerated AES operations (e.g. AES-NI on amd64 with SSE4.1). Therefor the functionality of
the descriptors for the AES algorithm has changed. The rijndael\_desc and rijndael\_enc\_desc descriptors provide the cipher
named \textit{rijndael} which contains the software implementation of the algorithm. The descriptors aes\_desc and aes\_enc\_desc
provide the cipher named \textit{aes} and implement an auto-detection mechanism that chooses between the software-only \textit{rijndael}
and the hardware-accelerated implementation.
Functionally both \textit{rijndael} and \textit{aes} are the same cipher. The
only difference is when you call find\_cipher() you have to pass the correct name. The cipher descriptors with \textit{enc}
in the middle (e.g. rijndael\_enc\_desc) are related to an implementation of Rijndael with only the encryption routine
and tables. The decryption and self--test function pointers of both \textit{encrypt only} descriptors are set to \textbf{NULL} and
should not be called.
The \textit{encrypt only} descriptors are useful for applications that only use the encryption function of the cipher. Algorithms such
as EAX, PMAC and OMAC only require the encryption function. So far this \textit{encrypt only} functionality has only been implemented for
Rijndael as it makes the most sense for this cipher.
as EAX, PMAC and OMAC or the CTR mode only require the encryption function. So far this \textit{encrypt only} functionality has only
been implemented for Rijndael as it makes the most sense for this cipher.
\item
Note that for \textit{DES} and \textit{3DES} they use 8 and 24 byte keys but only 7 and 21 [respectively] bytes of the keys are in
fact used for the purposes of encryption. My suggestion is just to use random 8/24 byte keys instead of trying to make a 8/24
byte string from the real 7/21 byte key.
For \textit{3DES} exists a two-key mode, that can be initialized by calling the setup function with a \textit{keylen} of 16. This results in the re-usage of key \textit{K1} as key \textit{K3}. This mode has been specified as \textit{Keying Option 2} in FIPS 46-3.
For \textit{3DES} exists a two-key mode, that can be initialized by calling the setup function with a \textit{keylen} of 16.
This results in the re-usage of key \textit{K1} as key \textit{K3}. This mode has been specified as \textit{Keying Option 2} in FIPS 46-3.
\item
Note that \textit{Twofish} has additional configuration options (Figure \ref{fig:twofishopts}) that take place at build time. These options are found in

View File

@ -316,7 +316,7 @@ sub process_makefiles {
my @t = qw();
find({ no_chdir => 1, wanted => sub { push @t, $_ if $_ =~ /(common|no_prng|_tests?|test).c$/ } }, 'tests');
my @o = sort ('src/ciphers/aes/aes_enc.o', map { my $x = $_; $x =~ s/\.c$/.o/; $x } @c);
my @o = sort ('src/ciphers/aes/aes_enc.o', 'src/ciphers/aes/aes_enc_desc.o', map { my $x = $_; $x =~ s/\.c$/.o/; $x } @c);
my $var_o = prepare_variable("OBJECTS", @o);
my $var_h = prepare_variable("HEADERS_PUB", (sort @h));
(my $var_obj = $var_o) =~ s/\.o\b/.obj/sg;

View File

@ -46,6 +46,11 @@ LTC_EXTRALIBS += $(EXTRALIBS)
#AES comes in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
ifneq ($V,1)
@echo " * ${CC} $@" ${silent_echo}
endif
${silent} ${CC} ${LTC_CFLAGS} -DENCRYPT_ONLY -c $< -o $@
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
ifneq ($V,1)
@echo " * ${CC} $@" ${silent_echo}
endif

View File

@ -246,6 +246,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
#SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -239,6 +239,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes.c /Fosrc/ciphers/aes/aes_enc.obj
src/ciphers/aes/aes_enc_desc.obj: src/ciphers/aes/aes_desc.c
$(CC) $(LTC_CFLAGS) /DENCRYPT_ONLY /c src/ciphers/aes/aes_desc.c /Fosrc/ciphers/aes/aes_enc_desc.obj
#SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.obj: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -70,6 +70,8 @@ endif
#ciphers come in two flavours... enc+dec and enc
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
.c.o:
$(LTCOMPILE) $(LTC_CFLAGS) $(CPPFLAGS) $(LTC_LDFLAGS) -o $@ -c $<

View File

@ -256,6 +256,8 @@ default: $(LIBMAIN_S)
#SPECIAL: AES comes in two flavours - enc+dec and enc-only
src/ciphers/aes/aes_enc.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes.c -o src/ciphers/aes/aes_enc.o
src/ciphers/aes/aes_enc_desc.o: src/ciphers/aes/aes_desc.c
$(CC) $(LTC_CFLAGS) -DENCRYPT_ONLY -c src/ciphers/aes/aes_desc.c -o src/ciphers/aes/aes_enc_desc.o
#SPECIAL: these are the rules to make certain object files
src/ciphers/aes/aes.o: src/ciphers/aes/aes.c src/ciphers/aes/aes_tab.c

View File

@ -427,6 +427,7 @@ src/hashes/sha2/sha512_224.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha512_22
src/hashes/sha2/sha512_256.o: src/hashes/sha2/sha512.c src/hashes/sha2/sha512_256.c
src/hashes/whirl/whirl.o: src/hashes/whirl/whirl.c src/hashes/whirl/whirltab.c
$(DOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS)
$(TOBJECTS): LTC_CFLAGS := -Itests $(LTC_CFLAGS)

View File

@ -44,15 +44,6 @@ const struct ltc_cipher_descriptor rijndael_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define SETUP rijndael_enc_setup
@ -69,15 +60,6 @@ const struct ltc_cipher_descriptor rijndael_enc_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
#define LTC_AES_TAB_C

244
src/ciphers/aes/aes_desc.c Normal file
View File

@ -0,0 +1,244 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
/* Auto-detection of AES implementation by Steffen Jaeckel */
/**
@file aes_desc.c
Run-time detection of correct AES implementation
*/
#include "tomcrypt_private.h"
#if defined(LTC_RIJNDAEL)
#ifndef ENCRYPT_ONLY
#define AES_SETUP aes_setup
#define AES_ENC aes_ecb_encrypt
#define AES_DEC aes_ecb_decrypt
#define AES_DONE aes_done
#define AES_TEST aes_test
#define AES_KS aes_keysize
const struct ltc_cipher_descriptor aes_desc =
{
"aes",
6,
16, 32, 16, 10,
AES_SETUP, AES_ENC, AES_DEC, AES_TEST, AES_DONE, AES_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#else
#define AES_SETUP aes_enc_setup
#define AES_ENC aes_enc_ecb_encrypt
#define AES_DONE aes_enc_done
#define AES_KS aes_enc_keysize
const struct ltc_cipher_descriptor aes_enc_desc =
{
"aes",
6,
16, 32, 16, 10,
AES_SETUP, AES_ENC, NULL, NULL, AES_DONE, AES_KS,
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
#endif
/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */
#if defined(LTC_HAS_AES_NI)
static LTC_INLINE int s_aesni_is_supported(void)
{
static int initialized = 0, is_supported = 0;
if (initialized == 0) {
int a, b, c, d;
/* Look for CPUID.1.0.ECX[25]
* EAX = 1, ECX = 0
*/
a = 1;
c = 0;
asm volatile ("cpuid"
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
:"a"(a), "c"(c)
);
is_supported = ((c >> 25) & 1);
initialized = 1;
}
return is_supported;
}
#ifndef ENCRYPT_ONLY
int aesni_is_supported(void)
{
return s_aesni_is_supported();
}
#endif
#endif
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@param keylen The key length in bytes
@param num_rounds The number of rounds desired (0 for default)
@param skey The key in as scheduled by this function.
@return CRYPT_OK if successful
*/
int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_setup(key, keylen, num_rounds, skey);
}
#endif
/* Last resort, software AES */
return rijndael_setup(key, keylen, num_rounds, skey);
}
/**
Encrypts a block of text with AES
@param pt The input plaintext (16 bytes)
@param ct The output ciphertext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_encrypt(pt, ct, skey);
}
#endif
return rijndael_ecb_encrypt(pt, ct, skey);
}
/**
Decrypts a block of text with AES
@param ct The input ciphertext (16 bytes)
@param pt The output plaintext (16 bytes)
@param skey The key as scheduled
@return CRYPT_OK if successful
*/
int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
{
#ifdef LTC_HAS_AES_NI
if (s_aesni_is_supported()) {
return aesni_ecb_decrypt(ct, pt, skey);
}
#endif
return rijndael_ecb_decrypt(ct, pt, skey);
}
/**
Performs a self-test of the AES block cipher
@return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
*/
int AES_TEST(void)
{
#ifndef LTC_TEST
return CRYPT_NOP;
#else
int err;
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
} tests[] = {
{ 16,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
}, {
24,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
}, {
32,
{ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
{ 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
{ 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
}
};
symmetric_key key;
unsigned char tmp[2][16];
int i, y;
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
zeromem(&key, sizeof(key));
if ((err = aes_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
return err;
}
aes_ecb_encrypt(tests[i].pt, tmp[0], &key);
aes_ecb_decrypt(tmp[0], tmp[1], &key);
if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) {
return CRYPT_FAIL_TESTVECTOR;
}
/* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
for (y = 0; y < 16; y++) tmp[0][y] = 0;
for (y = 0; y < 1000; y++) aes_ecb_encrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 1000; y++) aes_ecb_decrypt(tmp[0], tmp[0], &key);
for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
}
return CRYPT_OK;
#endif
}
/** Terminate the context
@param skey The scheduled key
*/
void AES_DONE(symmetric_key *skey)
{
LTC_UNUSED_PARAM(skey);
}
/**
Gets suitable key size
@param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
@return CRYPT_OK if the input key size is acceptable.
*/
int AES_KS(int *keysize)
{
LTC_ARGCHK(keysize != NULL);
if (*keysize < 16) {
return CRYPT_INVALID_KEYSIZE;
}
if (*keysize < 24) {
*keysize = 16;
return CRYPT_OK;
}
if (*keysize < 32) {
*keysize = 24;
return CRYPT_OK;
}
*keysize = 32;
return CRYPT_OK;
}
#endif

View File

@ -9,8 +9,7 @@
#include "tomcrypt_private.h"
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
#if defined(LTC_HAS_AES_NI)
const struct ltc_cipher_descriptor aesni_desc =
{
@ -35,32 +34,6 @@ static const ulong32 rcon[] = {
0x01UL, 0x02UL, 0x04UL, 0x08UL, 0x10UL, 0x20UL, 0x40UL, 0x80UL, 0x1BUL, 0x36UL
};
/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */
static int s_aesni_is_supported(void)
{
static int initialized = 0, is_supported = 0;
if (initialized == 0) {
int a, b, c, d;
/* Look for CPUID.1.0.ECX[25]
* EAX = 1, ECX = 0
*/
a = 1;
c = 0;
asm volatile ("cpuid"
:"=a"(a), "=b"(b), "=c"(c), "=d"(d)
:"a"(a), "c"(c)
);
is_supported = ((c >> 25) & 1);
initialized = 1;
}
return is_supported;
}
/**
Initialize the AES (Rijndael) block cipher
@param key The symmetric key you wish to pass
@ -78,14 +51,6 @@ int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(skey != NULL);
if (s_aesni_is_supported() == 0) {
#ifdef LTC_RIJNDAEL
return rijndael_setup(key, keylen, num_rounds, skey);
#else
return CRYPT_INVALID_CIPHER;
#endif
}
if (keylen != 16 && keylen != 24 && keylen != 32) {
return CRYPT_INVALID_KEYSIZE;
}
@ -213,14 +178,6 @@ int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetri
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
if (s_aesni_is_supported() == 0) {
#ifdef LTC_RIJNDAEL
return rijndael_ecb_encrypt(pt, ct, skey);
#else
return CRYPT_INVALID_CIPHER;
#endif
}
Nr = skey->rijndael.Nr;
if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;
@ -272,14 +229,6 @@ int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetri
LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(skey != NULL);
if (s_aesni_is_supported() == 0) {
#ifdef LTC_RIJNDAEL
return rijndael_ecb_decrypt(ct, pt, skey);
#else
return CRYPT_INVALID_CIPHER;
#endif
}
Nr = skey->rijndael.Nr;
if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;

View File

@ -689,18 +689,19 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
#endif
#ifdef LTC_RIJNDAEL
/* make aes an alias */
#define aes_setup rijndael_setup
#define aes_ecb_encrypt rijndael_ecb_encrypt
#define aes_ecb_decrypt rijndael_ecb_decrypt
#define aes_test rijndael_test
#define aes_done rijndael_done
#define aes_keysize rijndael_keysize
#define aes_enc_setup rijndael_enc_setup
#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
#define aes_enc_keysize rijndael_enc_keysize
/* declare aes properly now */
int aes_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
int aes_test(void);
void aes_done(symmetric_key *skey);
int aes_keysize(int *keysize);
int aes_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aes_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
void aes_enc_done(symmetric_key *skey);
int aes_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor aes_desc;
extern const struct ltc_cipher_descriptor aes_enc_desc;
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
@ -712,11 +713,12 @@ int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, sym
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
void rijndael_enc_done(symmetric_key *skey);
int rijndael_enc_keysize(int *keysize);
extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
extern const struct ltc_cipher_descriptor rijndael_desc;
extern const struct ltc_cipher_descriptor rijndael_enc_desc;
#endif
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
int aesni_is_supported(void);
int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);

View File

@ -77,6 +77,10 @@ typedef struct
/* tomcrypt_cipher.h */
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
#define LTC_HAS_AES_NI
#endif
void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
int blowfish_expand(const unsigned char *key, int keylen,
const unsigned char *data, int datalen,

View File

@ -16,20 +16,17 @@
int register_all_ciphers(void)
{
#ifdef LTC_RIJNDAEL
/* `aesni_desc` is explicitely not registered, since it's handled from within the `aes_desc` */
#ifdef ENCRYPT_ONLY
/* alternative would be
* register_cipher(&rijndael_enc_desc);
*/
REGISTER_CIPHER(&aes_enc_desc);
#else
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
REGISTER_CIPHER(&aesni_desc);
#else
/* alternative would be
* register_cipher(&rijndael_desc);
*/
REGISTER_CIPHER(&aes_desc);
#endif /* AES-NI */
#endif
#endif
#ifdef LTC_BLOWFISH

View File

@ -13,6 +13,14 @@ int cipher_hash_test(void)
DOX(cipher_descriptor[x].test(), cipher_descriptor[x].name);
}
/* explicit AES-NI test */
#if defined(LTC_HAS_AES_NI)
if (aesni_is_supported()) {
DO(aesni_test());
}
DO(rijndael_test());
#endif
/* test stream ciphers */
#ifdef LTC_CHACHA
DO(chacha_test());

View File

@ -106,20 +106,17 @@ static void *run(void *arg)
static void s_unregister_all(void)
{
#ifdef LTC_RIJNDAEL
/* `aesni_desc` is not registered, i.e. also shouldn't be unregistered */
#ifdef ENCRYPT_ONLY
/* alternative would be
* unregister_cipher(&rijndael_enc_desc);
*/
unregister_cipher(&aes_enc_desc);
#else
#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
unregister_cipher(&aesni_desc);
#else
/* alternative would be
* unregister_cipher(&rijndael_desc);
*/
unregister_cipher(&aes_desc);
#endif /* AES-NI */
#endif
#endif
#ifdef LTC_BLOWFISH