diff --git a/include/polarssl/aes.h b/include/polarssl/aes.h index 1b93e2a3d..0eb25dfff 100644 --- a/include/polarssl/aes.h +++ b/include/polarssl/aes.h @@ -38,6 +38,7 @@ typedef UINT32 uint32_t; #include #endif +/* padlock.c and aesni.c rely on these values! */ #define AES_ENCRYPT 1 #define AES_DECRYPT 0 diff --git a/include/polarssl/aesni.h b/include/polarssl/aesni.h index 9aaeff196..d6684fc6c 100644 --- a/include/polarssl/aesni.h +++ b/include/polarssl/aesni.h @@ -38,12 +38,27 @@ #if defined(POLARSSL_HAVE_X86_64) /** - * \brief AES_NI detection routine + * \brief AES-NI detection routine * * \return 1 if CPU supports AES-NI, 0 otherwise */ int aesni_supported( void ); +/** + * \brief AES-NI AES-ECB block en(de)cryption + * + * \param ctx AES context + * \param mode AES_ENCRYPT or AES_DECRYPT + * \param input 16-byte input block + * \param output 16-byte output block + * + * \return 0 if success, 1 if operation failed + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ); + #endif /* POLARSSL_HAVE_X86_64 */ #endif /* POLARSSL_AESNI_H */ diff --git a/library/aes.c b/library/aes.c index a3835cead..6d090a11d 100644 --- a/library/aes.c +++ b/library/aes.c @@ -37,6 +37,9 @@ #if defined(POLARSSL_PADLOCK_C) #include "polarssl/padlock.h" #endif +#if defined(POLARSSL_AESNI_C) +#include "polarssl/aesni.h" +#endif #if !defined(POLARSSL_AES_ALT) @@ -673,6 +676,11 @@ int aes_crypt_ecb( aes_context *ctx, int i; uint32_t *RK, X0, X1, X2, X3, Y0, Y1, Y2, Y3; +#if defined(POLARSSL_AESNI_C) && defined(POLARSSL_HAVE_X86_64) + if( aesni_supported() ) + return( aesni_crypt_ecb( ctx, mode, input, output ) ); +#endif + #if defined(POLARSSL_PADLOCK_C) && defined(POLARSSL_HAVE_X86) if( aes_padlock_ace ) { diff --git a/library/aesni.c b/library/aesni.c index 2882298e0..7628a0362 100644 --- a/library/aesni.c +++ b/library/aesni.c @@ -32,6 +32,7 @@ #if defined(POLARSSL_AESNI_C) #include "polarssl/aesni.h" +#include #if defined(POLARSSL_HAVE_X86_64) @@ -56,6 +57,50 @@ int aesni_supported( void ) return( supported ); } +/* + * AES-NI AES-ECB block en(de)cryption + */ +int aesni_crypt_ecb( aes_context *ctx, + int mode, + const unsigned char input[16], + unsigned char output[16] ) +{ + asm( "movdqu (%3), %%xmm0 \n" // load input + "movdqu (%1), %%xmm1 \n" // load round key 0 + "pxor %%xmm1, %%xmm0 \n" // round 0 + "addq $16, %1 \n" // point to next round key + "subl $1, %0 \n" // normal rounds = nr - 1 + "test %2, %2 \n" // mode? + "jz 2f \n" // 0 = decrypt + + "1: \n" // encryption loop + "movdqu (%1), %%xmm1 \n" // load round key + "aesenc %%xmm1, %%xmm0 \n" // do round + "addq $16, %1 \n" // point to next round key + "subl $1, %0 \n" // loop + "jnz 1b \n" + "movdqu (%1), %%xmm1 \n" // load round key + "aesenclast %%xmm1, %%xmm0 \n" // last round + "jmp 3f \n" + + "2: \n" // decryption loop + "movdqu (%1), %%xmm1 \n" + "aesdec %%xmm1, %%xmm0 \n" + "addq $16, %1 \n" + "subl $1, %0 \n" + "jnz 2b \n" + "movdqu (%1), %%xmm1 \n" // load round key + "aesdeclast %%xmm1, %%xmm0 \n" // last round + + "3: \n" + "movdqu %%xmm0, (%4) \n" // export output + : + : "r" (ctx->nr), "r" (ctx->rk), "r" (mode), "r" (input), "r" (output) + : "memory", "cc", "xmm0", "xmm1" ); + + + return( 0 ); +} #endif /* POLARSSL_HAVE_X86_64 */ #endif /* POLARSSL_AESNI_C */