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