This source file includes following definitions.
- rijndaelMakeKey
- rijndaelCipherInit
- rijndaelBlockEncrypt
- rijndaelPadEncrypt
- rijndaelBlockDecrypt
- rijndaelPadDecrypt
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26 #include <config.h>
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65 #include "rijndael-alg-fst.h"
66 #include "rijndael-api-fst.h"
67
68 #include <assert.h>
69 #include <stdlib.h>
70 #include <string.h>
71
72 rijndael_rc
73 rijndaelMakeKey (rijndaelKeyInstance *key, rijndael_direction direction,
74 size_t keyLen, const char *keyMaterial)
75 {
76 size_t i;
77 char *keyMat;
78 char cipherKey[RIJNDAEL_MAXKB];
79
80 if (key == NULL)
81 {
82 return RIJNDAEL_BAD_KEY_INSTANCE;
83 }
84
85 if ((direction == RIJNDAEL_DIR_ENCRYPT)
86 || (direction == RIJNDAEL_DIR_DECRYPT))
87 {
88 key->direction = direction;
89 }
90 else
91 {
92 return RIJNDAEL_BAD_KEY_DIR;
93 }
94
95 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256))
96 {
97 key->keyLen = keyLen;
98 }
99 else
100 {
101 return RIJNDAEL_BAD_KEY_MAT;
102 }
103
104 if (keyMaterial != NULL)
105 {
106 strncpy (key->keyMaterial, keyMaterial, keyLen / 4);
107 }
108
109
110 keyMat = key->keyMaterial;
111 for (i = 0; i < key->keyLen / 8; i++)
112 {
113 char t, v;
114
115 t = *keyMat++;
116 if ((t >= '0') && (t <= '9'))
117 v = (t - '0') << 4;
118 else if ((t >= 'a') && (t <= 'f'))
119 v = (t - 'a' + 10) << 4;
120 else if ((t >= 'A') && (t <= 'F'))
121 v = (t - 'A' + 10) << 4;
122 else
123 return RIJNDAEL_BAD_KEY_MAT;
124
125 t = *keyMat++;
126 if ((t >= '0') && (t <= '9'))
127 v ^= (t - '0');
128 else if ((t >= 'a') && (t <= 'f'))
129 v ^= (t - 'a' + 10);
130 else if ((t >= 'A') && (t <= 'F'))
131 v ^= (t - 'A' + 10);
132 else
133 return RIJNDAEL_BAD_KEY_MAT;
134
135 cipherKey[i] = v;
136 }
137 if (direction == RIJNDAEL_DIR_ENCRYPT)
138 {
139 key->Nr = rijndaelKeySetupEnc (key->rk, cipherKey, keyLen);
140 }
141 else
142 {
143 key->Nr = rijndaelKeySetupDec (key->rk, cipherKey, keyLen);
144 }
145 rijndaelKeySetupEnc (key->ek, cipherKey, keyLen);
146 return 0;
147 }
148
149 rijndael_rc
150 rijndaelCipherInit (rijndaelCipherInstance *cipher, rijndael_mode mode,
151 const char *IV)
152 {
153 if ((mode == RIJNDAEL_MODE_ECB) || (mode == RIJNDAEL_MODE_CBC)
154 || (mode == RIJNDAEL_MODE_CFB1))
155 {
156 cipher->mode = mode;
157 }
158 else
159 {
160 return RIJNDAEL_BAD_CIPHER_MODE;
161 }
162 if (IV != NULL)
163 {
164 int i;
165 for (i = 0; i < RIJNDAEL_MAX_IV_SIZE; i++)
166 {
167 int t, j;
168
169 t = IV[2 * i];
170 if ((t >= '0') && (t <= '9'))
171 j = (t - '0') << 4;
172 else if ((t >= 'a') && (t <= 'f'))
173 j = (t - 'a' + 10) << 4;
174 else if ((t >= 'A') && (t <= 'F'))
175 j = (t - 'A' + 10) << 4;
176 else
177 return RIJNDAEL_BAD_CIPHER_INSTANCE;
178
179 t = IV[2 * i + 1];
180 if ((t >= '0') && (t <= '9'))
181 j ^= (t - '0');
182 else if ((t >= 'a') && (t <= 'f'))
183 j ^= (t - 'a' + 10);
184 else if ((t >= 'A') && (t <= 'F'))
185 j ^= (t - 'A' + 10);
186 else
187 return RIJNDAEL_BAD_CIPHER_INSTANCE;
188
189 cipher->IV[i] = (uint8_t) j;
190 }
191 }
192 else
193 {
194 memset (cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
195 }
196 return 0;
197 }
198
199 int
200 rijndaelBlockEncrypt (rijndaelCipherInstance *cipher,
201 const rijndaelKeyInstance *key,
202 const char *input,
203 size_t inputLen, char *outBuffer)
204 {
205 size_t i, k, t, numBlocks;
206 union { char bytes[16]; uint32_t words[4]; } block;
207 char *iv;
208
209 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
210 {
211 return RIJNDAEL_BAD_CIPHER_STATE;
212 }
213 if (input == NULL || inputLen <= 0)
214 {
215 return 0;
216 }
217
218 numBlocks = inputLen / 128;
219
220 switch (cipher->mode)
221 {
222 case RIJNDAEL_MODE_ECB:
223 for (i = numBlocks; i > 0; i--)
224 {
225 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
226 input += 16;
227 outBuffer += 16;
228 }
229 break;
230
231 case RIJNDAEL_MODE_CBC:
232 iv = cipher->IV;
233 for (i = numBlocks; i > 0; i--)
234 {
235 block.words[0] = ((uint32_t *) input)[0] ^ ((uint32_t *) iv)[0];
236 block.words[1] = ((uint32_t *) input)[1] ^ ((uint32_t *) iv)[1];
237 block.words[2] = ((uint32_t *) input)[2] ^ ((uint32_t *) iv)[2];
238 block.words[3] = ((uint32_t *) input)[3] ^ ((uint32_t *) iv)[3];
239 rijndaelEncrypt (key->rk, key->Nr, block.bytes, outBuffer);
240 memcpy (cipher->IV, outBuffer, 16);
241 input += 16;
242 outBuffer += 16;
243 }
244 break;
245
246 case RIJNDAEL_MODE_CFB1:
247 iv = cipher->IV;
248 for (i = numBlocks; i > 0; i--)
249 {
250 memcpy (outBuffer, input, 16);
251 for (k = 0; k < 128; k++)
252 {
253 rijndaelEncrypt (key->ek, key->Nr, iv, block.bytes);
254 outBuffer[k >> 3] ^= (block.bytes[0] & 0x80U) >> (k & 7);
255 for (t = 0; t < 15; t++)
256 {
257 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
258 }
259 iv[15] = (iv[15] << 1) |
260 ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
261 }
262 outBuffer += 16;
263 input += 16;
264 }
265 break;
266
267 default:
268 return RIJNDAEL_BAD_CIPHER_STATE;
269 }
270
271 return 128 * numBlocks;
272 }
273
274 int
275 rijndaelPadEncrypt (rijndaelCipherInstance *cipher,
276 const rijndaelKeyInstance *key,
277 const char *input,
278 size_t inputOctets, char *outBuffer)
279 {
280 size_t i, numBlocks, padLen;
281 union { char bytes[16]; uint32_t words[4]; } block;
282 char *iv;
283
284 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_DECRYPT)
285 {
286 return RIJNDAEL_BAD_CIPHER_STATE;
287 }
288 if (input == NULL || inputOctets <= 0)
289 {
290 return 0;
291 }
292
293 numBlocks = inputOctets / 16;
294
295 switch (cipher->mode)
296 {
297 case RIJNDAEL_MODE_ECB:
298 for (i = numBlocks; i > 0; i--)
299 {
300 rijndaelEncrypt (key->rk, key->Nr, input, outBuffer);
301 input += 16;
302 outBuffer += 16;
303 }
304 padLen = 16 - (inputOctets - 16 * numBlocks);
305 assert (padLen > 0 && padLen <= 16);
306 memcpy (block.bytes, input, 16 - padLen);
307 memset (block.bytes + 16 - padLen, padLen, padLen);
308 rijndaelEncrypt (key->rk, key->Nr, block.bytes, outBuffer);
309 break;
310
311 case RIJNDAEL_MODE_CBC:
312 iv = cipher->IV;
313 for (i = numBlocks; i > 0; i--)
314 {
315 block.words[0] = ((uint32_t *) input)[0] ^ ((uint32_t *) iv)[0];
316 block.words[1] = ((uint32_t *) input)[1] ^ ((uint32_t *) iv)[1];
317 block.words[2] = ((uint32_t *) input)[2] ^ ((uint32_t *) iv)[2];
318 block.words[3] = ((uint32_t *) input)[3] ^ ((uint32_t *) iv)[3];
319 rijndaelEncrypt (key->rk, key->Nr, block.bytes, outBuffer);
320 memcpy (cipher->IV, outBuffer, 16);
321 input += 16;
322 outBuffer += 16;
323 }
324 padLen = 16 - (inputOctets - 16 * numBlocks);
325 assert (padLen > 0 && padLen <= 16);
326 for (i = 0; i < 16 - padLen; i++)
327 {
328 block.bytes[i] = input[i] ^ iv[i];
329 }
330 for (i = 16 - padLen; i < 16; i++)
331 {
332 block.bytes[i] = (char) padLen ^ iv[i];
333 }
334 rijndaelEncrypt (key->rk, key->Nr, block.bytes, outBuffer);
335 memcpy (cipher->IV, outBuffer, 16);
336 break;
337
338 default:
339 return RIJNDAEL_BAD_CIPHER_STATE;
340 }
341
342 return 16 * (numBlocks + 1);
343 }
344
345 int
346 rijndaelBlockDecrypt (rijndaelCipherInstance *cipher,
347 const rijndaelKeyInstance *key,
348 const char *input,
349 size_t inputLen, char *outBuffer)
350 {
351 size_t i, k, t, numBlocks;
352 union { char bytes[16]; uint32_t words[4]; } block;
353 char *iv;
354
355 if (cipher == NULL
356 || key == NULL
357 || (cipher->mode != RIJNDAEL_MODE_CFB1
358 && key->direction == RIJNDAEL_DIR_ENCRYPT))
359 {
360 return RIJNDAEL_BAD_CIPHER_STATE;
361 }
362 if (input == NULL || inputLen <= 0)
363 {
364 return 0;
365 }
366
367 numBlocks = inputLen / 128;
368
369 switch (cipher->mode)
370 {
371 case RIJNDAEL_MODE_ECB:
372 for (i = numBlocks; i > 0; i--)
373 {
374 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
375 input += 16;
376 outBuffer += 16;
377 }
378 break;
379
380 case RIJNDAEL_MODE_CBC:
381 iv = cipher->IV;
382 for (i = numBlocks; i > 0; i--)
383 {
384 rijndaelDecrypt (key->rk, key->Nr, input, block.bytes);
385 block.words[0] ^= ((uint32_t *) iv)[0];
386 block.words[1] ^= ((uint32_t *) iv)[1];
387 block.words[2] ^= ((uint32_t *) iv)[2];
388 block.words[3] ^= ((uint32_t *) iv)[3];
389 memcpy (cipher->IV, input, 16);
390 memcpy (outBuffer, block.bytes, 16);
391 input += 16;
392 outBuffer += 16;
393 }
394 break;
395
396 case RIJNDAEL_MODE_CFB1:
397 iv = cipher->IV;
398 for (i = numBlocks; i > 0; i--)
399 {
400 memcpy (outBuffer, input, 16);
401 for (k = 0; k < 128; k++)
402 {
403 rijndaelEncrypt (key->ek, key->Nr, iv, block.bytes);
404 for (t = 0; t < 15; t++)
405 {
406 iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
407 }
408 iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
409 outBuffer[k >> 3] ^= (block.bytes[0] & 0x80U) >> (k & 7);
410 }
411 outBuffer += 16;
412 input += 16;
413 }
414 break;
415
416 default:
417 return RIJNDAEL_BAD_CIPHER_STATE;
418 }
419
420 return 128 * numBlocks;
421 }
422
423 int
424 rijndaelPadDecrypt (rijndaelCipherInstance *cipher,
425 const rijndaelKeyInstance *key,
426 const char *input,
427 size_t inputOctets, char *outBuffer)
428 {
429 size_t i, numBlocks, padLen;
430 union { char bytes[16]; uint32_t words[4]; } block;
431 char *iv;
432
433 if (cipher == NULL || key == NULL || key->direction == RIJNDAEL_DIR_ENCRYPT)
434 {
435 return RIJNDAEL_BAD_CIPHER_STATE;
436 }
437 if (input == NULL || inputOctets <= 0)
438 {
439 return 0;
440 }
441 if (inputOctets % 16 != 0)
442 {
443 return RIJNDAEL_BAD_DATA;
444 }
445
446 numBlocks = inputOctets / 16;
447
448 switch (cipher->mode)
449 {
450 case RIJNDAEL_MODE_ECB:
451
452 for (i = numBlocks - 1; i > 0; i--)
453 {
454 rijndaelDecrypt (key->rk, key->Nr, input, outBuffer);
455 input += 16;
456 outBuffer += 16;
457 }
458
459 rijndaelDecrypt (key->rk, key->Nr, input, block.bytes);
460 padLen = block.bytes[15];
461 if (padLen >= 16)
462 {
463 return RIJNDAEL_BAD_DATA;
464 }
465 for (i = 16 - padLen; i < 16; i++)
466 {
467 if (block.bytes[i] != padLen)
468 {
469 return RIJNDAEL_BAD_DATA;
470 }
471 }
472 memcpy (outBuffer, block.bytes, 16 - padLen);
473 break;
474
475 case RIJNDAEL_MODE_CBC:
476 iv = cipher->IV;
477
478 for (i = numBlocks - 1; i > 0; i--)
479 {
480 rijndaelDecrypt (key->rk, key->Nr, input, block.bytes);
481 block.words[0] ^= ((uint32_t *) iv)[0];
482 block.words[1] ^= ((uint32_t *) iv)[1];
483 block.words[2] ^= ((uint32_t *) iv)[2];
484 block.words[3] ^= ((uint32_t *) iv)[3];
485 memcpy (iv, input, 16);
486 memcpy (outBuffer, block.bytes, 16);
487 input += 16;
488 outBuffer += 16;
489 }
490
491 rijndaelDecrypt (key->rk, key->Nr, input, block.bytes);
492 block.words[0] ^= ((uint32_t *) iv)[0];
493 block.words[1] ^= ((uint32_t *) iv)[1];
494 block.words[2] ^= ((uint32_t *) iv)[2];
495 block.words[3] ^= ((uint32_t *) iv)[3];
496 padLen = block.bytes[15];
497 if (padLen <= 0 || padLen > 16)
498 {
499 return RIJNDAEL_BAD_DATA;
500 }
501 for (i = 16 - padLen; i < 16; i++)
502 {
503 if (block.bytes[i] != padLen)
504 {
505 return RIJNDAEL_BAD_DATA;
506 }
507 }
508 memcpy (outBuffer, block.bytes, 16 - padLen);
509 break;
510
511 default:
512 return RIJNDAEL_BAD_CIPHER_STATE;
513 }
514
515 return 16 * numBlocks - padLen;
516 }