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/param.h>
19#ifdef _KERNEL
20#include <sys/systm.h>
21#else
22#include <string.h>
23#endif
24
25#include <crypto/rijndael/rijndael_local.h>
26#include <crypto/rijndael/rijndael-api-fst.h>
27
28#ifndef TRUE
29#define TRUE 1
30#endif
31
32typedef uint8_t	BYTE;
33
34int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
35	const char *keyMaterial) {
36
37	if (key == NULL) {
38		return BAD_KEY_INSTANCE;
39	}
40
41	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
42		key->direction = direction;
43	} else {
44		return BAD_KEY_DIR;
45	}
46
47	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
48		key->keyLen = keyLen;
49	} else {
50		return BAD_KEY_MAT;
51	}
52
53	if (keyMaterial != NULL) {
54		memcpy(key->keyMaterial, keyMaterial, keyLen/8);
55	}
56
57	/* initialize key schedule: */
58	if (direction == DIR_ENCRYPT) {
59		key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen);
60	} else {
61		key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen);
62	}
63	rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen);
64	return TRUE;
65}
66
67int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
68	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
69		cipher->mode = mode;
70	} else {
71		return BAD_CIPHER_MODE;
72	}
73	if (IV != NULL) {
74		memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
75	} else {
76		memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
77	}
78	return TRUE;
79}
80
81int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
82		const BYTE *input, int inputLen, BYTE *outBuffer) {
83	int i, k, numBlocks;
84	uint8_t block[16], iv[4][4];
85
86	if (cipher == NULL ||
87		key == NULL ||
88		key->direction == DIR_DECRYPT) {
89		return BAD_CIPHER_STATE;
90	}
91	if (input == NULL || inputLen <= 0) {
92		return 0; /* nothing to do */
93	}
94
95	numBlocks = inputLen/128;
96
97	switch (cipher->mode) {
98	case MODE_ECB:
99		for (i = numBlocks; i > 0; i--) {
100			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
101			input += 16;
102			outBuffer += 16;
103		}
104		break;
105
106	case MODE_CBC:
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];
114#else
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];
119#endif
120		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
121		input += 16;
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];
130#else
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];
135#endif
136			outBuffer += 16;
137			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
138			input += 16;
139		}
140		break;
141
142	case MODE_CFB1:
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,
158				    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);
176			}
177		}
178		break;
179
180	default:
181		return BAD_CIPHER_STATE;
182	}
183
184	explicit_bzero(block, sizeof(block));
185	return 128*numBlocks;
186}
187
188/**
189 * Encrypt data partitioned in octets, using RFC 2040-like padding.
190 *
191 * @param   input           data to be encrypted (octet sequence)
192 * @param   inputOctets		input length in octets (not bits)
193 * @param   outBuffer       encrypted output data
194 *
195 * @return	length in octets (not bits) of the encrypted output buffer.
196 */
197int 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;
201
202	if (cipher == NULL ||
203		key == NULL ||
204		key->direction == DIR_DECRYPT) {
205		return BAD_CIPHER_STATE;
206	}
207	if (input == NULL || inputOctets <= 0) {
208		return 0; /* nothing to do */
209	}
210
211	numBlocks = inputOctets/16;
212
213	switch (cipher->mode) {
214	case MODE_ECB:
215		for (i = numBlocks; i > 0; i--) {
216			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
217			input += 16;
218			outBuffer += 16;
219		}
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++)
225			*cp = padLen;
226		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
227		break;
228
229	case MODE_CBC:
230		iv = cipher->IV;
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);
237			iv = outBuffer;
238			input += 16;
239			outBuffer += 16;
240		}
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];
246		}
247		for (i = 16 - padLen; i < 16; i++) {
248			block[i] = (BYTE)padLen ^ iv[i];
249		}
250		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
251		break;
252
253	default:
254		return BAD_CIPHER_STATE;
255	}
256
257	explicit_bzero(block, sizeof(block));
258	return 16*(numBlocks + 1);
259}
260
261int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
262		const BYTE *input, int inputLen, BYTE *outBuffer) {
263	int i, k, numBlocks;
264	uint8_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		*((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));
294#endif
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);
304#else
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];
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		*((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));
323#endif
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,
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	explicit_bzero(block, sizeof(block));
358	return 128*numBlocks;
359}
360
361int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
362		const BYTE *input, int inputOctets, BYTE *outBuffer) {
363	int i, numBlocks, padLen, rval;
364	uint8_t block[16];
365	uint32_t iv[4];
366
367	if (cipher == NULL ||
368		key == NULL ||
369		key->direction == DIR_ENCRYPT) {
370		return BAD_CIPHER_STATE;
371	}
372	if (input == NULL || inputOctets <= 0) {
373		return 0; /* nothing to do */
374	}
375	if (inputOctets % 16 != 0) {
376		return BAD_DATA;
377	}
378
379	numBlocks = inputOctets/16;
380
381	switch (cipher->mode) {
382	case MODE_ECB:
383		/* all blocks but last */
384		for (i = numBlocks - 1; i > 0; i--) {
385			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
386			input += 16;
387			outBuffer += 16;
388		}
389		/* last block */
390		rijndaelDecrypt(key->rk, key->Nr, input, block);
391		padLen = block[15];
392		if (padLen >= 16) {
393			rval = BAD_DATA;
394			goto out;
395		}
396		for (i = 16 - padLen; i < 16; i++) {
397			if (block[i] != padLen) {
398				rval = BAD_DATA;
399				goto out;
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			((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);
416			input += 16;
417			outBuffer += 16;
418		}
419		/* last block */
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];
425		padLen = block[15];
426		if (padLen <= 0 || padLen > 16) {
427			rval = BAD_DATA;
428			goto out;
429		}
430		for (i = 16 - padLen; i < 16; i++) {
431			if (block[i] != padLen) {
432				rval = BAD_DATA;
433				goto out;
434			}
435		}
436		memcpy(outBuffer, block, 16 - padLen);
437		break;
438
439	default:
440		return BAD_CIPHER_STATE;
441	}
442
443	rval = 16*numBlocks - padLen;
444
445out:
446	explicit_bzero(block, sizeof(block));
447	return rval;
448}
449