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/cdefs.h>
19__FBSDID("$FreeBSD$");
20
21#include <sys/param.h>
22#ifdef _KERNEL
23#include <sys/systm.h>
24#else
25#include <string.h>
26#endif
27
28#include <crypto/rijndael/rijndael_local.h>
29#include <crypto/rijndael/rijndael-api-fst.h>
30
31#ifndef TRUE
32#define TRUE 1
33#endif
34
35typedef u_int8_t	BYTE;
36
37int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
38	const char *keyMaterial) {
39	u_int8_t cipherKey[RIJNDAEL_MAXKB];
40
41	if (key == NULL) {
42		return BAD_KEY_INSTANCE;
43	}
44
45	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
46		key->direction = direction;
47	} else {
48		return BAD_KEY_DIR;
49	}
50
51	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
52		key->keyLen = keyLen;
53	} else {
54		return BAD_KEY_MAT;
55	}
56
57	if (keyMaterial != NULL) {
58		memcpy(key->keyMaterial, keyMaterial, keyLen/8);
59	}
60
61	/* initialize key schedule: */
62	memcpy(cipherKey, key->keyMaterial, keyLen/8);
63	if (direction == DIR_ENCRYPT) {
64		key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
65	} else {
66		key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
67	}
68	rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
69	return TRUE;
70}
71
72int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
73	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
74		cipher->mode = mode;
75	} else {
76		return BAD_CIPHER_MODE;
77	}
78	if (IV != NULL) {
79		memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
80	} else {
81		memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
82	}
83	return TRUE;
84}
85
86int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
87		const BYTE *input, int inputLen, BYTE *outBuffer) {
88	int i, k, numBlocks;
89	u_int8_t block[16], iv[4][4];
90
91	if (cipher == NULL ||
92		key == NULL ||
93		key->direction == DIR_DECRYPT) {
94		return BAD_CIPHER_STATE;
95	}
96	if (input == NULL || inputLen <= 0) {
97		return 0; /* nothing to do */
98	}
99
100	numBlocks = inputLen/128;
101
102	switch (cipher->mode) {
103	case MODE_ECB:
104		for (i = numBlocks; i > 0; i--) {
105			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
106			input += 16;
107			outBuffer += 16;
108		}
109		break;
110
111	case MODE_CBC:
112#if 1 /*STRICT_ALIGN*/
113		memcpy(block, cipher->IV, 16);
114		memcpy(iv, input, 16);
115		((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
116		((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
117		((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
118		((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
119#else
120		((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0];
121		((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1];
122		((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2];
123		((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3];
124#endif
125		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
126		input += 16;
127		for (i = numBlocks - 1; i > 0; i--) {
128#if 1 /*STRICT_ALIGN*/
129			memcpy(block, outBuffer, 16);
130			memcpy(iv, input, 16);
131			((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
132			((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
133			((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
134			((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
135#else
136			((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0];
137			((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1];
138			((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2];
139			((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3];
140#endif
141			outBuffer += 16;
142			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
143			input += 16;
144		}
145		break;
146
147	case MODE_CFB1:
148#if 1 /*STRICT_ALIGN*/
149		memcpy(iv, cipher->IV, 16);
150#else  /* !STRICT_ALIGN */
151		*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
152		*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
153		*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
154		*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
155#endif /* ?STRICT_ALIGN */
156		for (i = numBlocks; i > 0; i--) {
157			for (k = 0; k < 128; k++) {
158				*((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
159				*((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
160				*((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
161				*((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
162				rijndaelEncrypt(key->ek, key->Nr, block,
163				    block);
164				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
165				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
166				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
167				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
168				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
169				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
170				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
171				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
172				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
173				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
174				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
175				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
176				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
177				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
178				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
179				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
180				iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
181			}
182		}
183		break;
184
185	default:
186		return BAD_CIPHER_STATE;
187	}
188
189	return 128*numBlocks;
190}
191
192/**
193 * Encrypt data partitioned in octets, using RFC 2040-like padding.
194 *
195 * @param   input           data to be encrypted (octet sequence)
196 * @param   inputOctets		input length in octets (not bits)
197 * @param   outBuffer       encrypted output data
198 *
199 * @return	length in octets (not bits) of the encrypted output buffer.
200 */
201int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
202		const BYTE *input, int inputOctets, BYTE *outBuffer) {
203	int i, numBlocks, padLen;
204	u_int8_t block[16], *iv, *cp;
205
206	if (cipher == NULL ||
207		key == NULL ||
208		key->direction == DIR_DECRYPT) {
209		return BAD_CIPHER_STATE;
210	}
211	if (input == NULL || inputOctets <= 0) {
212		return 0; /* nothing to do */
213	}
214
215	numBlocks = inputOctets/16;
216
217	switch (cipher->mode) {
218	case MODE_ECB:
219		for (i = numBlocks; i > 0; i--) {
220			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
221			input += 16;
222			outBuffer += 16;
223		}
224		padLen = 16 - (inputOctets - 16*numBlocks);
225		if (padLen <= 0 || padLen > 16)
226			return BAD_CIPHER_STATE;
227		memcpy(block, input, 16 - padLen);
228		for (cp = block + 16 - padLen; cp < block + 16; cp++)
229			*cp = padLen;
230		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
231		break;
232
233	case MODE_CBC:
234		iv = cipher->IV;
235		for (i = numBlocks; i > 0; i--) {
236			((u_int32_t*)block)[0] = ((const u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
237			((u_int32_t*)block)[1] = ((const u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
238			((u_int32_t*)block)[2] = ((const u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
239			((u_int32_t*)block)[3] = ((const u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
240			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
241			iv = outBuffer;
242			input += 16;
243			outBuffer += 16;
244		}
245		padLen = 16 - (inputOctets - 16*numBlocks);
246		if (padLen <= 0 || padLen > 16)
247			return BAD_CIPHER_STATE;
248		for (i = 0; i < 16 - padLen; i++) {
249			block[i] = input[i] ^ iv[i];
250		}
251		for (i = 16 - padLen; i < 16; i++) {
252			block[i] = (BYTE)padLen ^ iv[i];
253		}
254		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
255		break;
256
257	default:
258		return BAD_CIPHER_STATE;
259	}
260
261	return 16*(numBlocks + 1);
262}
263
264int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
265		const BYTE *input, int inputLen, BYTE *outBuffer) {
266	int i, k, numBlocks;
267	u_int8_t block[16], iv[4][4];
268
269	if (cipher == NULL ||
270		key == NULL ||
271		(cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
272		return BAD_CIPHER_STATE;
273	}
274	if (input == NULL || inputLen <= 0) {
275		return 0; /* nothing to do */
276	}
277
278	numBlocks = inputLen/128;
279
280	switch (cipher->mode) {
281	case MODE_ECB:
282		for (i = numBlocks; i > 0; i--) {
283			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
284			input += 16;
285			outBuffer += 16;
286		}
287		break;
288
289	case MODE_CBC:
290#if 1 /*STRICT_ALIGN */
291		memcpy(iv, cipher->IV, 16);
292#else
293		*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV   ));
294		*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
295		*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
296		*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
297#endif
298		for (i = numBlocks; i > 0; i--) {
299			rijndaelDecrypt(key->rk, key->Nr, input, block);
300			((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]);
301			((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]);
302			((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]);
303			((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]);
304#if 1 /*STRICT_ALIGN*/
305			memcpy(iv, input, 16);
306			memcpy(outBuffer, block, 16);
307#else
308			*((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0];
309			*((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1];
310			*((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2];
311			*((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_t*)block)[3];
312#endif
313			input += 16;
314			outBuffer += 16;
315		}
316		break;
317
318	case MODE_CFB1:
319#if 1 /*STRICT_ALIGN */
320		memcpy(iv, cipher->IV, 16);
321#else
322		*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV));
323		*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
324		*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
325		*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
326#endif
327		for (i = numBlocks; i > 0; i--) {
328			for (k = 0; k < 128; k++) {
329				*((u_int32_t*) block    ) = *((u_int32_t*)iv[0]);
330				*((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
331				*((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
332				*((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
333				rijndaelEncrypt(key->ek, key->Nr, block,
334				    block);
335				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
336				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
337				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
338				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
339				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
340				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
341				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
342				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
343				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
344				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
345				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
346				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
347				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
348				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
349				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
350				iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
351				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
352			}
353		}
354		break;
355
356	default:
357		return BAD_CIPHER_STATE;
358	}
359
360	return 128*numBlocks;
361}
362
363int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
364		const BYTE *input, int inputOctets, BYTE *outBuffer) {
365	int i, numBlocks, padLen;
366	u_int8_t block[16];
367	u_int32_t iv[4];
368
369	if (cipher == NULL ||
370		key == NULL ||
371		key->direction == DIR_ENCRYPT) {
372		return BAD_CIPHER_STATE;
373	}
374	if (input == NULL || inputOctets <= 0) {
375		return 0; /* nothing to do */
376	}
377	if (inputOctets % 16 != 0) {
378		return BAD_DATA;
379	}
380
381	numBlocks = inputOctets/16;
382
383	switch (cipher->mode) {
384	case MODE_ECB:
385		/* all blocks but last */
386		for (i = numBlocks - 1; i > 0; i--) {
387			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
388			input += 16;
389			outBuffer += 16;
390		}
391		/* last block */
392		rijndaelDecrypt(key->rk, key->Nr, input, block);
393		padLen = block[15];
394		if (padLen >= 16) {
395			return BAD_DATA;
396		}
397		for (i = 16 - padLen; i < 16; i++) {
398			if (block[i] != padLen) {
399				return BAD_DATA;
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			((u_int32_t*)block)[0] ^= iv[0];
411			((u_int32_t*)block)[1] ^= iv[1];
412			((u_int32_t*)block)[2] ^= iv[2];
413			((u_int32_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		((u_int32_t*)block)[0] ^= iv[0];
422		((u_int32_t*)block)[1] ^= iv[1];
423		((u_int32_t*)block)[2] ^= iv[2];
424		((u_int32_t*)block)[3] ^= iv[3];
425		padLen = block[15];
426		if (padLen <= 0 || padLen > 16) {
427			return BAD_DATA;
428		}
429		for (i = 16 - padLen; i < 16; i++) {
430			if (block[i] != padLen) {
431				return BAD_DATA;
432			}
433		}
434		memcpy(outBuffer, block, 16 - padLen);
435		break;
436
437	default:
438		return BAD_CIPHER_STATE;
439	}
440
441	return 16*numBlocks - padLen;
442}
443