1 /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */
4 * rijndael-api-fst.c v2.3 April '2000
6 * Optimised ANSI C code
8 * authors: v1.0: Antoon Bosselaers
10 * v2.1: Vincent Rijmen
11 * v2.2: Vincent Rijmen
13 * v2.4: Vincent Rijmen
15 * This code is placed in the public domain.
18 #include <sys/param.h>
20 #include <sys/systm.h>
25 #include <crypto/rijndael/rijndael_local.h>
26 #include <crypto/rijndael/rijndael-api-fst.h>
34 int rijndael_makeKey(keyInstance
*key
, BYTE direction
, int keyLen
,
35 const char *keyMaterial
) {
38 return BAD_KEY_INSTANCE
;
41 if ((direction
== DIR_ENCRYPT
) || (direction
== DIR_DECRYPT
)) {
42 key
->direction
= direction
;
47 if ((keyLen
== 128) || (keyLen
== 192) || (keyLen
== 256)) {
53 if (keyMaterial
!= NULL
) {
54 memcpy(key
->keyMaterial
, keyMaterial
, keyLen
/8);
57 /* initialize key schedule: */
58 if (direction
== DIR_ENCRYPT
) {
59 key
->Nr
= rijndaelKeySetupEnc(key
->rk
, key
->keyMaterial
, keyLen
);
61 key
->Nr
= rijndaelKeySetupDec(key
->rk
, key
->keyMaterial
, keyLen
);
63 rijndaelKeySetupEnc(key
->ek
, key
->keyMaterial
, keyLen
);
67 int rijndael_cipherInit(cipherInstance
*cipher
, BYTE mode
, char *IV
) {
68 if ((mode
== MODE_ECB
) || (mode
== MODE_CBC
) || (mode
== MODE_CFB1
)) {
71 return BAD_CIPHER_MODE
;
74 memcpy(cipher
->IV
, IV
, RIJNDAEL_MAX_IV_SIZE
);
76 memset(cipher
->IV
, 0, RIJNDAEL_MAX_IV_SIZE
);
81 int rijndael_blockEncrypt(cipherInstance
*cipher
, keyInstance
*key
,
82 const BYTE
*input
, int inputLen
, BYTE
*outBuffer
) {
84 uint8_t block
[16], iv
[4][4];
88 key
->direction
== DIR_DECRYPT
) {
89 return BAD_CIPHER_STATE
;
91 if (input
== NULL
|| inputLen
<= 0) {
92 return 0; /* nothing to do */
95 numBlocks
= inputLen
/128;
97 switch (cipher
->mode
) {
99 for (i
= numBlocks
; i
> 0; i
--) {
100 rijndaelEncrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
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];
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];
120 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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];
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];
137 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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
,
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);
181 return BAD_CIPHER_STATE
;
184 explicit_bzero(block
, sizeof(block
));
185 return 128*numBlocks
;
189 * Encrypt data partitioned in octets, using RFC 2040-like padding.
191 * @param input data to be encrypted (octet sequence)
192 * @param inputOctets input length in octets (not bits)
193 * @param outBuffer encrypted output data
195 * @return length in octets (not bits) of the encrypted output buffer.
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
;
202 if (cipher
== NULL
||
204 key
->direction
== DIR_DECRYPT
) {
205 return BAD_CIPHER_STATE
;
207 if (input
== NULL
|| inputOctets
<= 0) {
208 return 0; /* nothing to do */
211 numBlocks
= inputOctets
/16;
213 switch (cipher
->mode
) {
215 for (i
= numBlocks
; i
> 0; i
--) {
216 rijndaelEncrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
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
++)
226 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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
);
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
];
247 for (i
= 16 - padLen
; i
< 16; i
++) {
248 block
[i
] = (BYTE
)padLen
^ iv
[i
];
250 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
254 return BAD_CIPHER_STATE
;
257 explicit_bzero(block
, sizeof(block
));
258 return 16*(numBlocks
+ 1);
261 int rijndael_blockDecrypt(cipherInstance
*cipher
, keyInstance
*key
,
262 const BYTE
*input
, int inputLen
, BYTE
*outBuffer
) {
264 uint8_t block
[16], iv
[4][4];
266 if (cipher
== NULL
||
268 (cipher
->mode
!= MODE_CFB1
&& key
->direction
== DIR_ENCRYPT
)) {
269 return BAD_CIPHER_STATE
;
271 if (input
== NULL
|| inputLen
<= 0) {
272 return 0; /* nothing to do */
275 numBlocks
= inputLen
/128;
277 switch (cipher
->mode
) {
279 for (i
= numBlocks
; i
> 0; i
--) {
280 rijndaelDecrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
287 #if 1 /*STRICT_ALIGN */
288 memcpy(iv
, cipher
->IV
, 16);
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));
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);
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];
316 #if 1 /*STRICT_ALIGN */
317 memcpy(iv
, cipher
->IV
, 16);
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));
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
,
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);
354 return BAD_CIPHER_STATE
;
357 explicit_bzero(block
, sizeof(block
));
358 return 128*numBlocks
;
361 int rijndael_padDecrypt(cipherInstance
*cipher
, keyInstance
*key
,
362 const BYTE
*input
, int inputOctets
, BYTE
*outBuffer
) {
363 int i
, numBlocks
, padLen
, rval
;
367 if (cipher
== NULL
||
369 key
->direction
== DIR_ENCRYPT
) {
370 return BAD_CIPHER_STATE
;
372 if (input
== NULL
|| inputOctets
<= 0) {
373 return 0; /* nothing to do */
375 if (inputOctets
% 16 != 0) {
379 numBlocks
= inputOctets
/16;
381 switch (cipher
->mode
) {
383 /* all blocks but last */
384 for (i
= numBlocks
- 1; i
> 0; i
--) {
385 rijndaelDecrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
390 rijndaelDecrypt(key
->rk
, key
->Nr
, input
, block
);
396 for (i
= 16 - padLen
; i
< 16; i
++) {
397 if (block
[i
] != padLen
) {
402 memcpy(outBuffer
, block
, 16 - padLen
);
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);
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];
426 if (padLen
<= 0 || padLen
> 16) {
430 for (i
= 16 - padLen
; i
< 16; i
++) {
431 if (block
[i
] != padLen
) {
436 memcpy(outBuffer
, block
, 16 - padLen
);
440 return BAD_CIPHER_STATE
;
443 rval
= 16*numBlocks
- padLen
;
446 explicit_bzero(block
, sizeof(block
));