]> pd.if.org Git - zpackage/blob - libtomcrypt/src/modes/xts/xts_decrypt.c
458099150860360a7c5f96e7a2b8f5f9a27534d2
[zpackage] / libtomcrypt / src / modes / xts / xts_decrypt.c
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 #include "tomcrypt.h"
10
11 /**
12  Source donated by Elliptic Semiconductor Inc (www.ellipticsemi.com) to the LibTom Projects
13  */
14
15 #ifdef LTC_XTS_MODE
16
17 static int _tweak_uncrypt(const unsigned char *C, unsigned char *P, unsigned char *T, symmetric_xts *xts)
18 {
19    unsigned long x;
20    int err;
21
22    /* tweak encrypt block i */
23 #ifdef LTC_FAST
24    for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
25       *(LTC_FAST_TYPE_PTR_CAST(&P[x])) = *(LTC_FAST_TYPE_PTR_CAST(&C[x])) ^ *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
26    }
27 #else
28    for (x = 0; x < 16; x++) {
29       P[x] = C[x] ^ T[x];
30    }
31 #endif
32
33    err = cipher_descriptor[xts->cipher].ecb_decrypt(P, P, &xts->key1);
34
35 #ifdef LTC_FAST
36    for (x = 0; x < 16; x += sizeof(LTC_FAST_TYPE)) {
37       *(LTC_FAST_TYPE_PTR_CAST(&P[x])) ^= *(LTC_FAST_TYPE_PTR_CAST(&T[x]));
38    }
39 #else
40    for (x = 0; x < 16; x++) {
41       P[x] = P[x] ^ T[x];
42    }
43 #endif
44
45    /* LFSR the tweak */
46    xts_mult_x(T);
47
48    return err;
49 }
50
51 /** XTS Decryption
52  @param ct     [in] Ciphertext
53  @param ptlen  Length of plaintext (and ciphertext)
54  @param pt     [out]  Plaintext
55  @param tweak  [in] The 128--bit encryption tweak (e.g. sector number)
56  @param xts    The XTS structure
57  Returns CRYPT_OK upon success
58  */
59 int xts_decrypt(const unsigned char *ct, unsigned long ptlen, unsigned char *pt, unsigned char *tweak,
60                 symmetric_xts *xts)
61 {
62    unsigned char PP[16], CC[16], T[16];
63    unsigned long i, m, mo, lim;
64    int err;
65
66    /* check inputs */
67    LTC_ARGCHK(pt != NULL);
68    LTC_ARGCHK(ct != NULL);
69    LTC_ARGCHK(tweak != NULL);
70    LTC_ARGCHK(xts != NULL);
71
72    /* check if valid */
73    if ((err = cipher_is_valid(xts->cipher)) != CRYPT_OK) {
74       return err;
75    }
76
77    /* get number of blocks */
78    m = ptlen >> 4;
79    mo = ptlen & 15;
80
81    /* must have at least one full block */
82    if (m == 0) {
83       return CRYPT_INVALID_ARG;
84    }
85
86    if (mo == 0) {
87       lim = m;
88    } else {
89       lim = m - 1;
90    }
91
92    if (cipher_descriptor[xts->cipher].accel_xts_decrypt && lim > 0) {
93
94       /* use accelerated decryption for whole blocks */
95       if ((err = cipher_descriptor[xts->cipher].accel_xts_decrypt(ct, pt, lim, tweak, &xts->key1, &xts->key2)) !=
96                  CRYPT_OK) {
97          return err;
98       }
99       ct += lim * 16;
100       pt += lim * 16;
101
102       /* tweak is encrypted on output */
103       XMEMCPY(T, tweak, sizeof(T));
104    } else {
105       /* encrypt the tweak */
106       if ((err = cipher_descriptor[xts->cipher].ecb_encrypt(tweak, T, &xts->key2)) != CRYPT_OK) {
107          return err;
108       }
109
110       for (i = 0; i < lim; i++) {
111          if ((err = _tweak_uncrypt(ct, pt, T, xts)) != CRYPT_OK) {
112             return err;
113          }
114          ct += 16;
115          pt += 16;
116       }
117    }
118
119    /* if ptlen not divide 16 then */
120    if (mo > 0) {
121       XMEMCPY(CC, T, 16);
122       xts_mult_x(CC);
123
124       /* PP = tweak decrypt block m-1 */
125       if ((err = _tweak_uncrypt(ct, PP, CC, xts)) != CRYPT_OK) {
126          return err;
127       }
128
129       /* Pm = first ptlen % 16 bytes of PP */
130       for (i = 0; i < mo; i++) {
131          CC[i] = ct[16 + i];
132          pt[16 + i] = PP[i];
133       }
134       for (; i < 16; i++) {
135          CC[i] = PP[i];
136       }
137
138       /* Pm-1 = Tweak uncrypt CC */
139       if ((err = _tweak_uncrypt(CC, pt, T, xts)) != CRYPT_OK) {
140          return err;
141       }
142    }
143
144    /* Decrypt the tweak back */
145    if ((err = cipher_descriptor[xts->cipher].ecb_decrypt(T, tweak, &xts->key2)) != CRYPT_OK) {
146       return err;
147    }
148
149    return CRYPT_OK;
150 }
151
152 #endif
153
154 /* ref:         $Format:%D$ */
155 /* git commit:  $Format:%H$ */
156 /* commit time: $Format:%ai$ */