WIP crypto/opencrypto update
[dragonfly.git] / sys / crypto / rijndael / rijndael-api-fst.c
1 /*      $FreeBSD: src/sys/crypto/rijndael/rijndael-api-fst.c,v 1.12 2005/03/11 16:26:10 ume Exp $       */
2 /*      $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $       */
3
4 /*
5  * rijndael-api-fst.c   v2.3   April '2000
6  *
7  * Optimised ANSI C code
8  *
9  * authors: v1.0: Antoon Bosselaers
10  *          v2.0: Vincent Rijmen
11  *          v2.1: Vincent Rijmen
12  *          v2.2: Vincent Rijmen
13  *          v2.3: Paulo Barreto
14  *          v2.4: Vincent Rijmen
15  *
16  * This code is placed in the public domain.
17  */
18
19 #include <sys/param.h>
20 #ifdef _KERNEL
21 #include <sys/systm.h>
22 #else
23 #include <string.h>
24 #endif
25
26 #include <crypto/rijndael/rijndael_local.h>
27 #include <crypto/rijndael/rijndael-api-fst.h>
28
29 #ifndef TRUE
30 #define TRUE 1
31 #endif
32
33 typedef u_int8_t        BYTE;
34
35 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
36         u_int8_t cipherKey[RIJNDAEL_MAXKB];
37
38         if (key == NULL) {
39                 return BAD_KEY_INSTANCE;
40         }
41
42         if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
43                 key->direction = direction;
44         } else {
45                 return BAD_KEY_DIR;
46         }
47
48         if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
49                 key->keyLen = keyLen;
50         } else {
51                 return BAD_KEY_MAT;
52         }
53
54         if (keyMaterial != NULL) {
55                 memcpy(key->keyMaterial, keyMaterial, keyLen/8);
56         }
57
58         /* initialize key schedule: */
59         memcpy(cipherKey, key->keyMaterial, keyLen/8);
60         if (direction == DIR_ENCRYPT) {
61                 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
62         } else {
63                 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
64         }
65         rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
66         return TRUE;
67 }
68
69 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
70         if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
71                 cipher->mode = mode;
72         } else {
73                 return BAD_CIPHER_MODE;
74         }
75         if (IV != NULL) {
76                 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
77         } else {
78                 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
79         }
80         return TRUE;
81 }
82
83 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
84                 BYTE *input, int inputLen, BYTE *outBuffer) {
85         int i, k, numBlocks;
86         u_int8_t block[16], iv[4][4];
87
88         if (cipher == NULL ||
89                 key == NULL ||
90                 key->direction == DIR_DECRYPT) {
91                 return BAD_CIPHER_STATE;
92         }
93         if (input == NULL || inputLen <= 0) {
94                 return 0; /* nothing to do */
95         }
96
97         numBlocks = inputLen/128;
98
99         switch (cipher->mode) {
100         case MODE_ECB:
101                 for (i = numBlocks; i > 0; i--) {
102                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
103                         input += 16;
104                         outBuffer += 16;
105                 }
106                 break;
107
108         case MODE_CBC:
109 #if 1 /*STRICT_ALIGN*/
110                 memcpy(block, cipher->IV, 16);
111                 memcpy(iv, input, 16);
112                 ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
113                 ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
114                 ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
115                 ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
116 #else
117                 ((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0];
118                 ((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1];
119                 ((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2];
120                 ((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3];
121 #endif
122                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
123                 input += 16;
124                 for (i = numBlocks - 1; i > 0; i--) {
125 #if 1 /*STRICT_ALIGN*/
126                         memcpy(block, outBuffer, 16);
127                         memcpy(iv, input, 16);
128                         ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
129                         ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
130                         ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
131                         ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
132 #else
133                         ((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0];
134                         ((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1];
135                         ((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2];
136                         ((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3];
137 #endif
138                         outBuffer += 16;
139                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
140                         input += 16;
141                 }
142                 break;
143
144         case MODE_CFB1:
145 #if 1 /*STRICT_ALIGN*/
146                 memcpy(iv, cipher->IV, 16);
147 #else  /* !STRICT_ALIGN */
148                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
149                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
150                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
151                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
152 #endif /* ?STRICT_ALIGN */
153                 for (i = numBlocks; i > 0; i--) {
154                         for (k = 0; k < 128; k++) {
155                                 *((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
156                                 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
157                                 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
158                                 *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
159                                 rijndaelEncrypt(key->ek, key->Nr, block,
160                                     block);
161                                 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
162                                 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
163                                 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
164                                 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
165                                 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
166                                 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
167                                 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
168                                 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
169                                 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
170                                 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
171                                 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
172                                 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
173                                 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
174                                 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
175                                 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
176                                 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
177                                 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
178                         }
179                 }
180                 break;
181
182         default:
183                 return BAD_CIPHER_STATE;
184         }
185
186         return 128*numBlocks;
187 }
188
189 /**
190  * Encrypt data partitioned in octets, using RFC 2040-like padding.
191  *
192  * @param   input           data to be encrypted (octet sequence)
193  * @param   inputOctets         input length in octets (not bits)
194  * @param   outBuffer       encrypted output data
195  *
196  * @return      length in octets (not bits) of the encrypted output buffer.
197  */
198 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
199                 BYTE *input, int inputOctets, BYTE *outBuffer) {
200         int i, numBlocks, padLen;
201         u_int8_t block[16], *iv, *cp;
202
203         if (cipher == NULL ||
204                 key == NULL ||
205                 key->direction == DIR_DECRYPT) {
206                 return BAD_CIPHER_STATE;
207         }
208         if (input == NULL || inputOctets <= 0) {
209                 return 0; /* nothing to do */
210         }
211
212         numBlocks = inputOctets/16;
213
214         switch (cipher->mode) {
215         case MODE_ECB:
216                 for (i = numBlocks; i > 0; i--) {
217                         rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
218                         input += 16;
219                         outBuffer += 16;
220                 }
221                 padLen = 16 - (inputOctets - 16*numBlocks);
222                 if (padLen <= 0 || padLen > 16)
223                         return BAD_CIPHER_STATE;
224                 memcpy(block, input, 16 - padLen);
225                 for (cp = block + 16 - padLen; cp < block + 16; cp++)
226                         *cp = padLen;
227                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
228                 break;
229
230         case MODE_CBC:
231                 iv = cipher->IV;
232                 for (i = numBlocks; i > 0; i--) {
233                         ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
234                         ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
235                         ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
236                         ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
237                         rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
238                         iv = outBuffer;
239                         input += 16;
240                         outBuffer += 16;
241                 }
242                 padLen = 16 - (inputOctets - 16*numBlocks);
243                 if (padLen <= 0 || padLen > 16)
244                         return BAD_CIPHER_STATE;
245                 for (i = 0; i < 16 - padLen; i++) {
246                         block[i] = input[i] ^ iv[i];
247                 }
248                 for (i = 16 - padLen; i < 16; i++) {
249                         block[i] = (BYTE)padLen ^ iv[i];
250                 }
251                 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
252                 break;
253
254         default:
255                 return BAD_CIPHER_STATE;
256         }
257
258         return 16*(numBlocks + 1);
259 }
260
261 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
262                 BYTE *input, int inputLen, BYTE *outBuffer) {
263         int i, k, numBlocks;
264         u_int8_t block[16], iv[4][4];
265
266         if (cipher == NULL ||
267                 key == NULL ||
268                 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
269                 return BAD_CIPHER_STATE;
270         }
271         if (input == NULL || inputLen <= 0) {
272                 return 0; /* nothing to do */
273         }
274
275         numBlocks = inputLen/128;
276
277         switch (cipher->mode) {
278         case MODE_ECB:
279                 for (i = numBlocks; i > 0; i--) {
280                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
281                         input += 16;
282                         outBuffer += 16;
283                 }
284                 break;
285
286         case MODE_CBC:
287 #if 1 /*STRICT_ALIGN */
288                 memcpy(iv, cipher->IV, 16);
289 #else
290                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
291                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
292                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
293                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
294 #endif
295                 for (i = numBlocks; i > 0; i--) {
296                         rijndaelDecrypt(key->rk, key->Nr, input, block);
297                         ((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]);
298                         ((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]);
299                         ((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]);
300                         ((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]);
301 #if 1 /*STRICT_ALIGN*/
302                         memcpy(iv, input, 16);
303                         memcpy(outBuffer, block, 16);
304 #else
305                         *((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0];
306                         *((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1];
307                         *((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2];
308                         *((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_t*)block)[3];
309 #endif
310                         input += 16;
311                         outBuffer += 16;
312                 }
313                 break;
314
315         case MODE_CFB1:
316 #if 1 /*STRICT_ALIGN */
317                 memcpy(iv, cipher->IV, 16);
318 #else
319                 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV));
320                 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
321                 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
322                 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
323 #endif
324                 for (i = numBlocks; i > 0; i--) {
325                         for (k = 0; k < 128; k++) {
326                                 *((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
327                                 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
328                                 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
329                                 *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
330                                 rijndaelEncrypt(key->ek, key->Nr, block,
331                                     block);
332                                 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
333                                 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
334                                 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
335                                 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
336                                 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
337                                 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
338                                 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
339                                 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
340                                 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
341                                 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
342                                 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
343                                 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
344                                 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
345                                 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
346                                 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
347                                 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
348                                 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
349                         }
350                 }
351                 break;
352
353         default:
354                 return BAD_CIPHER_STATE;
355         }
356
357         return 128*numBlocks;
358 }
359
360 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
361                 BYTE *input, int inputOctets, BYTE *outBuffer) {
362         int i, numBlocks, padLen;
363         u_int8_t block[16];
364         u_int32_t iv[4];
365
366         if (cipher == NULL ||
367                 key == NULL ||
368                 key->direction == DIR_ENCRYPT) {
369                 return BAD_CIPHER_STATE;
370         }
371         if (input == NULL || inputOctets <= 0) {
372                 return 0; /* nothing to do */
373         }
374         if (inputOctets % 16 != 0) {
375                 return BAD_DATA;
376         }
377
378         numBlocks = inputOctets/16;
379
380         switch (cipher->mode) {
381         case MODE_ECB:
382                 /* all blocks but last */
383                 for (i = numBlocks - 1; i > 0; i--) {
384                         rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
385                         input += 16;
386                         outBuffer += 16;
387                 }
388                 /* last block */
389                 rijndaelDecrypt(key->rk, key->Nr, input, block);
390                 padLen = block[15];
391                 if (padLen >= 16) {
392                         return BAD_DATA;
393                 }
394                 for (i = 16 - padLen; i < 16; i++) {
395                         if (block[i] != padLen) {
396                                 return BAD_DATA;
397                         }
398                 }
399                 memcpy(outBuffer, block, 16 - padLen);
400                 break;
401
402         case MODE_CBC:
403                 memcpy(iv, cipher->IV, 16);
404                 /* all blocks but last */
405                 for (i = numBlocks - 1; i > 0; i--) {
406                         rijndaelDecrypt(key->rk, key->Nr, input, block);
407                         ((u_int32_t*)block)[0] ^= iv[0];
408                         ((u_int32_t*)block)[1] ^= iv[1];
409                         ((u_int32_t*)block)[2] ^= iv[2];
410                         ((u_int32_t*)block)[3] ^= iv[3];
411                         memcpy(iv, input, 16);
412                         memcpy(outBuffer, block, 16);
413                         input += 16;
414                         outBuffer += 16;
415                 }
416                 /* last block */
417                 rijndaelDecrypt(key->rk, key->Nr, input, block);
418                 ((u_int32_t*)block)[0] ^= iv[0];
419                 ((u_int32_t*)block)[1] ^= iv[1];
420                 ((u_int32_t*)block)[2] ^= iv[2];
421                 ((u_int32_t*)block)[3] ^= iv[3];
422                 padLen = block[15];
423                 if (padLen <= 0 || padLen > 16) {
424                         return BAD_DATA;
425                 }
426                 for (i = 16 - padLen; i < 16; i++) {
427                         if (block[i] != padLen) {
428                                 return BAD_DATA;
429                         }
430                 }
431                 memcpy(outBuffer, block, 16 - padLen);
432                 break;
433
434         default:
435                 return BAD_CIPHER_STATE;
436         }
437
438         return 16*numBlocks - padLen;
439 }