| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- /*
- * This file is adapted from PolarSSL 1.3.19 (GPL)
- */
- #include "aesni.h"
- #include "aesarm.h"
- #include <stdint.h>
- #include <string.h>
- #include <assert.h>
- #if defined(AES256) && (AES256 == 1)
- #define AES_KEYSIZE 256
- #ifdef HAVE_AMD64
- #define aeshw_setkey_enc aesni_setkey_enc_256
- #endif
- #elif defined(AES192) && (AES192 == 1)
- #define AES_KEYSIZE 192
- #ifdef HAVE_AMD64
- #define aeshw_setkey_enc aesni_setkey_enc_192
- #endif
- #else
- #define AES_KEYSIZE 128
- #ifdef HAVE_AMD64
- #define aeshw_setkey_enc aesni_setkey_enc_128
- #endif
- #endif
- #define AES_NR ((AES_KEYSIZE >> 5) + 6)
- #define AES_RKSIZE 272
- #ifdef HAVE_AMD64
- #define HAVE_HARDAES 1
- #define aeshw_supported aesni_supported
- #define aeshw_crypt_ecb aesni_crypt_ecb
- #define aeshw_inverse_key(a,b) aesni_inverse_key(a,b,AES_NR)
- #endif /* HAVE_AMD64 */
- #ifdef HAVE_ARM64
- #define HAVE_HARDAES 1
- #define aeshw_supported aesarm_supported
- #define aeshw_crypt_ecb aesarm_crypt_ecb
- #include "aesarm_table.h"
- #ifndef GET_UINT32_LE
- #define GET_UINT32_LE(n,b,i) \
- { \
- (n) = ( (uint32_t) (b)[(i) ] ) \
- | ( (uint32_t) (b)[(i) + 1] << 8 ) \
- | ( (uint32_t) (b)[(i) + 2] << 16 ) \
- | ( (uint32_t) (b)[(i) + 3] << 24 ); \
- }
- #endif
- static void aeshw_setkey_enc(uint8_t *rk, const uint8_t *key)
- {
- unsigned int i;
- uint32_t *RK;
- RK = (uint32_t *) rk;
- for( i = 0; i < ( AES_KEYSIZE >> 5 ); i++ )
- {
- GET_UINT32_LE( RK[i], key, i << 2 );
- }
- switch( AES_NR )
- {
- case 10:
- for( i = 0; i < 10; i++, RK += 4 )
- {
- RK[4] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[3] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[3] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[3] ) & 0xFF ] << 24 );
- RK[5] = RK[1] ^ RK[4];
- RK[6] = RK[2] ^ RK[5];
- RK[7] = RK[3] ^ RK[6];
- }
- break;
- case 12:
- for( i = 0; i < 8; i++, RK += 6 )
- {
- RK[6] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[5] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[5] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[5] ) & 0xFF ] << 24 );
- RK[7] = RK[1] ^ RK[6];
- RK[8] = RK[2] ^ RK[7];
- RK[9] = RK[3] ^ RK[8];
- RK[10] = RK[4] ^ RK[9];
- RK[11] = RK[5] ^ RK[10];
- }
- break;
- case 14:
- for( i = 0; i < 7; i++, RK += 8 )
- {
- RK[8] = RK[0] ^ RCON[i] ^
- ( (uint32_t) FSb[ ( RK[7] >> 8 ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 16 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[7] >> 24 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[7] ) & 0xFF ] << 24 );
- RK[9] = RK[1] ^ RK[8];
- RK[10] = RK[2] ^ RK[9];
- RK[11] = RK[3] ^ RK[10];
- RK[12] = RK[4] ^
- ( (uint32_t) FSb[ ( RK[11] ) & 0xFF ] ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 8 ) & 0xFF ] << 8 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 16 ) & 0xFF ] << 16 ) ^
- ( (uint32_t) FSb[ ( RK[11] >> 24 ) & 0xFF ] << 24 );
- RK[13] = RK[5] ^ RK[12];
- RK[14] = RK[6] ^ RK[13];
- RK[15] = RK[7] ^ RK[14];
- }
- break;
- }
- }
- static void aeshw_inverse_key(uint8_t *invkey, const uint8_t *fwdkey)
- {
- int i, j;
- uint32_t *RK;
- uint32_t *SK;
- RK = (uint32_t *) invkey;
- SK = ((uint32_t *) fwdkey) + AES_NR * 4;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- for( i = AES_NR - 1, SK -= 8; i > 0; i--, SK -= 8 )
- {
- for( j = 0; j < 4; j++, SK++ )
- {
- *RK++ = RT0[ FSb[ ( *SK ) & 0xFF ] ] ^
- RT1[ FSb[ ( *SK >> 8 ) & 0xFF ] ] ^
- RT2[ FSb[ ( *SK >> 16 ) & 0xFF ] ] ^
- RT3[ FSb[ ( *SK >> 24 ) & 0xFF ] ];
- }
- }
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- *RK++ = *SK++;
- }
- #endif /* HAVE_ARM64 */
- #ifdef HAVE_HARDAES
- static void aeshw_setkey_dec(uint8_t *rk, const uint8_t *key)
- {
- uint8_t rk_tmp[AES_RKSIZE];
- aeshw_setkey_enc(rk_tmp, key);
- aeshw_inverse_key(rk, rk_tmp);
- }
- static void aeshw_encrypt_ecb( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- aeshw_crypt_ecb(nr, rk, AES_ENCRYPT, input, output);
- }
- static void aeshw_decrypt_ecb( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- aeshw_crypt_ecb(nr, rk, AES_DECRYPT, input, output);
- }
- #endif /* HAVE_HARDAES */
- /* OpenSSL assembly functions */
- #define AES_MAXNR 14
- typedef struct {
- uint32_t rd_key[4 * (AES_MAXNR + 1)];
- uint32_t rounds;
- } AES_KEY;
- #if defined(__amd64__) || defined(__x86_64__) || \
- defined(__aarch64__)
- #define AES_set_encrypt_key vpaes_set_encrypt_key
- #define AES_set_decrypt_key vpaes_set_decrypt_key
- #define AES_encrypt vpaes_encrypt
- #define AES_decrypt vpaes_decrypt
- #endif /* VPAES for 64-bit Intel and ARM */
- #ifdef __cplusplus
- extern "C" {
- #endif
- int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
- int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
- AES_KEY *key);
- void AES_encrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
- void AES_decrypt(const unsigned char *in, unsigned char *out,
- const AES_KEY *key);
- #ifdef __cplusplus
- }
- #endif
- static void aes_encrypt_ecb( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- AES_encrypt(input, output, (AES_KEY *) rk);
- }
- static void aes_decrypt_ecb( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- {
- AES_decrypt(input, output, (AES_KEY *) rk);
- }
- static void aes_setkey_enc(uint8_t *rk, const uint8_t *key)
- {
- AES_set_encrypt_key(key, AES_KEYSIZE, (AES_KEY *) rk);
- }
- static void aes_setkey_dec(uint8_t *rk, const uint8_t *key)
- {
- AES_set_decrypt_key(key, AES_KEYSIZE, (AES_KEY *) rk);
- }
- static void (*encrypt_ecb) ( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- = aes_encrypt_ecb;
- static void (*decrypt_ecb) ( int nr,
- unsigned char *rk,
- const unsigned char input[16],
- unsigned char output[16] )
- = aes_decrypt_ecb;
- static void (*setkey_enc) (uint8_t *rk, const uint8_t *key)
- = aes_setkey_enc;
- static void (*setkey_dec) (uint8_t *rk, const uint8_t *key)
- = aes_setkey_dec;
- /*
- * AESNI-CBC buffer encryption/decryption
- */
- static void encrypt_cbc( uint8_t* rk,
- uint32_t length,
- uint8_t iv[16],
- const uint8_t *input,
- uint8_t *output )
- {
- int i;
- uint8_t temp[16];
- while( length > 0 )
- {
- for( i = 0; i < 16; i++ )
- output[i] = (uint8_t)( input[i] ^ iv[i] );
- encrypt_ecb( AES_NR, rk, output, output );
- memcpy( iv, output, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- static void decrypt_cbc( uint8_t* rk,
- uint32_t length,
- uint8_t iv[16],
- const uint8_t *input,
- uint8_t *output )
- {
- int i;
- uint8_t temp[16];
- while( length > 0 )
- {
- memcpy( temp, input, 16 );
- decrypt_ecb( AES_NR, rk, input, output );
- for( i = 0; i < 16; i++ )
- output[i] = (uint8_t)( output[i] ^ iv[i] );
- memcpy( iv, temp, 16 );
- input += 16;
- output += 16;
- length -= 16;
- }
- }
- static void aeshw_init(void)
- {
- #ifdef HAVE_HARDAES
- static int done = 0;
- if (!done) {
- if (aeshw_supported()) {
- encrypt_ecb = aeshw_encrypt_ecb;
- decrypt_ecb = aeshw_decrypt_ecb;
- setkey_enc = aeshw_setkey_enc;
- setkey_dec = aeshw_setkey_dec;
- }
- done = 1;
- }
- #endif
- }
- int AES_support_hwaccel(void)
- {
- #ifdef HAVE_HARDAES
- return aeshw_supported();
- #else
- return 0;
- #endif
- }
- void AES_CBC_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
- {
- uint8_t iv_tmp[16];
- static uint8_t rk[AES_RKSIZE];
- assert(iv!=NULL);
- aeshw_init();
- memcpy(iv_tmp, iv, 16);
- if(key!= NULL)
- setkey_enc(rk, key);
- encrypt_cbc(rk, length, iv_tmp, input, output);
- }
- void AES_CBC_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
- {
- uint8_t iv_tmp[16];
- static uint8_t rk[AES_RKSIZE];
- assert(iv!=NULL);
- aeshw_init();
- memcpy(iv_tmp, iv, 16);
- if(key!= NULL)
- {
- setkey_dec(rk, key);
- }
- decrypt_cbc(rk, length, iv_tmp, input, output);
- }
- void AES_ECB_encrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t* output)
- {
- static uint8_t rk[AES_RKSIZE];
- aeshw_init();
- if(key!=NULL)
- setkey_enc(rk, key);
- encrypt_ecb(AES_NR, rk, input, output);
- }
- void AES_ECB_decrypt_buffer(const uint8_t* input, const uint8_t* key, uint8_t *output)
- {
- static uint8_t rk[AES_RKSIZE];
- aeshw_init();
- if(key!=NULL)
- setkey_dec(rk, key);
- decrypt_ecb(AES_NR, rk, input, output);
- }
- static void encrypt_cfb( uint8_t* rk,
- uint32_t length,size_t *iv_off,
- uint8_t iv[16],
- const uint8_t *input,
- uint8_t *output )
- {
- int c;
- size_t n = *iv_off;
- while( length-- )
- {
- if( n == 0 )
- encrypt_ecb( AES_NR, rk, iv, iv );
- iv[n] = *output++ = (unsigned char)( iv[n] ^ *input++ );
- n = ( n + 1 ) & 0x0F;
- }
- *iv_off = n;
- }
- static void decrypt_cfb( uint8_t* rk,
- uint32_t length,size_t *iv_off,
- uint8_t iv[16],
- const uint8_t *input,
- uint8_t *output )
- {
- int c;
- size_t n = *iv_off;
- while( length-- )
- {
- if( n == 0 )
- encrypt_ecb( AES_NR, rk, iv, iv );
- c = *input++;
- *output++ = (unsigned char)( c ^ iv[n] );
- iv[n] = (unsigned char) c;
- n = ( n + 1 ) & 0x0F;
- }
- *iv_off = n;
- }
- void AES_CFB_encrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
- {
- uint8_t iv_tmp[16];
- static uint8_t rk[AES_RKSIZE];
- assert(iv!=NULL);
- aeshw_init();
- memcpy(iv_tmp, iv, 16);
- if(key!= NULL)
- setkey_enc(rk, key);
- size_t offset=0;
- encrypt_cfb(rk, length,&offset, iv_tmp, input, output);
- }
- void AES_CFB_decrypt_buffer(uint8_t* output, uint8_t* input, uint32_t length, const uint8_t* key, const uint8_t* iv)
- {
- uint8_t iv_tmp[16];
- static uint8_t rk[AES_RKSIZE];
- assert(iv!=NULL);
- aeshw_init();
- memcpy(iv_tmp, iv, 16);
- if(key!= NULL)
- {
- setkey_enc(rk, key);//its enc again,not typo
- }
- size_t offset=0;
- decrypt_cfb(rk, length,&offset, iv_tmp, input, output);
- }
|