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