Home | History | Annotate | Download | only in cbc
      1 /* LibTomCrypt, modular cryptographic library -- Tom St Denis
      2  *
      3  * LibTomCrypt is a library that provides various cryptographic
      4  * algorithms in a highly modular and flexible manner.
      5  *
      6  * The library is free for all purposes without any express
      7  * guarantee it works.
      8  *
      9  * Tom St Denis, tomstdenis (at) gmail.com, http://libtomcrypt.com
     10  */
     11 #include "tomcrypt.h"
     12 
     13 /**
     14    @file cbc_decrypt.c
     15    CBC implementation, encrypt block, Tom St Denis
     16 */
     17 
     18 
     19 #ifdef LTC_CBC_MODE
     20 
     21 /**
     22   CBC decrypt
     23   @param ct     Ciphertext
     24   @param pt     [out] Plaintext
     25   @param len    The number of bytes to process (must be multiple of block length)
     26   @param cbc    CBC state
     27   @return CRYPT_OK if successful
     28 */
     29 int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)
     30 {
     31    int x, err;
     32    unsigned char tmp[16];
     33 #ifdef LTC_FAST
     34    LTC_FAST_TYPE tmpy;
     35 #else
     36    unsigned char tmpy;
     37 #endif
     38 
     39    LTC_ARGCHK(pt  != NULL);
     40    LTC_ARGCHK(ct  != NULL);
     41    LTC_ARGCHK(cbc != NULL);
     42 
     43    if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {
     44        return err;
     45    }
     46 
     47    /* is blocklen valid? */
     48    if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV)) {
     49       return CRYPT_INVALID_ARG;
     50    }
     51 
     52    if (len % cbc->blocklen) {
     53       return CRYPT_INVALID_ARG;
     54    }
     55 #ifdef LTC_FAST
     56    if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {
     57       return CRYPT_INVALID_ARG;
     58    }
     59 #endif
     60 
     61    if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {
     62       return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);
     63    } else {
     64       while (len) {
     65          /* decrypt */
     66          if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {
     67             return err;
     68          }
     69 
     70          /* xor IV against plaintext */
     71          #if defined(LTC_FAST)
     72         for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {
     73             tmpy = *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) ^ *((LTC_FAST_TYPE*)((unsigned char *)tmp + x));
     74        *((LTC_FAST_TYPE*)((unsigned char *)cbc->IV + x)) = *((LTC_FAST_TYPE*)((unsigned char *)ct + x));
     75        *((LTC_FAST_TYPE*)((unsigned char *)pt + x)) = tmpy;
     76         }
     77     #else
     78             for (x = 0; x < cbc->blocklen; x++) {
     79                tmpy       = tmp[x] ^ cbc->IV[x];
     80                cbc->IV[x] = ct[x];
     81                pt[x]      = tmpy;
     82             }
     83     #endif
     84 
     85          ct  += cbc->blocklen;
     86          pt  += cbc->blocklen;
     87          len -= cbc->blocklen;
     88       }
     89    }
     90    return CRYPT_OK;
     91 }
     92 
     93 #endif
     94 
     95 /* $Source: /cvs/libtom/libtomcrypt/src/modes/cbc/cbc_decrypt.c,v $ */
     96 /* $Revision: 1.15 $ */
     97 /* $Date: 2006/11/21 00:18:23 $ */
     98