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 $ */
5 * rijndael-api-fst.c v2.3 April '2000
7 * Optimised ANSI C code
9 * authors: v1.0: Antoon Bosselaers
10 * v2.0: Vincent Rijmen
11 * v2.1: Vincent Rijmen
12 * v2.2: Vincent Rijmen
14 * v2.4: Vincent Rijmen
16 * This code is placed in the public domain.
19 #include <sys/param.h>
21 #include <sys/systm.h>
26 #include <crypto/rijndael/rijndael_local.h>
27 #include <crypto/rijndael/rijndael-api-fst.h>
33 typedef u_int8_t BYTE
;
35 int rijndael_makeKey(keyInstance
*key
, BYTE direction
, int keyLen
, char *keyMaterial
) {
36 u_int8_t cipherKey
[RIJNDAEL_MAXKB
];
39 return BAD_KEY_INSTANCE
;
42 if ((direction
== DIR_ENCRYPT
) || (direction
== DIR_DECRYPT
)) {
43 key
->direction
= direction
;
48 if ((keyLen
== 128) || (keyLen
== 192) || (keyLen
== 256)) {
54 if (keyMaterial
!= NULL
) {
55 memcpy(key
->keyMaterial
, keyMaterial
, keyLen
/8);
58 /* initialize key schedule: */
59 memcpy(cipherKey
, key
->keyMaterial
, keyLen
/8);
60 if (direction
== DIR_ENCRYPT
) {
61 key
->Nr
= rijndaelKeySetupEnc(key
->rk
, cipherKey
, keyLen
);
63 key
->Nr
= rijndaelKeySetupDec(key
->rk
, cipherKey
, keyLen
);
65 rijndaelKeySetupEnc(key
->ek
, cipherKey
, keyLen
);
69 int rijndael_cipherInit(cipherInstance
*cipher
, BYTE mode
, char *IV
) {
70 if ((mode
== MODE_ECB
) || (mode
== MODE_CBC
) || (mode
== MODE_CFB1
)) {
73 return BAD_CIPHER_MODE
;
76 memcpy(cipher
->IV
, IV
, RIJNDAEL_MAX_IV_SIZE
);
78 memset(cipher
->IV
, 0, RIJNDAEL_MAX_IV_SIZE
);
83 int rijndael_blockEncrypt(cipherInstance
*cipher
, keyInstance
*key
,
84 BYTE
*input
, int inputLen
, BYTE
*outBuffer
) {
86 u_int8_t block
[16], iv
[4][4];
90 key
->direction
== DIR_DECRYPT
) {
91 return BAD_CIPHER_STATE
;
93 if (input
== NULL
|| inputLen
<= 0) {
94 return 0; /* nothing to do */
97 numBlocks
= inputLen
/128;
99 switch (cipher
->mode
) {
101 for (i
= numBlocks
; i
> 0; i
--) {
102 rijndaelEncrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
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];
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];
122 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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];
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];
139 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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
,
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);
183 return BAD_CIPHER_STATE
;
186 return 128*numBlocks
;
190 * Encrypt data partitioned in octets, using RFC 2040-like padding.
192 * @param input data to be encrypted (octet sequence)
193 * @param inputOctets input length in octets (not bits)
194 * @param outBuffer encrypted output data
196 * @return length in octets (not bits) of the encrypted output buffer.
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
;
203 if (cipher
== NULL
||
205 key
->direction
== DIR_DECRYPT
) {
206 return BAD_CIPHER_STATE
;
208 if (input
== NULL
|| inputOctets
<= 0) {
209 return 0; /* nothing to do */
212 numBlocks
= inputOctets
/16;
214 switch (cipher
->mode
) {
216 for (i
= numBlocks
; i
> 0; i
--) {
217 rijndaelEncrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
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
++)
227 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
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
);
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
];
248 for (i
= 16 - padLen
; i
< 16; i
++) {
249 block
[i
] = (BYTE
)padLen
^ iv
[i
];
251 rijndaelEncrypt(key
->rk
, key
->Nr
, block
, outBuffer
);
255 return BAD_CIPHER_STATE
;
258 return 16*(numBlocks
+ 1);
261 int rijndael_blockDecrypt(cipherInstance
*cipher
, keyInstance
*key
,
262 BYTE
*input
, int inputLen
, BYTE
*outBuffer
) {
264 u_int8_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 *((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));
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);
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];
316 #if 1 /*STRICT_ALIGN */
317 memcpy(iv
, cipher
->IV
, 16);
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));
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
,
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 return 128*numBlocks
;
360 int rijndael_padDecrypt(cipherInstance
*cipher
, keyInstance
*key
,
361 BYTE
*input
, int inputOctets
, BYTE
*outBuffer
) {
362 int i
, numBlocks
, padLen
;
366 if (cipher
== NULL
||
368 key
->direction
== DIR_ENCRYPT
) {
369 return BAD_CIPHER_STATE
;
371 if (input
== NULL
|| inputOctets
<= 0) {
372 return 0; /* nothing to do */
374 if (inputOctets
% 16 != 0) {
378 numBlocks
= inputOctets
/16;
380 switch (cipher
->mode
) {
382 /* all blocks but last */
383 for (i
= numBlocks
- 1; i
> 0; i
--) {
384 rijndaelDecrypt(key
->rk
, key
->Nr
, input
, outBuffer
);
389 rijndaelDecrypt(key
->rk
, key
->Nr
, input
, block
);
394 for (i
= 16 - padLen
; i
< 16; i
++) {
395 if (block
[i
] != padLen
) {
399 memcpy(outBuffer
, block
, 16 - padLen
);
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);
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];
423 if (padLen
<= 0 || padLen
> 16) {
426 for (i
= 16 - padLen
; i
< 16; i
++) {
427 if (block
[i
] != padLen
) {
431 memcpy(outBuffer
, block
, 16 - padLen
);
435 return BAD_CIPHER_STATE
;
438 return 16*numBlocks
- padLen
;