Path: blob/master/libs/tomcrypt/src/modes/xts/xts_encrypt.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_crypt(const unsigned char *P, unsigned char *C, 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(&C[x])) = *(LTC_FAST_TYPE_PTR_CAST(&P[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&T[x]));25}26#else27for (x = 0; x < 16; x++) {28C[x] = P[x] ^ T[x];29}30#endif3132if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(C, C, &xts->key1)) != CRYPT_OK) {33return err;34}3536#ifdef LTC_FAST37for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {38*(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));39}40#else41for (x = 0; x < 16; x++) {42C[x] = C[x] ^ T[x];43}44#endif4546/* LFSR the tweak */47xts_mult_x(T);4849return CRYPT_OK;50}5152/** XTS Encryption53@param pt [in] Plaintext54@param ptlen Length of plaintext (and ciphertext)55@param ct [out] Ciphertext56@param tweak [in] The 128--bit encryption tweak (e.g. sector number)57@param xts The XTS structure58Returns CRYPT_OK upon success59*/60int xts_encrypt(const unsigned char *pt, unsigned long ptlen, unsigned char *ct, unsigned char *tweak,61symmetric_xts *xts)62{63unsigned char PP[16], CC[16], T[16];64unsigned long i, m, mo, lim;65int err;6667/* check inputs */68LTC_ARGCHK(pt != NULL);69LTC_ARGCHK(ct != NULL);70LTC_ARGCHK(tweak != NULL);71LTC_ARGCHK(xts != NULL);7273/* check if valid */74if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {75return err;76}7778/* get number of blocks */79m = ptlen >> 4;80mo = ptlen & 15;8182/* must have at least one full block */83if (m == 0) {84return CRYPT_INVALID_ARG;85}8687if (mo == 0) {88lim = m;89} else {90lim = m - 1;91}9293if (cipher_descriptor[xts->cipher].accel_xts_encrypt && lim > 0) {9495/* use accelerated encryption for whole blocks */96if ((err = cipher_descriptor[xts->cipher].accel_xts_encrypt(pt, ct, lim, tweak, &xts->key1, &xts->key2)) !=97CRYPT_OK) {98return err;99}100ct += lim * 16;101pt += lim * 16;102103/* tweak is encrypted on output */104XMEMCPY(T, tweak, sizeof(T));105} else {106107/* encrypt the tweak */108if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {109return err;110}111112for (i = 0; i < lim; i++) {113if ((err = _tweak_crypt(pt, ct, T, xts)) != CRYPT_OK) {114return err;115}116ct += 16;117pt += 16;118}119}120121/* if ptlen not divide 16 then */122if (mo > 0) {123/* CC = tweak encrypt block m-1 */124if ((err = _tweak_crypt(pt, CC, T, xts)) != CRYPT_OK) {125return err;126}127128/* Cm = first ptlen % 16 bytes of CC */129for (i = 0; i < mo; i++) {130PP[i] = pt[16 + i];131ct[16 + i] = CC[i];132}133134for (; i < 16; i++) {135PP[i] = CC[i];136}137138/* Cm-1 = Tweak encrypt PP */139if ((err = _tweak_crypt(PP, ct, T, xts)) != CRYPT_OK) {140return err;141}142}143144/* Decrypt the tweak back */145if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {146return err;147}148149return err;150}151152#endif153154155