diff --git a/src/ciphers/aes/aes.c b/src/ciphers/aes/aes.c index aea8e19..cc9d99f 100644 --- a/src/ciphers/aes/aes.c +++ b/src/ciphers/aes/aes.c @@ -49,7 +49,7 @@ const struct ltc_cipher_descriptor rijndael_desc = 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_desc = @@ -58,7 +58,7 @@ const struct ltc_cipher_descriptor aes_desc = 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #else @@ -74,7 +74,7 @@ const struct ltc_cipher_descriptor rijndael_enc_desc = 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor aes_enc_desc = @@ -83,7 +83,7 @@ const struct ltc_cipher_descriptor aes_enc_desc = 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, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #endif diff --git a/src/ciphers/anubis.c b/src/ciphers/anubis.c index 226a190..c3b3c2f 100644 --- a/src/ciphers/anubis.c +++ b/src/ciphers/anubis.c @@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor anubis_desc = { &anubis_test, &anubis_done, &anubis_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define MIN_N 4 diff --git a/src/ciphers/blowfish.c b/src/ciphers/blowfish.c index cbe6942..9a78733 100644 --- a/src/ciphers/blowfish.c +++ b/src/ciphers/blowfish.c @@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor blowfish_desc = &blowfish_test, &blowfish_done, &blowfish_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 ORIG_P[16 + 2] = { diff --git a/src/ciphers/camellia.c b/src/ciphers/camellia.c index 3497cfa..c152ff7 100644 --- a/src/ciphers/camellia.c +++ b/src/ciphers/camellia.c @@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor camellia_desc = { &camellia_test, &camellia_done, &camellia_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 SP1110[] = { diff --git a/src/ciphers/cast5.c b/src/ciphers/cast5.c index 817ec5a..f4f9154 100644 --- a/src/ciphers/cast5.c +++ b/src/ciphers/cast5.c @@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor cast5_desc = { &cast5_test, &cast5_done, &cast5_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 S1[256] = { diff --git a/src/ciphers/des.c b/src/ciphers/des.c index b706b07..cd343b3 100644 --- a/src/ciphers/des.c +++ b/src/ciphers/des.c @@ -31,7 +31,7 @@ const struct ltc_cipher_descriptor des_desc = &des_test, &des_done, &des_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; const struct ltc_cipher_descriptor des3_desc = @@ -45,7 +45,7 @@ const struct ltc_cipher_descriptor des3_desc = &des3_test, &des3_done, &des3_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 bytebit[8] = diff --git a/src/ciphers/kasumi.c b/src/ciphers/kasumi.c index c611331..61369e0 100644 --- a/src/ciphers/kasumi.c +++ b/src/ciphers/kasumi.c @@ -33,7 +33,7 @@ const struct ltc_cipher_descriptor kasumi_desc = { &kasumi_test, &kasumi_done, &kasumi_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static u16 FI( u16 in, u16 subkey ) diff --git a/src/ciphers/khazad.c b/src/ciphers/khazad.c index 285e8b1..1cea03c 100644 --- a/src/ciphers/khazad.c +++ b/src/ciphers/khazad.c @@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor khazad_desc = { &khazad_test, &khazad_done, &khazad_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; #define R 8 diff --git a/src/ciphers/kseed.c b/src/ciphers/kseed.c index e8f0fa8..003074c 100644 --- a/src/ciphers/kseed.c +++ b/src/ciphers/kseed.c @@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor kseed_desc = { &kseed_test, &kseed_done, &kseed_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 SS0[256] = { diff --git a/src/ciphers/multi2.c b/src/ciphers/multi2.c index 65249a3..d1e4a6c 100644 --- a/src/ciphers/multi2.c +++ b/src/ciphers/multi2.c @@ -116,7 +116,7 @@ const struct ltc_cipher_descriptor multi2_desc = { &multi2_test, &multi2_done, &multi2_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) diff --git a/src/ciphers/noekeon.c b/src/ciphers/noekeon.c index 40c0711..f748d3e 100644 --- a/src/ciphers/noekeon.c +++ b/src/ciphers/noekeon.c @@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor noekeon_desc = &noekeon_test, &noekeon_done, &noekeon_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 RC[] = { diff --git a/src/ciphers/rc2.c b/src/ciphers/rc2.c index 87ccb6d..dbe5696 100644 --- a/src/ciphers/rc2.c +++ b/src/ciphers/rc2.c @@ -36,7 +36,7 @@ const struct ltc_cipher_descriptor rc2_desc = { &rc2_test, &rc2_done, &rc2_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* 256-entry permutation table, probably derived somehow from pi */ diff --git a/src/ciphers/rc5.c b/src/ciphers/rc5.c index b267a5a..bd964e2 100644 --- a/src/ciphers/rc5.c +++ b/src/ciphers/rc5.c @@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor rc5_desc = &rc5_test, &rc5_done, &rc5_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[50] = { diff --git a/src/ciphers/rc6.c b/src/ciphers/rc6.c index 611c00c..48d413d 100644 --- a/src/ciphers/rc6.c +++ b/src/ciphers/rc6.c @@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor rc6_desc = &rc6_test, &rc6_done, &rc6_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const ulong32 stab[44] = { diff --git a/src/ciphers/safer/safer.c b/src/ciphers/safer/safer.c index 434a7db..865eee3 100644 --- a/src/ciphers/safer/safer.c +++ b/src/ciphers/safer/safer.c @@ -45,7 +45,7 @@ const struct ltc_cipher_descriptor &safer_k64_test, &safer_done, &safer_64_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk64_desc = { @@ -57,7 +57,7 @@ const struct ltc_cipher_descriptor &safer_sk64_test, &safer_done, &safer_64_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_k128_desc = { @@ -69,7 +69,7 @@ const struct ltc_cipher_descriptor &safer_sk128_test, &safer_done, &safer_128_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }, safer_sk128_desc = { @@ -81,7 +81,7 @@ const struct ltc_cipher_descriptor &safer_sk128_test, &safer_done, &safer_128_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /******************* Constants ************************************************/ diff --git a/src/ciphers/safer/saferp.c b/src/ciphers/safer/saferp.c index 27580b8..e5f8bf3 100644 --- a/src/ciphers/safer/saferp.c +++ b/src/ciphers/safer/saferp.c @@ -31,7 +31,7 @@ const struct ltc_cipher_descriptor saferp_desc = &saferp_test, &saferp_done, &saferp_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* ROUND(b,i) diff --git a/src/ciphers/skipjack.c b/src/ciphers/skipjack.c index 9b2e101..4333a9f 100644 --- a/src/ciphers/skipjack.c +++ b/src/ciphers/skipjack.c @@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor skipjack_desc = &skipjack_test, &skipjack_done, &skipjack_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; static const unsigned char sbox[256] = { diff --git a/src/ciphers/twofish/twofish.c b/src/ciphers/twofish/twofish.c index be6c7d5..b443a7c 100644 --- a/src/ciphers/twofish/twofish.c +++ b/src/ciphers/twofish/twofish.c @@ -35,7 +35,7 @@ const struct ltc_cipher_descriptor twofish_desc = &twofish_test, &twofish_done, &twofish_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; /* the two polynomials */ diff --git a/src/ciphers/xtea.c b/src/ciphers/xtea.c index 963824d..4b3b52b 100644 --- a/src/ciphers/xtea.c +++ b/src/ciphers/xtea.c @@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor xtea_desc = &xtea_test, &xtea_done, &xtea_keysize, - NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }; int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) diff --git a/src/headers/tomcrypt_cipher.h b/src/headers/tomcrypt_cipher.h index edf25c0..da3a6b7 100644 --- a/src/headers/tomcrypt_cipher.h +++ b/src/headers/tomcrypt_cipher.h @@ -553,6 +553,36 @@ extern struct ltc_cipher_descriptor { const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen); + + /** Accelerated XTS encryption + @param pt Plaintext + @param ct Ciphertext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_encrypt)(const unsigned char *pt, unsigned char *ct, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); + + /** Accelerated XTS decryption + @param ct Ciphertext + @param pt Plaintext + @param blocks The number of complete blocks to process + @param tweak The 128-bit encryption tweak (input/output). + The tweak should not be encrypted on input, but + next tweak will be copied encrypted on output. + @param skey1 The first scheduled key context + @param skey2 The second scheduled key context + @return CRYPT_OK if successful + */ + int (*accel_xts_decrypt)(const unsigned char *ct, unsigned char *pt, + unsigned long blocks, unsigned char *tweak, symmetric_key *skey1, + symmetric_key *skey2); } cipher_descriptor[]; #ifdef LTC_BLOWFISH diff --git a/src/misc/crypt/crypt_cipher_descriptor.c b/src/misc/crypt/crypt_cipher_descriptor.c index 20aac57..2e35787 100644 --- a/src/misc/crypt/crypt_cipher_descriptor.c +++ b/src/misc/crypt/crypt_cipher_descriptor.c @@ -16,7 +16,7 @@ */ struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = { -{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } +{ NULL, 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL } }; LTC_MUTEX_GLOBAL(ltc_cipher_mutex) diff --git a/src/modes/xts/xts_decrypt.c b/src/modes/xts/xts_decrypt.c index f73770d..6afe936 100644 --- a/src/modes/xts/xts_decrypt.c +++ b/src/modes/xts/xts_decrypt.c @@ -10,9 +10,9 @@ */ #include "tomcrypt.h" -/** - Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects -*/ +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects + */ #ifdef LTC_XTS_MODE @@ -24,23 +24,23 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char /* tweak encrypt block i */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { - *((LTC_FAST_TYPE*)&P[x]) = *((LTC_FAST_TYPE*)&C[x]) ^ *((LTC_FAST_TYPE*)&T[x]); + *((LTC_FAST_TYPE *)&P[x]) = *((LTC_FAST_TYPE *)&C[x]) ^ *((LTC_FAST_TYPE *)&T[x]); } #else for (x = 0; x < 16; x++) { - P[x] = C[x] ^ T[x]; + P[x] = C[x] ^ T[x]; } #endif - - err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1); + + err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1); #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { - *((LTC_FAST_TYPE*)&P[x]) ^= *((LTC_FAST_TYPE*)&T[x]); + *((LTC_FAST_TYPE *)&P[x]) ^= *((LTC_FAST_TYPE *)&T[x]); } #else for (x = 0; x < 16; x++) { - P[x] = P[x] ^ T[x]; + P[x] = P[x] ^ T[x]; } #endif @@ -48,30 +48,28 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char xts_mult_x(T); return err; -} +} /** XTS Decryption - @param ct [in] Ciphertext - @param ptlen Length of plaintext (and ciphertext) - @param pt [out] Plaintext - @param tweak [in] The 128--bit encryption tweak (e.g. sector number) - @param xts The XTS structure - Returns CRYPT_OK upon success -*/int xts_decrypt( - const unsigned char *ct, unsigned long ptlen, - unsigned char *pt, - unsigned char *tweak, - symmetric_xts *xts) + @param ct [in] Ciphertext + @param ptlen Length of plaintext (and ciphertext) + @param pt [out] Plaintext + @param tweak [in] The 128--bit encryption tweak (e.g. sector number) + @param xts The XTS structure + Returns CRYPT_OK upon success + */ +int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak, + symmetric_xts *xts) { unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; - int err; + int err; /* check inputs */ - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tweak != NULL); - LTC_ARGCHK(xts != NULL); + LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { @@ -79,7 +77,7 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char } /* get number of blocks */ - m = ptlen >> 4; + m = ptlen >> 4; mo = ptlen & 15; /* must have at least one full block */ @@ -87,24 +85,37 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char return CRYPT_INVALID_ARG; } - /* encrypt the tweak */ - if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { - return err; - } - - /* for i = 0 to m-2 do */ if (mo == 0) { lim = m; } else { lim = m - 1; } - for (i = 0; i < lim; i++) { - err = tweak_uncrypt(ct, pt, T, xts); - ct += 16; - pt += 16; + if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) { + + /* use accelerated decryption for whole blocks */ + if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2) != + CRYPT_OK)) { + return err; + } + ct += lim * 16; + pt += lim * 16; + + /* tweak is encrypted on output */ + XMEMCPY(T, tweak, sizeof(T)); + } else { + /* encrypt the tweak */ + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { + return err; + } + + for (i = 0; i < lim; i++) { + err = tweak_uncrypt(ct, pt, T, xts); + ct += 16; + pt += 16; + } } - + /* if ptlen not divide 16 then */ if (mo > 0) { XMEMCPY(CC, T, 16); @@ -117,11 +128,11 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char /* Pm = first ptlen % 16 bytes of PP */ for (i = 0; i < mo; i++) { - CC[i] = ct[16+i]; - pt[16+i] = PP[i]; + CC[i] = ct[16 + i]; + pt[16 + i] = PP[i]; } for (; i < 16; i++) { - CC[i] = PP[i]; + CC[i] = PP[i]; } /* Pm-1 = Tweak uncrypt CC */ @@ -143,4 +154,3 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char /* $Source$ */ /* $Revision$ */ /* $Date$ */ - diff --git a/src/modes/xts/xts_done.c b/src/modes/xts/xts_done.c index 7c04277..a7a85ed 100644 --- a/src/modes/xts/xts_done.c +++ b/src/modes/xts/xts_done.c @@ -10,13 +10,13 @@ */ #include "tomcrypt.h" -/** +/** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE -/** Terminate XTS state +/** Terminate XTS state @param XTS The state to terminate */ void xts_done(symmetric_xts *xts) @@ -31,4 +31,3 @@ void xts_done(symmetric_xts *xts) /* $Source$ */ /* $Revision$ */ /* $Date$ */ - diff --git a/src/modes/xts/xts_encrypt.c b/src/modes/xts/xts_encrypt.c index 6474b13..4f114d7 100644 --- a/src/modes/xts/xts_encrypt.c +++ b/src/modes/xts/xts_encrypt.c @@ -10,9 +10,9 @@ */ #include "tomcrypt.h" -/** - Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects -*/ +/** + Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects + */ #ifdef LTC_XTS_MODE @@ -24,25 +24,25 @@ static int tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char * /* tweak encrypt block i */ #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { - *((LTC_FAST_TYPE*)&C[x]) = *((LTC_FAST_TYPE*)&P[x]) ^ *((LTC_FAST_TYPE*)&T[x]); + *((LTC_FAST_TYPE *)&C[x]) = *((LTC_FAST_TYPE *)&P[x]) ^ *((LTC_FAST_TYPE *)&T[x]); } #else for (x = 0; x < 16; x++) { C[x] = P[x] ^ T[x]; } #endif - + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) { return err; } #ifdef LTC_FAST for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { - *((LTC_FAST_TYPE*)&C[x]) ^= *((LTC_FAST_TYPE*)&T[x]); + *((LTC_FAST_TYPE *)&C[x]) ^= *((LTC_FAST_TYPE *)&T[x]); } #else for (x = 0; x < 16; x++) { - C[x] = C[x] ^ T[x]; + C[x] = C[x] ^ T[x]; } #endif @@ -50,31 +50,28 @@ static int tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char * xts_mult_x(T); return CRYPT_OK; -} +} /** XTS Encryption - @param pt [in] Plaintext - @param ptlen Length of plaintext (and ciphertext) - @param ct [out] Ciphertext - @param tweak [in] The 128--bit encryption tweak (e.g. sector number) - @param xts The XTS structure - Returns CRYPT_OK upon success -*/ -int xts_encrypt( - const unsigned char *pt, unsigned long ptlen, - unsigned char *ct, - unsigned char *tweak, - symmetric_xts *xts) + @param pt [in] Plaintext + @param ptlen Length of plaintext (and ciphertext) + @param ct [out] Ciphertext + @param tweak [in] The 128--bit encryption tweak (e.g. sector number) + @param xts The XTS structure + Returns CRYPT_OK upon success + */ +int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tweak, + symmetric_xts *xts) { unsigned char PP[16], CC[16], T[16]; unsigned long i, m, mo, lim; - int err; + int err; /* check inputs */ - LTC_ARGCHK(pt != NULL); - LTC_ARGCHK(ct != NULL); + LTC_ARGCHK(pt != NULL); + LTC_ARGCHK(ct != NULL); LTC_ARGCHK(tweak != NULL); - LTC_ARGCHK(xts != NULL); + LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { @@ -82,32 +79,46 @@ int xts_encrypt( } /* get number of blocks */ - m = ptlen >> 4; + m = ptlen >> 4; mo = ptlen & 15; - /* must have at least one full block */ + /* must have at least one full block */ if (m == 0) { return CRYPT_INVALID_ARG; } - /* encrypt the tweak */ - if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { - return err; - } - - /* for i = 0 to m-2 do */ if (mo == 0) { lim = m; } else { lim = m - 1; } - for (i = 0; i < lim; i++) { - err = tweak_crypt(pt, ct, T, xts); - ct += 16; - pt += 16; + if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) { + + /* use accelerated encryption for whole blocks */ + if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1, &xts->key2) != + CRYPT_OK)) { + return err; + } + ct += lim * 16; + pt += lim * 16; + + /* tweak is encrypted on output */ + XMEMCPY(T, tweak, sizeof(T)); + } else { + + /* encrypt the tweak */ + if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) { + return err; + } + + for (i = 0; i < lim; i++) { + err = tweak_crypt(pt, ct, T, xts); + ct += 16; + pt += 16; + } } - + /* if ptlen not divide 16 then */ if (mo > 0) { /* CC = tweak encrypt block m-1 */ @@ -117,12 +128,12 @@ int xts_encrypt( /* Cm = first ptlen % 16 bytes of CC */ for (i = 0; i < mo; i++) { - PP[i] = pt[16+i]; - ct[16+i] = CC[i]; + PP[i] = pt[16 + i]; + ct[16 + i] = CC[i]; } for (; i < 16; i++) { - PP[i] = CC[i]; + PP[i] = CC[i]; } /* Cm-1 = Tweak encrypt PP */ @@ -144,4 +155,3 @@ int xts_encrypt( /* $Source$ */ /* $Revision$ */ /* $Date$ */ - diff --git a/src/modes/xts/xts_init.c b/src/modes/xts/xts_init.c index f38c01e..687596e 100644 --- a/src/modes/xts/xts_init.c +++ b/src/modes/xts/xts_init.c @@ -10,13 +10,12 @@ */ #include "tomcrypt.h" -/** +/** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE - /** Start XTS mode @param cipher The index of the cipher to use @param key1 The encrypt key @@ -26,19 +25,15 @@ @param xts [out] XTS structure Returns CRYPT_OK upon success. */ -int xts_start( int cipher, - const unsigned char *key1, - const unsigned char *key2, - unsigned long keylen, - int num_rounds, - symmetric_xts *xts) +int xts_start(int cipher, const unsigned char *key1, const unsigned char *key2, unsigned long keylen, int num_rounds, + symmetric_xts *xts) { int err; /* check inputs */ - LTC_ARGCHK(key1 != NULL); - LTC_ARGCHK(key2 != NULL); - LTC_ARGCHK(xts != NULL); + LTC_ARGCHK(key1 != NULL); + LTC_ARGCHK(key2 != NULL); + LTC_ARGCHK(xts != NULL); /* check if valid */ if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { @@ -66,4 +61,3 @@ int xts_start( int cipher, /* $Source$ */ /* $Revision$ */ /* $Date$ */ - diff --git a/src/modes/xts/xts_mult_x.c b/src/modes/xts/xts_mult_x.c index e5b7c11..c1eecef 100644 --- a/src/modes/xts/xts_mult_x.c +++ b/src/modes/xts/xts_mult_x.c @@ -10,28 +10,28 @@ */ #include "tomcrypt.h" -/** +/** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects */ #ifdef LTC_XTS_MODE -/** multiply by x +/** multiply by x @param I The value to multiply by x (LFSR shift) */ void xts_mult_x(unsigned char *I) { - int x; - unsigned char t, tt; + int x; + unsigned char t, tt; - for (x = t = 0; x < 16; x++) { - tt = I[x] >> 7; - I[x] = ((I[x] << 1) | t) & 0xFF; - t = tt; - } - if (tt) { - I[0] ^= 0x87; - } + for (x = t = 0; x < 16; x++) { + tt = I[x] >> 7; + I[x] = ((I[x] << 1) | t) & 0xFF; + t = tt; + } + if (tt) { + I[0] ^= 0x87; + } } #endif @@ -39,4 +39,3 @@ void xts_mult_x(unsigned char *I) /* $Source$ */ /* $Revision$ */ /* $Date$ */ - diff --git a/src/modes/xts/xts_test.c b/src/modes/xts/xts_test.c index 8b9cd4f..e274eb0 100644 --- a/src/modes/xts/xts_test.c +++ b/src/modes/xts/xts_test.c @@ -12,8 +12,57 @@ #ifdef LTC_XTS_MODE +static int _xts_test_accel_xts_encrypt(const unsigned char *pt, unsigned char *ct, unsigned long blocks, + unsigned char *tweak, symmetric_key *skey1, symmetric_key *skey2) +{ + int ret; + symmetric_xts xts; + + /* AES can be under rijndael or aes... try to find it */ + if ((xts.cipher = find_cipher("aes")) == -1) { + if ((xts.cipher = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + void *orig = cipher_descriptor[xts.cipher].accel_xts_encrypt; + cipher_descriptor[xts.cipher].accel_xts_encrypt = NULL; + + XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key)); + XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key)); + + ret = xts_encrypt(pt, blocks << 4, ct, tweak, &xts); + cipher_descriptor[xts.cipher].accel_xts_encrypt = orig; + + return ret; +} + +static int _xts_test_accel_xts_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long blocks, + unsigned char *tweak, symmetric_key *skey1, symmetric_key *skey2) +{ + int ret; + symmetric_xts xts; + + /* AES can be under rijndael or aes... try to find it */ + if ((xts.cipher = find_cipher("aes")) == -1) { + if ((xts.cipher = find_cipher("rijndael")) == -1) { + return CRYPT_NOP; + } + } + void *orig = cipher_descriptor[xts.cipher].accel_xts_decrypt; + cipher_descriptor[xts.cipher].accel_xts_decrypt = NULL; + + XMEMCPY(&xts.key1, skey1, sizeof(symmetric_key)); + XMEMCPY(&xts.key2, skey2, sizeof(symmetric_key)); + + ret = xts_decrypt(ct, blocks << 4, pt, tweak, &xts); + cipher_descriptor[xts.cipher].accel_xts_decrypt = orig; + + return ret; +} + /** Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects + Returns CRYPT_OK upon success. */ int xts_test(void) @@ -21,7 +70,8 @@ int xts_test(void) #ifdef LTC_NO_TEST return CRYPT_NOP; #else - static const struct { + static const struct + { int keylen; unsigned char key1[32]; unsigned char key2[32]; @@ -143,9 +193,9 @@ int xts_test(void) }; unsigned char OUT[512], Torg[16], T[16]; - ulong64 seq; + ulong64 seq; symmetric_xts xts; - int i, j, err, idx; + int i, j, k, err, idx; unsigned long len; /* AES can be under rijndael or aes... try to find it */ @@ -154,91 +204,103 @@ int xts_test(void) return CRYPT_NOP; } } + for (k = 0; k < 4; ++k) { + cipher_descriptor[idx].accel_xts_encrypt = NULL; + cipher_descriptor[idx].accel_xts_decrypt = NULL; + if (k & 0x1) { + cipher_descriptor[idx].accel_xts_encrypt = _xts_test_accel_xts_encrypt; + } + if (k & 0x2) { + cipher_descriptor[idx].accel_xts_decrypt = _xts_test_accel_xts_decrypt; + } + for (j = 0; j < 2; j++) { + for (i = 0; i < (int)(sizeof(tests) / sizeof(tests[0])); i++) { + /* skip the cases where + * the length is smaller than 2*blocklen + * or the length is not a multiple of 32 + */ + if ((j == 1) && ((tests[i].PTLEN < 32) || (tests[i].PTLEN % 32))) { + continue; + } + if ((k > 0) && (j == 1)) { + continue; + } + len = tests[i].PTLEN / 2; - for (j = 0; j < 2; j++) { - for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { - /* skip the cases where - * the length is smaller than 2*blocklen - * or the length is not a multiple of 32 - */ - if ((j == 1) && ((tests[i].PTLEN < 32) || (tests[i].PTLEN % 32))) { - continue; - } - len = tests[i].PTLEN/2; + err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen / 2, 0, &xts); + if (err != CRYPT_OK) { + return err; + } - err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen/2, 0, &xts); - if (err != CRYPT_OK) { - return err; - } + seq = tests[i].seqnum; + STORE64L(seq, Torg); + XMEMSET(Torg + 8, 0, 8); - seq = tests[i].seqnum; - STORE64L(seq,Torg); - XMEMSET(Torg+8, 0, 8); + XMEMCPY(T, Torg, sizeof(T)); + if (j == 0) { + err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + } else { + err = xts_encrypt(tests[i].PTX, len, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + err = xts_encrypt(&tests[i].PTX[len], len, &OUT[len], T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + } - XMEMCPY(T, Torg, sizeof(T)); - if (j == 0) { - err = xts_encrypt(tests[i].PTX, tests[i].PTLEN, OUT, T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - } - else { - err = xts_encrypt(tests[i].PTX, len, OUT, T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - err = xts_encrypt(&tests[i].PTX[len], len, &OUT[len], T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - } - - if (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) { + if (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) { #ifdef LTC_TEST_DBG - printf("\nTestcase #%d with original length %lu and half of it %lu\n", i, tests[i].PTLEN, len); - printf("\nencrypt\n"); - print_hex("should", tests[i].CTX, tests[i].PTLEN); - print_hex("is", OUT, tests[i].PTLEN); + printf("\nTestcase #%d with original length %lu and half of it " + "%lu\n", + i, tests[i].PTLEN, len); + printf("\nencrypt\n"); + print_hex("should", tests[i].CTX, tests[i].PTLEN); + print_hex("is", OUT, tests[i].PTLEN); #endif - xts_done(&xts); - return CRYPT_FAIL_TESTVECTOR; - } + xts_done(&xts); + return CRYPT_FAIL_TESTVECTOR; + } - XMEMCPY(T, Torg, sizeof(T)); - if (j == 0) { - err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - } - else { - err = xts_decrypt(tests[i].CTX, len, OUT, T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - err = xts_decrypt(&tests[i].CTX[len], len, &OUT[len], T, &xts); - if (err != CRYPT_OK) { - xts_done(&xts); - return err; - } - } + XMEMCPY(T, Torg, sizeof(T)); + if (j == 0) { + err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + } else { + err = xts_decrypt(tests[i].CTX, len, OUT, T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + err = xts_decrypt(&tests[i].CTX[len], len, &OUT[len], T, &xts); + if (err != CRYPT_OK) { + xts_done(&xts); + return err; + } + } - if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { + if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { #ifdef LTC_TEST_DBG - printf("\ndecrypt\n"); - print_hex("should", tests[i].PTX, tests[i].PTLEN); - print_hex("is", OUT, tests[i].PTLEN); + printf("\ndecrypt\n"); + print_hex("should", tests[i].PTX, tests[i].PTLEN); + print_hex("is", OUT, tests[i].PTLEN); #endif + xts_done(&xts); + return CRYPT_FAIL_TESTVECTOR; + } xts_done(&xts); - return CRYPT_FAIL_TESTVECTOR; } - xts_done(&xts); - } + } } return CRYPT_OK; #endif @@ -249,4 +311,3 @@ int xts_test(void) /* $Source$ */ /* $Revision$ */ /* $Date$ */ -