Browse Source

Merge branch 'aes-xts-accel' into develop

This fixes #70
Steffen Jaeckel 10 years ago
parent
commit
38bfef2996

+ 4 - 4
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

+ 1 - 1
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

+ 1 - 1
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] = {

+ 1 - 1
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[] = {

+ 1 - 1
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] = {

+ 2 - 2
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] =

+ 1 - 1
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 )

+ 1 - 1
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

+ 1 - 1
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] = {

+ 1 - 1
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)

+ 1 - 1
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[] = {

+ 1 - 1
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 */

+ 1 - 1
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] = {

+ 1 - 1
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] = {

+ 4 - 4
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 ************************************************/

+ 1 - 1
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)

+ 1 - 1
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] = {

+ 1 - 1
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 */

+ 1 - 1
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)

+ 30 - 0
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

+ 1 - 1
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)

+ 51 - 41
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$ */
-

+ 2 - 3
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$ */
-

+ 51 - 41
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$ */
-

+ 6 - 12
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$ */
-

+ 12 - 13
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$ */
-

+ 138 - 77
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$ */
-