Path: blob/master/libs/tomcrypt/src/modes/cbc/cbc_decrypt.c
5972 views
/* LibTomCrypt, modular cryptographic library -- Tom St Denis1*2* LibTomCrypt is a library that provides various cryptographic3* algorithms in a highly modular and flexible manner.4*5* The library is free for all purposes without any express6* guarantee it works.7*/8#include "tomcrypt.h"910/**11@file cbc_decrypt.c12CBC implementation, encrypt block, Tom St Denis13*/141516#ifdef LTC_CBC_MODE1718/**19CBC decrypt20@param ct Ciphertext21@param pt [out] Plaintext22@param len The number of bytes to process (must be multiple of block length)23@param cbc CBC state24@return CRYPT_OK if successful25*/26int cbc_decrypt(const unsigned char *ct, unsigned char *pt, unsigned long len, symmetric_CBC *cbc)27{28int x, err;29unsigned char tmp[16];30#ifdef LTC_FAST31LTC_FAST_TYPE tmpy;32#else33unsigned char tmpy;34#endif3536LTC_ARGCHK(pt != NULL);37LTC_ARGCHK(ct != NULL);38LTC_ARGCHK(cbc != NULL);3940if ((err = cipher_is_valid(cbc->cipher)) != CRYPT_OK) {41return err;42}4344/* is blocklen valid? */45if (cbc->blocklen < 1 || cbc->blocklen > (int)sizeof(cbc->IV) || cbc->blocklen > (int)sizeof(tmp)) {46return CRYPT_INVALID_ARG;47}4849if (len % cbc->blocklen) {50return CRYPT_INVALID_ARG;51}52#ifdef LTC_FAST53if (cbc->blocklen % sizeof(LTC_FAST_TYPE)) {54return CRYPT_INVALID_ARG;55}56#endif5758if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) {59return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key);60} else {61while (len) {62/* decrypt */63if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) {64return err;65}6667/* xor IV against plaintext */68#if defined(LTC_FAST)69for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) {70tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x));71*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x));72*(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy;73}74#else75for (x = 0; x < cbc->blocklen; x++) {76tmpy = tmp[x] ^ cbc->IV[x];77cbc->IV[x] = ct[x];78pt[x] = tmpy;79}80#endif8182ct += cbc->blocklen;83pt += cbc->blocklen;84len -= cbc->blocklen;85}86}87return CRYPT_OK;88}8990#endif919293