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 }
440