Merge branch 'aes-xts-accel' into develop

This fixes #70
This commit is contained in:
Steffen Jaeckel 2015-08-26 00:05:31 +02:00
commit 38bfef2996
27 changed files with 317 additions and 214 deletions

View File

@ -49,7 +49,7 @@ const struct ltc_cipher_descriptor rijndael_desc =
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, 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 = const struct ltc_cipher_descriptor aes_desc =
@ -58,7 +58,7 @@ const struct ltc_cipher_descriptor aes_desc =
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS, 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 #else
@ -74,7 +74,7 @@ const struct ltc_cipher_descriptor rijndael_enc_desc =
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, 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 = const struct ltc_cipher_descriptor aes_enc_desc =
@ -83,7 +83,7 @@ const struct ltc_cipher_descriptor aes_enc_desc =
6, 6,
16, 32, 16, 10, 16, 32, 16, 10,
SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS, 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 #endif

View File

@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor anubis_desc = {
&anubis_test, &anubis_test,
&anubis_done, &anubis_done,
&anubis_keysize, &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 #define MIN_N 4

View File

@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor blowfish_desc =
&blowfish_test, &blowfish_test,
&blowfish_done, &blowfish_done,
&blowfish_keysize, &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] = { static const ulong32 ORIG_P[16 + 2] = {

View File

@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor camellia_desc = {
&camellia_test, &camellia_test,
&camellia_done, &camellia_done,
&camellia_keysize, &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[] = { static const ulong32 SP1110[] = {

View File

@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor cast5_desc = {
&cast5_test, &cast5_test,
&cast5_done, &cast5_done,
&cast5_keysize, &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] = { static const ulong32 S1[256] = {

View File

@ -31,7 +31,7 @@ const struct ltc_cipher_descriptor des_desc =
&des_test, &des_test,
&des_done, &des_done,
&des_keysize, &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 = const struct ltc_cipher_descriptor des3_desc =
@ -45,7 +45,7 @@ const struct ltc_cipher_descriptor des3_desc =
&des3_test, &des3_test,
&des3_done, &des3_done,
&des3_keysize, &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] = static const ulong32 bytebit[8] =

View File

@ -33,7 +33,7 @@ const struct ltc_cipher_descriptor kasumi_desc = {
&kasumi_test, &kasumi_test,
&kasumi_done, &kasumi_done,
&kasumi_keysize, &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 ) static u16 FI( u16 in, u16 subkey )

View File

@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor khazad_desc = {
&khazad_test, &khazad_test,
&khazad_done, &khazad_done,
&khazad_keysize, &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 #define R 8

View File

@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor kseed_desc = {
&kseed_test, &kseed_test,
&kseed_done, &kseed_done,
&kseed_keysize, &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] = { static const ulong32 SS0[256] = {

View File

@ -116,7 +116,7 @@ const struct ltc_cipher_descriptor multi2_desc = {
&multi2_test, &multi2_test,
&multi2_done, &multi2_done,
&multi2_keysize, &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) int multi2_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)

View File

@ -27,7 +27,7 @@ const struct ltc_cipher_descriptor noekeon_desc =
&noekeon_test, &noekeon_test,
&noekeon_done, &noekeon_done,
&noekeon_keysize, &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[] = { static const ulong32 RC[] = {

View File

@ -36,7 +36,7 @@ const struct ltc_cipher_descriptor rc2_desc = {
&rc2_test, &rc2_test,
&rc2_done, &rc2_done,
&rc2_keysize, &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 */ /* 256-entry permutation table, probably derived somehow from pi */

View File

@ -29,7 +29,7 @@ const struct ltc_cipher_descriptor rc5_desc =
&rc5_test, &rc5_test,
&rc5_done, &rc5_done,
&rc5_keysize, &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] = { static const ulong32 stab[50] = {

View File

@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor rc6_desc =
&rc6_test, &rc6_test,
&rc6_done, &rc6_done,
&rc6_keysize, &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] = { static const ulong32 stab[44] = {

View File

@ -45,7 +45,7 @@ const struct ltc_cipher_descriptor
&safer_k64_test, &safer_k64_test,
&safer_done, &safer_done,
&safer_64_keysize, &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 = { safer_sk64_desc = {
@ -57,7 +57,7 @@ const struct ltc_cipher_descriptor
&safer_sk64_test, &safer_sk64_test,
&safer_done, &safer_done,
&safer_64_keysize, &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 = { safer_k128_desc = {
@ -69,7 +69,7 @@ const struct ltc_cipher_descriptor
&safer_sk128_test, &safer_sk128_test,
&safer_done, &safer_done,
&safer_128_keysize, &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 = { safer_sk128_desc = {
@ -81,7 +81,7 @@ const struct ltc_cipher_descriptor
&safer_sk128_test, &safer_sk128_test,
&safer_done, &safer_done,
&safer_128_keysize, &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 ************************************************/ /******************* Constants ************************************************/

View File

@ -31,7 +31,7 @@ const struct ltc_cipher_descriptor saferp_desc =
&saferp_test, &saferp_test,
&saferp_done, &saferp_done,
&saferp_keysize, &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) /* ROUND(b,i)

View File

@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor skipjack_desc =
&skipjack_test, &skipjack_test,
&skipjack_done, &skipjack_done,
&skipjack_keysize, &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] = { static const unsigned char sbox[256] = {

View File

@ -35,7 +35,7 @@ const struct ltc_cipher_descriptor twofish_desc =
&twofish_test, &twofish_test,
&twofish_done, &twofish_done,
&twofish_keysize, &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 */ /* the two polynomials */

View File

@ -28,7 +28,7 @@ const struct ltc_cipher_descriptor xtea_desc =
&xtea_test, &xtea_test,
&xtea_done, &xtea_done,
&xtea_keysize, &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) int xtea_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)

View File

@ -553,6 +553,36 @@ extern struct ltc_cipher_descriptor {
const unsigned char *key, unsigned long keylen, const unsigned char *key, unsigned long keylen,
const unsigned char *in, unsigned long inlen, const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen); 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[]; } cipher_descriptor[];
#ifdef LTC_BLOWFISH #ifdef LTC_BLOWFISH

View File

@ -16,7 +16,7 @@
*/ */
struct ltc_cipher_descriptor cipher_descriptor[TAB_SIZE] = { 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) LTC_MUTEX_GLOBAL(ltc_cipher_mutex)

View File

@ -10,9 +10,9 @@
*/ */
#include "tomcrypt.h" #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 #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 */ /* tweak encrypt block i */
#ifdef LTC_FAST #ifdef LTC_FAST
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { 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 #else
for (x = 0; x < 16; x++) { for (x = 0; x < 16; x++) {
P[x] = C[x] ^ T[x]; P[x] = C[x] ^ T[x];
} }
#endif #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 #ifdef LTC_FAST
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { 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 #else
for (x = 0; x < 16; x++) { for (x = 0; x < 16; x++) {
P[x] = P[x] ^ T[x]; P[x] = P[x] ^ T[x];
} }
#endif #endif
@ -48,30 +48,28 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char
xts_mult_x(T); xts_mult_x(T);
return err; return err;
} }
/** XTS Decryption /** XTS Decryption
@param ct [in] Ciphertext @param ct [in] Ciphertext
@param ptlen Length of plaintext (and ciphertext) @param ptlen Length of plaintext (and ciphertext)
@param pt [out] Plaintext @param pt [out] Plaintext
@param tweak [in] The 128--bit encryption tweak (e.g. sector number) @param tweak [in] The 128--bit encryption tweak (e.g. sector number)
@param xts The XTS structure @param xts The XTS structure
Returns CRYPT_OK upon success Returns CRYPT_OK upon success
*/int xts_decrypt( */
const unsigned char *ct, unsigned long ptlen, int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak,
unsigned char *pt, symmetric_xts *xts)
unsigned char *tweak,
symmetric_xts *xts)
{ {
unsigned char PP[16], CC[16], T[16]; unsigned char PP[16], CC[16], T[16];
unsigned long i, m, mo, lim; unsigned long i, m, mo, lim;
int err; int err;
/* check inputs */ /* check inputs */
LTC_ARGCHK(pt != NULL); LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tweak != NULL); LTC_ARGCHK(tweak != NULL);
LTC_ARGCHK(xts != NULL); LTC_ARGCHK(xts != NULL);
/* check if valid */ /* check if valid */
if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { 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 */ /* get number of blocks */
m = ptlen >> 4; m = ptlen >> 4;
mo = ptlen & 15; mo = ptlen & 15;
/* must have at least one full block */ /* 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; 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) { if (mo == 0) {
lim = m; lim = m;
} else { } else {
lim = m - 1; lim = m - 1;
} }
for (i = 0; i < lim; i++) { if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) {
err = tweak_uncrypt(ct, pt, T, xts);
ct += 16; /* use accelerated decryption for whole blocks */
pt += 16; 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 ptlen not divide 16 then */
if (mo > 0) { if (mo > 0) {
XMEMCPY(CC, T, 16); 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 */ /* Pm = first ptlen % 16 bytes of PP */
for (i = 0; i < mo; i++) { for (i = 0; i < mo; i++) {
CC[i] = ct[16+i]; CC[i] = ct[16 + i];
pt[16+i] = PP[i]; pt[16 + i] = PP[i];
} }
for (; i < 16; i++) { for (; i < 16; i++) {
CC[i] = PP[i]; CC[i] = PP[i];
} }
/* Pm-1 = Tweak uncrypt CC */ /* Pm-1 = Tweak uncrypt CC */
@ -143,4 +154,3 @@ static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */

View File

@ -10,13 +10,13 @@
*/ */
#include "tomcrypt.h" #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 #ifdef LTC_XTS_MODE
/** Terminate XTS state /** Terminate XTS state
@param XTS The state to terminate @param XTS The state to terminate
*/ */
void xts_done(symmetric_xts *xts) void xts_done(symmetric_xts *xts)
@ -31,4 +31,3 @@ void xts_done(symmetric_xts *xts)
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */

View File

@ -10,9 +10,9 @@
*/ */
#include "tomcrypt.h" #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 #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 */ /* tweak encrypt block i */
#ifdef LTC_FAST #ifdef LTC_FAST
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { 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 #else
for (x = 0; x < 16; x++) { for (x = 0; x < 16; x++) {
C[x] = P[x] ^ T[x]; C[x] = P[x] ^ T[x];
} }
#endif #endif
if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) { if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) {
return err; return err;
} }
#ifdef LTC_FAST #ifdef LTC_FAST
for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) { 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 #else
for (x = 0; x < 16; x++) { for (x = 0; x < 16; x++) {
C[x] = C[x] ^ T[x]; C[x] = C[x] ^ T[x];
} }
#endif #endif
@ -50,31 +50,28 @@ static int tweak_crypt(const unsigned char *P, unsigned char *C, unsigned char *
xts_mult_x(T); xts_mult_x(T);
return CRYPT_OK; return CRYPT_OK;
} }
/** XTS Encryption /** XTS Encryption
@param pt [in] Plaintext @param pt [in] Plaintext
@param ptlen Length of plaintext (and ciphertext) @param ptlen Length of plaintext (and ciphertext)
@param ct [out] Ciphertext @param ct [out] Ciphertext
@param tweak [in] The 128--bit encryption tweak (e.g. sector number) @param tweak [in] The 128--bit encryption tweak (e.g. sector number)
@param xts The XTS structure @param xts The XTS structure
Returns CRYPT_OK upon success Returns CRYPT_OK upon success
*/ */
int xts_encrypt( int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tweak,
const unsigned char *pt, unsigned long ptlen, symmetric_xts *xts)
unsigned char *ct,
unsigned char *tweak,
symmetric_xts *xts)
{ {
unsigned char PP[16], CC[16], T[16]; unsigned char PP[16], CC[16], T[16];
unsigned long i, m, mo, lim; unsigned long i, m, mo, lim;
int err; int err;
/* check inputs */ /* check inputs */
LTC_ARGCHK(pt != NULL); LTC_ARGCHK(pt != NULL);
LTC_ARGCHK(ct != NULL); LTC_ARGCHK(ct != NULL);
LTC_ARGCHK(tweak != NULL); LTC_ARGCHK(tweak != NULL);
LTC_ARGCHK(xts != NULL); LTC_ARGCHK(xts != NULL);
/* check if valid */ /* check if valid */
if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {
@ -82,32 +79,46 @@ int xts_encrypt(
} }
/* get number of blocks */ /* get number of blocks */
m = ptlen >> 4; m = ptlen >> 4;
mo = ptlen & 15; mo = ptlen & 15;
/* must have at least one full block */ /* must have at least one full block */
if (m == 0) { if (m == 0) {
return CRYPT_INVALID_ARG; 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) { if (mo == 0) {
lim = m; lim = m;
} else { } else {
lim = m - 1; lim = m - 1;
} }
for (i = 0; i < lim; i++) { if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) {
err = tweak_crypt(pt, ct, T, xts);
ct += 16; /* use accelerated encryption for whole blocks */
pt += 16; 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 ptlen not divide 16 then */
if (mo > 0) { if (mo > 0) {
/* CC = tweak encrypt block m-1 */ /* CC = tweak encrypt block m-1 */
@ -117,12 +128,12 @@ int xts_encrypt(
/* Cm = first ptlen % 16 bytes of CC */ /* Cm = first ptlen % 16 bytes of CC */
for (i = 0; i < mo; i++) { for (i = 0; i < mo; i++) {
PP[i] = pt[16+i]; PP[i] = pt[16 + i];
ct[16+i] = CC[i]; ct[16 + i] = CC[i];
} }
for (; i < 16; i++) { for (; i < 16; i++) {
PP[i] = CC[i]; PP[i] = CC[i];
} }
/* Cm-1 = Tweak encrypt PP */ /* Cm-1 = Tweak encrypt PP */
@ -144,4 +155,3 @@ int xts_encrypt(
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */

View File

@ -10,13 +10,12 @@
*/ */
#include "tomcrypt.h" #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 #ifdef LTC_XTS_MODE
/** Start XTS mode /** Start XTS mode
@param cipher The index of the cipher to use @param cipher The index of the cipher to use
@param key1 The encrypt key @param key1 The encrypt key
@ -26,19 +25,15 @@
@param xts [out] XTS structure @param xts [out] XTS structure
Returns CRYPT_OK upon success. Returns CRYPT_OK upon success.
*/ */
int xts_start( int cipher, int xts_start(int cipher, const unsigned char *key1, const unsigned char *key2, unsigned long keylen, int num_rounds,
const unsigned char *key1, symmetric_xts *xts)
const unsigned char *key2,
unsigned long keylen,
int num_rounds,
symmetric_xts *xts)
{ {
int err; int err;
/* check inputs */ /* check inputs */
LTC_ARGCHK(key1 != NULL); LTC_ARGCHK(key1 != NULL);
LTC_ARGCHK(key2 != NULL); LTC_ARGCHK(key2 != NULL);
LTC_ARGCHK(xts != NULL); LTC_ARGCHK(xts != NULL);
/* check if valid */ /* check if valid */
if ((err = cipher_is_valid(cipher)) != CRYPT_OK) { if ((err = cipher_is_valid(cipher)) != CRYPT_OK) {
@ -66,4 +61,3 @@ int xts_start( int cipher,
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */

View File

@ -10,28 +10,28 @@
*/ */
#include "tomcrypt.h" #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 #ifdef LTC_XTS_MODE
/** multiply by x /** multiply by x
@param I The value to multiply by x (LFSR shift) @param I The value to multiply by x (LFSR shift)
*/ */
void xts_mult_x(unsigned char *I) void xts_mult_x(unsigned char *I)
{ {
int x; int x;
unsigned char t, tt; unsigned char t, tt;
for (x = t = 0; x < 16; x++) { for (x = t = 0; x < 16; x++) {
tt = I[x] >> 7; tt = I[x] >> 7;
I[x] = ((I[x] << 1) | t) & 0xFF; I[x] = ((I[x] << 1) | t) & 0xFF;
t = tt; t = tt;
} }
if (tt) { if (tt) {
I[0] ^= 0x87; I[0] ^= 0x87;
} }
} }
#endif #endif
@ -39,4 +39,3 @@ void xts_mult_x(unsigned char *I)
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */

View File

@ -12,8 +12,57 @@
#ifdef LTC_XTS_MODE #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 Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects
Returns CRYPT_OK upon success. Returns CRYPT_OK upon success.
*/ */
int xts_test(void) int xts_test(void)
@ -21,7 +70,8 @@ int xts_test(void)
#ifdef LTC_NO_TEST #ifdef LTC_NO_TEST
return CRYPT_NOP; return CRYPT_NOP;
#else #else
static const struct { static const struct
{
int keylen; int keylen;
unsigned char key1[32]; unsigned char key1[32];
unsigned char key2[32]; unsigned char key2[32];
@ -143,9 +193,9 @@ int xts_test(void)
}; };
unsigned char OUT[512], Torg[16], T[16]; unsigned char OUT[512], Torg[16], T[16];
ulong64 seq; ulong64 seq;
symmetric_xts xts; symmetric_xts xts;
int i, j, err, idx; int i, j, k, err, idx;
unsigned long len; unsigned long len;
/* AES can be under rijndael or aes... try to find it */ /* AES can be under rijndael or aes... try to find it */
@ -154,91 +204,103 @@ int xts_test(void)
return CRYPT_NOP; 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++) { err = xts_start(idx, tests[i].key1, tests[i].key2, tests[i].keylen / 2, 0, &xts);
for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) { if (err != CRYPT_OK) {
/* skip the cases where return err;
* 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); seq = tests[i].seqnum;
if (err != CRYPT_OK) { STORE64L(seq, Torg);
return err; XMEMSET(Torg + 8, 0, 8);
}
seq = tests[i].seqnum; XMEMCPY(T, Torg, sizeof(T));
STORE64L(seq,Torg); if (j == 0) {
XMEMSET(Torg+8, 0, 8); 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 (XMEMCMP(OUT, tests[i].CTX, tests[i].PTLEN)) {
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)) {
#ifdef LTC_TEST_DBG #ifdef LTC_TEST_DBG
printf("\nTestcase #%d with original length %lu and half of it %lu\n", i, tests[i].PTLEN, len); printf("\nTestcase #%d with original length %lu and half of it "
printf("\nencrypt\n"); "%lu\n",
print_hex("should", tests[i].CTX, tests[i].PTLEN); i, tests[i].PTLEN, len);
print_hex("is", OUT, tests[i].PTLEN); printf("\nencrypt\n");
print_hex("should", tests[i].CTX, tests[i].PTLEN);
print_hex("is", OUT, tests[i].PTLEN);
#endif #endif
xts_done(&xts); xts_done(&xts);
return CRYPT_FAIL_TESTVECTOR; return CRYPT_FAIL_TESTVECTOR;
} }
XMEMCPY(T, Torg, sizeof(T)); XMEMCPY(T, Torg, sizeof(T));
if (j == 0) { if (j == 0) {
err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts); err = xts_decrypt(tests[i].CTX, tests[i].PTLEN, OUT, T, &xts);
if (err != CRYPT_OK) { if (err != CRYPT_OK) {
xts_done(&xts); xts_done(&xts);
return err; return err;
} }
} } else {
else { err = xts_decrypt(tests[i].CTX, len, OUT, T, &xts);
err = xts_decrypt(tests[i].CTX, len, OUT, T, &xts); if (err != CRYPT_OK) {
if (err != CRYPT_OK) { xts_done(&xts);
xts_done(&xts); return err;
return err; }
} err = xts_decrypt(&tests[i].CTX[len], len, &OUT[len], T, &xts);
err = xts_decrypt(&tests[i].CTX[len], len, &OUT[len], T, &xts); if (err != CRYPT_OK) {
if (err != CRYPT_OK) { xts_done(&xts);
xts_done(&xts); return err;
return err; }
} }
}
if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) { if (XMEMCMP(OUT, tests[i].PTX, tests[i].PTLEN)) {
#ifdef LTC_TEST_DBG #ifdef LTC_TEST_DBG
printf("\ndecrypt\n"); printf("\ndecrypt\n");
print_hex("should", tests[i].PTX, tests[i].PTLEN); print_hex("should", tests[i].PTX, tests[i].PTLEN);
print_hex("is", OUT, tests[i].PTLEN); print_hex("is", OUT, tests[i].PTLEN);
#endif #endif
xts_done(&xts);
return CRYPT_FAIL_TESTVECTOR;
}
xts_done(&xts); xts_done(&xts);
return CRYPT_FAIL_TESTVECTOR;
} }
xts_done(&xts); }
}
} }
return CRYPT_OK; return CRYPT_OK;
#endif #endif
@ -249,4 +311,3 @@ int xts_test(void)
/* $Source$ */ /* $Source$ */
/* $Revision$ */ /* $Revision$ */
/* $Date$ */ /* $Date$ */