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