Path: blob/master/libs/tomcrypt/src/modes/xts/xts_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/**11Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects12*/1314#ifdef LTC_XTS_MODE1516static int _tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts)17{18unsigned long x;19int err;2021/* tweak encrypt block i */22#ifdef LTC_FAST23for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {24*(LTC_FAST_TYPE_PTR_CAST(&P[x])) = *(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&T[x]));25}26#else27for (x = 0; x < 16; x++) {28P[x] = C[x] ^ T[x];29}30#endif3132err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1);3334#ifdef LTC_FAST35for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {36*(LTC_FAST_TYPE_PTR_CAST(&P[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));37}38#else39for (x = 0; x < 16; x++) {40P[x] = P[x] ^ T[x];41}42#endif4344/* LFSR the tweak */45xts_mult_x(T);4647return err;48}4950/** XTS Decryption51@param ct [in] Ciphertext52@param ptlen Length of plaintext (and ciphertext)53@param pt [out] Plaintext54@param tweak [in] The 128--bit encryption tweak (e.g. sector number)55@param xts The XTS structure56Returns CRYPT_OK upon success57*/58int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak,59symmetric_xts *xts)60{61unsigned char PP[16], CC[16], T[16];62unsigned long i, m, mo, lim;63int err;6465/* check inputs */66LTC_ARGCHK(pt != NULL);67LTC_ARGCHK(ct != NULL);68LTC_ARGCHK(tweak != NULL);69LTC_ARGCHK(xts != NULL);7071/* check if valid */72if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {73return err;74}7576/* get number of blocks */77m = ptlen >> 4;78mo = ptlen & 15;7980/* must have at least one full block */81if (m == 0) {82return CRYPT_INVALID_ARG;83}8485if (mo == 0) {86lim = m;87} else {88lim = m - 1;89}9091if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) {9293/* use accelerated decryption for whole blocks */94if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2)) !=95CRYPT_OK) {96return err;97}98ct += lim * 16;99pt += lim * 16;100101/* tweak is encrypted on output */102XMEMCPY(T, tweak, sizeof(T));103} else {104/* encrypt the tweak */105if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {106return err;107}108109for (i = 0; i < lim; i++) {110if ((err = _tweak_uncrypt(ct, pt, T, xts)) != CRYPT_OK) {111return err;112}113ct += 16;114pt += 16;115}116}117118/* if ptlen not divide 16 then */119if (mo > 0) {120XMEMCPY(CC, T, 16);121xts_mult_x(CC);122123/* PP = tweak decrypt block m-1 */124if ((err = _tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) {125return err;126}127128/* Pm = first ptlen % 16 bytes of PP */129for (i = 0; i < mo; i++) {130CC[i] = ct[16 + i];131pt[16 + i] = PP[i];132}133for (; i < 16; i++) {134CC[i] = PP[i];135}136137/* Pm-1 = Tweak uncrypt CC */138if ((err = _tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) {139return err;140}141}142143/* Decrypt the tweak back */144if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {145return err;146}147148return CRYPT_OK;149}150151#endif152153154