diff libtomcrypt/src/modes/xts/xts_decrypt.c @ 1471:6dba84798cd5

Update to libtomcrypt 1.18.1, merged with Dropbear changes
author Matt Johnston <matt@ucc.asn.au>
date Fri, 09 Feb 2018 21:44:05 +0800
parents f849a5ca2efc
children
line wrap: on
line diff
--- a/libtomcrypt/src/modes/xts/xts_decrypt.c	Thu Feb 08 23:11:40 2018 +0800
+++ b/libtomcrypt/src/modes/xts/xts_decrypt.c	Fri Feb 09 21:44:05 2018 +0800
@@ -5,18 +5,16 @@
  *
  * The library is free for all purposes without any express
  * guarantee it works.
- *
- * Tom St Denis, [email protected], 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 @@
    /* 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 @@
    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 @@
    }
 
    /* get number of blocks */
-   m  = ptlen >> 4;
+   m = ptlen >> 4;
    mo = ptlen & 15;
 
    /* must have at least one full block */
@@ -87,55 +83,74 @@
       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$ */