summaryrefslogtreecommitdiffhomepage
path: root/libtomcrypt/src/modes/xts/xts_decrypt.c
diff options
context:
space:
mode:
Diffstat (limited to 'libtomcrypt/src/modes/xts/xts_decrypt.c')
-rw-r--r--libtomcrypt/src/modes/xts/xts_decrypt.c113
1 files changed, 64 insertions, 49 deletions
diff --git a/libtomcrypt/src/modes/xts/xts_decrypt.c b/libtomcrypt/src/modes/xts/xts_decrypt.c
index 3e46c53..4580991 100644
--- a/libtomcrypt/src/modes/xts/xts_decrypt.c
+++ b/libtomcrypt/src/modes/xts/xts_decrypt.c
@@ -5,18 +5,16 @@
*
* The library is free for all purposes without any express
* guarantee it works.
- *
- * Tom St Denis, tomstdenis@gmail.com, http://libtom.org
*/
#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
-static int tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts)
+static int _tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts)
{
unsigned long x;
int err;
@@ -24,23 +22,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_PTR_CAST(&P[x])) = *(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&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_PTR_CAST(&P[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
}
#else
for (x = 0; x < 16; x++) {
- P[x] = P[x] ^ T[x];
+ P[x] = P[x] ^ T[x];
}
#endif
@@ -48,30 +46,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,
- const 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 +75,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,55 +83,74 @@ 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++) {
+ if ((err = _tweak_uncrypt(ct, pt, T, xts)) != CRYPT_OK) {
+ return err;
+ }
+ ct += 16;
+ pt += 16;
+ }
}
-
+
/* if ptlen not divide 16 then */
if (mo > 0) {
XMEMCPY(CC, T, 16);
xts_mult_x(CC);
/* PP = tweak decrypt block m-1 */
- if ((err = tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) {
+ if ((err = _tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) {
return err;
}
/* 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 */
- if ((err = tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) {
+ if ((err = _tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) {
return err;
}
}
+ /* Decrypt the tweak back */
+ if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
+ return err;
+ }
+
return CRYPT_OK;
}
#endif
-/* $Source$ */
-/* $Revision$ */
-/* $Date$ */
-
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */