xref: /freebsd/sys/crypto/rijndael/rijndael-api-fst.c (revision d3d79e968b67cc9a9855f9a29cf72763dec3578d)
19132d507SHajimu UMEMOTO /*	$KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $	*/
2fe2869c8SKris Kennaway 
39132d507SHajimu UMEMOTO /*
49132d507SHajimu UMEMOTO  * rijndael-api-fst.c   v2.3   April '2000
5fe2869c8SKris Kennaway  *
69132d507SHajimu UMEMOTO  * Optimised ANSI C code
7fe2869c8SKris Kennaway  *
89132d507SHajimu UMEMOTO  * authors: v1.0: Antoon Bosselaers
99132d507SHajimu UMEMOTO  *          v2.0: Vincent Rijmen
109132d507SHajimu UMEMOTO  *          v2.1: Vincent Rijmen
119132d507SHajimu UMEMOTO  *          v2.2: Vincent Rijmen
129132d507SHajimu UMEMOTO  *          v2.3: Paulo Barreto
139132d507SHajimu UMEMOTO  *          v2.4: Vincent Rijmen
14fe2869c8SKris Kennaway  *
159132d507SHajimu UMEMOTO  * This code is placed in the public domain.
16fe2869c8SKris Kennaway  */
17fe2869c8SKris Kennaway 
18ad39da78SDavid E. O'Brien #include <sys/cdefs.h>
19ad39da78SDavid E. O'Brien __FBSDID("$FreeBSD$");
20ad39da78SDavid E. O'Brien 
21fe2869c8SKris Kennaway #include <sys/param.h>
2233841545SHajimu UMEMOTO #ifdef _KERNEL
2333841545SHajimu UMEMOTO #include <sys/systm.h>
2433841545SHajimu UMEMOTO #else
2533841545SHajimu UMEMOTO #include <string.h>
2633841545SHajimu UMEMOTO #endif
275129dcfcSHajimu UMEMOTO 
285129dcfcSHajimu UMEMOTO #include <crypto/rijndael/rijndael_local.h>
29fe2869c8SKris Kennaway #include <crypto/rijndael/rijndael-api-fst.h>
309132d507SHajimu UMEMOTO 
319132d507SHajimu UMEMOTO #ifndef TRUE
329132d507SHajimu UMEMOTO #define TRUE 1
339132d507SHajimu UMEMOTO #endif
349132d507SHajimu UMEMOTO 
35*d3d79e96SJohn Baldwin typedef uint8_t	BYTE;
3627da1009SPoul-Henning Kamp 
37133cdd9eSDag-Erling Smørgrav int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
38133cdd9eSDag-Erling Smørgrav 	const char *keyMaterial) {
39fe2869c8SKris Kennaway 
40fe2869c8SKris Kennaway 	if (key == NULL) {
41fe2869c8SKris Kennaway 		return BAD_KEY_INSTANCE;
42fe2869c8SKris Kennaway 	}
43fe2869c8SKris Kennaway 
44fe2869c8SKris Kennaway 	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
45fe2869c8SKris Kennaway 		key->direction = direction;
46fe2869c8SKris Kennaway 	} else {
47fe2869c8SKris Kennaway 		return BAD_KEY_DIR;
48fe2869c8SKris Kennaway 	}
49fe2869c8SKris Kennaway 
50fe2869c8SKris Kennaway 	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
51fe2869c8SKris Kennaway 		key->keyLen = keyLen;
52fe2869c8SKris Kennaway 	} else {
53fe2869c8SKris Kennaway 		return BAD_KEY_MAT;
54fe2869c8SKris Kennaway 	}
55fe2869c8SKris Kennaway 
56fe2869c8SKris Kennaway 	if (keyMaterial != NULL) {
575129dcfcSHajimu UMEMOTO 		memcpy(key->keyMaterial, keyMaterial, keyLen/8);
58fe2869c8SKris Kennaway 	}
59fe2869c8SKris Kennaway 
60fe2869c8SKris Kennaway 	/* initialize key schedule: */
615129dcfcSHajimu UMEMOTO 	if (direction == DIR_ENCRYPT) {
6207024904SConrad Meyer 		key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen);
635129dcfcSHajimu UMEMOTO 	} else {
6407024904SConrad Meyer 		key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen);
65fe2869c8SKris Kennaway 	}
6607024904SConrad Meyer 	rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen);
67fe2869c8SKris Kennaway 	return TRUE;
68fe2869c8SKris Kennaway }
69fe2869c8SKris Kennaway 
70fe2869c8SKris Kennaway int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
71fe2869c8SKris Kennaway 	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
72fe2869c8SKris Kennaway 		cipher->mode = mode;
73fe2869c8SKris Kennaway 	} else {
74fe2869c8SKris Kennaway 		return BAD_CIPHER_MODE;
75fe2869c8SKris Kennaway 	}
76fe2869c8SKris Kennaway 	if (IV != NULL) {
775129dcfcSHajimu UMEMOTO 		memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
78fe2869c8SKris Kennaway 	} else {
795129dcfcSHajimu UMEMOTO 		memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
80fe2869c8SKris Kennaway 	}
81fe2869c8SKris Kennaway 	return TRUE;
82fe2869c8SKris Kennaway }
83fe2869c8SKris Kennaway 
84fe2869c8SKris Kennaway int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
85133cdd9eSDag-Erling Smørgrav 		const BYTE *input, int inputLen, BYTE *outBuffer) {
869132d507SHajimu UMEMOTO 	int i, k, numBlocks;
87*d3d79e96SJohn Baldwin 	uint8_t block[16], iv[4][4];
88fe2869c8SKris Kennaway 
89fe2869c8SKris Kennaway 	if (cipher == NULL ||
90fe2869c8SKris Kennaway 		key == NULL ||
91fe2869c8SKris Kennaway 		key->direction == DIR_DECRYPT) {
92fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
93fe2869c8SKris Kennaway 	}
94fe2869c8SKris Kennaway 	if (input == NULL || inputLen <= 0) {
95fe2869c8SKris Kennaway 		return 0; /* nothing to do */
96fe2869c8SKris Kennaway 	}
97fe2869c8SKris Kennaway 
98fe2869c8SKris Kennaway 	numBlocks = inputLen/128;
99fe2869c8SKris Kennaway 
100fe2869c8SKris Kennaway 	switch (cipher->mode) {
101fe2869c8SKris Kennaway 	case MODE_ECB:
102fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
1035129dcfcSHajimu UMEMOTO 			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
104fe2869c8SKris Kennaway 			input += 16;
105fe2869c8SKris Kennaway 			outBuffer += 16;
106fe2869c8SKris Kennaway 		}
107fe2869c8SKris Kennaway 		break;
108fe2869c8SKris Kennaway 
109fe2869c8SKris Kennaway 	case MODE_CBC:
1103011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1115129dcfcSHajimu UMEMOTO 		memcpy(block, cipher->IV, 16);
1125129dcfcSHajimu UMEMOTO 		memcpy(iv, input, 16);
113*d3d79e96SJohn Baldwin 		((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
114*d3d79e96SJohn Baldwin 		((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
115*d3d79e96SJohn Baldwin 		((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
116*d3d79e96SJohn Baldwin 		((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
1173011d4b3SHajimu UMEMOTO #else
118*d3d79e96SJohn Baldwin 		((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0];
119*d3d79e96SJohn Baldwin 		((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1];
120*d3d79e96SJohn Baldwin 		((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2];
121*d3d79e96SJohn Baldwin 		((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3];
1223011d4b3SHajimu UMEMOTO #endif
1235129dcfcSHajimu UMEMOTO 		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
124fe2869c8SKris Kennaway 		input += 16;
1259132d507SHajimu UMEMOTO 		for (i = numBlocks - 1; i > 0; i--) {
1269132d507SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1275129dcfcSHajimu UMEMOTO 			memcpy(block, outBuffer, 16);
1285129dcfcSHajimu UMEMOTO 			memcpy(iv, input, 16);
129*d3d79e96SJohn Baldwin 			((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
130*d3d79e96SJohn Baldwin 			((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
131*d3d79e96SJohn Baldwin 			((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
132*d3d79e96SJohn Baldwin 			((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
1339132d507SHajimu UMEMOTO #else
134*d3d79e96SJohn Baldwin 			((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0];
135*d3d79e96SJohn Baldwin 			((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1];
136*d3d79e96SJohn Baldwin 			((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2];
137*d3d79e96SJohn Baldwin 			((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3];
1389132d507SHajimu UMEMOTO #endif
139fe2869c8SKris Kennaway 			outBuffer += 16;
1405129dcfcSHajimu UMEMOTO 			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
1419132d507SHajimu UMEMOTO 			input += 16;
142fe2869c8SKris Kennaway 		}
143fe2869c8SKris Kennaway 		break;
144fe2869c8SKris Kennaway 
145fe2869c8SKris Kennaway 	case MODE_CFB1:
1463011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1475129dcfcSHajimu UMEMOTO 		memcpy(iv, cipher->IV, 16);
1489132d507SHajimu UMEMOTO #else  /* !STRICT_ALIGN */
149*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV   ));
150*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
151*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
152*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
1539132d507SHajimu UMEMOTO #endif /* ?STRICT_ALIGN */
154fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
155fe2869c8SKris Kennaway 			for (k = 0; k < 128; k++) {
156*d3d79e96SJohn Baldwin 				*((uint32_t*) block    ) = *((uint32_t*)iv[0]);
157*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
158*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
159*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
1605129dcfcSHajimu UMEMOTO 				rijndaelEncrypt(key->ek, key->Nr, block,
1615129dcfcSHajimu UMEMOTO 				    block);
1629132d507SHajimu UMEMOTO 				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
1639132d507SHajimu UMEMOTO 				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
1649132d507SHajimu UMEMOTO 				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
1659132d507SHajimu UMEMOTO 				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
1669132d507SHajimu UMEMOTO 				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
1679132d507SHajimu UMEMOTO 				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
1689132d507SHajimu UMEMOTO 				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
1699132d507SHajimu UMEMOTO 				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
1709132d507SHajimu UMEMOTO 				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
1719132d507SHajimu UMEMOTO 				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
1729132d507SHajimu UMEMOTO 				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
1739132d507SHajimu UMEMOTO 				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
1749132d507SHajimu UMEMOTO 				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
1759132d507SHajimu UMEMOTO 				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
1769132d507SHajimu UMEMOTO 				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
1779132d507SHajimu UMEMOTO 				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
1789132d507SHajimu UMEMOTO 				iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
179fe2869c8SKris Kennaway 			}
1808f21478bSHajimu UMEMOTO 		}
181fe2869c8SKris Kennaway 		break;
182fe2869c8SKris Kennaway 
183fe2869c8SKris Kennaway 	default:
184fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
185fe2869c8SKris Kennaway 	}
186fe2869c8SKris Kennaway 
18707024904SConrad Meyer 	explicit_bzero(block, sizeof(block));
188fe2869c8SKris Kennaway 	return 128*numBlocks;
189fe2869c8SKris Kennaway }
190fe2869c8SKris Kennaway 
191fe2869c8SKris Kennaway /**
192fe2869c8SKris Kennaway  * Encrypt data partitioned in octets, using RFC 2040-like padding.
193fe2869c8SKris Kennaway  *
194fe2869c8SKris Kennaway  * @param   input           data to be encrypted (octet sequence)
195fe2869c8SKris Kennaway  * @param   inputOctets		input length in octets (not bits)
196fe2869c8SKris Kennaway  * @param   outBuffer       encrypted output data
197fe2869c8SKris Kennaway  *
198fe2869c8SKris Kennaway  * @return	length in octets (not bits) of the encrypted output buffer.
199fe2869c8SKris Kennaway  */
200fe2869c8SKris Kennaway int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
201133cdd9eSDag-Erling Smørgrav 		const BYTE *input, int inputOctets, BYTE *outBuffer) {
202fe2869c8SKris Kennaway 	int i, numBlocks, padLen;
203*d3d79e96SJohn Baldwin 	uint8_t block[16], *iv, *cp;
204fe2869c8SKris Kennaway 
205fe2869c8SKris Kennaway 	if (cipher == NULL ||
206fe2869c8SKris Kennaway 		key == NULL ||
207fe2869c8SKris Kennaway 		key->direction == DIR_DECRYPT) {
208fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
209fe2869c8SKris Kennaway 	}
210fe2869c8SKris Kennaway 	if (input == NULL || inputOctets <= 0) {
211fe2869c8SKris Kennaway 		return 0; /* nothing to do */
212fe2869c8SKris Kennaway 	}
213fe2869c8SKris Kennaway 
214fe2869c8SKris Kennaway 	numBlocks = inputOctets/16;
215fe2869c8SKris Kennaway 
216fe2869c8SKris Kennaway 	switch (cipher->mode) {
217fe2869c8SKris Kennaway 	case MODE_ECB:
218fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
2195129dcfcSHajimu UMEMOTO 			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
220fe2869c8SKris Kennaway 			input += 16;
221fe2869c8SKris Kennaway 			outBuffer += 16;
222fe2869c8SKris Kennaway 		}
223fe2869c8SKris Kennaway 		padLen = 16 - (inputOctets - 16*numBlocks);
224eb159f5bSHajimu UMEMOTO 		if (padLen <= 0 || padLen > 16)
22527da1009SPoul-Henning Kamp 			return BAD_CIPHER_STATE;
2265129dcfcSHajimu UMEMOTO 		memcpy(block, input, 16 - padLen);
2279132d507SHajimu UMEMOTO 		for (cp = block + 16 - padLen; cp < block + 16; cp++)
2289132d507SHajimu UMEMOTO 			*cp = padLen;
2295129dcfcSHajimu UMEMOTO 		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
230fe2869c8SKris Kennaway 		break;
231fe2869c8SKris Kennaway 
232fe2869c8SKris Kennaway 	case MODE_CBC:
233fe2869c8SKris Kennaway 		iv = cipher->IV;
234fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
235*d3d79e96SJohn Baldwin 			((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0];
236*d3d79e96SJohn Baldwin 			((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1];
237*d3d79e96SJohn Baldwin 			((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2];
238*d3d79e96SJohn Baldwin 			((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3];
2395129dcfcSHajimu UMEMOTO 			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
240fe2869c8SKris Kennaway 			iv = outBuffer;
241fe2869c8SKris Kennaway 			input += 16;
242fe2869c8SKris Kennaway 			outBuffer += 16;
243fe2869c8SKris Kennaway 		}
244fe2869c8SKris Kennaway 		padLen = 16 - (inputOctets - 16*numBlocks);
24566476d45SHajimu UMEMOTO 		if (padLen <= 0 || padLen > 16)
24627da1009SPoul-Henning Kamp 			return BAD_CIPHER_STATE;
247fe2869c8SKris Kennaway 		for (i = 0; i < 16 - padLen; i++) {
248fe2869c8SKris Kennaway 			block[i] = input[i] ^ iv[i];
249fe2869c8SKris Kennaway 		}
250fe2869c8SKris Kennaway 		for (i = 16 - padLen; i < 16; i++) {
251fe2869c8SKris Kennaway 			block[i] = (BYTE)padLen ^ iv[i];
252fe2869c8SKris Kennaway 		}
2535129dcfcSHajimu UMEMOTO 		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
254fe2869c8SKris Kennaway 		break;
255fe2869c8SKris Kennaway 
256fe2869c8SKris Kennaway 	default:
257fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
258fe2869c8SKris Kennaway 	}
259fe2869c8SKris Kennaway 
26007024904SConrad Meyer 	explicit_bzero(block, sizeof(block));
261fe2869c8SKris Kennaway 	return 16*(numBlocks + 1);
262fe2869c8SKris Kennaway }
263fe2869c8SKris Kennaway 
264fe2869c8SKris Kennaway int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
265133cdd9eSDag-Erling Smørgrav 		const BYTE *input, int inputLen, BYTE *outBuffer) {
2669132d507SHajimu UMEMOTO 	int i, k, numBlocks;
267*d3d79e96SJohn Baldwin 	uint8_t block[16], iv[4][4];
268fe2869c8SKris Kennaway 
269fe2869c8SKris Kennaway 	if (cipher == NULL ||
270fe2869c8SKris Kennaway 		key == NULL ||
271fe2869c8SKris Kennaway 		(cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
272fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
273fe2869c8SKris Kennaway 	}
274fe2869c8SKris Kennaway 	if (input == NULL || inputLen <= 0) {
275fe2869c8SKris Kennaway 		return 0; /* nothing to do */
276fe2869c8SKris Kennaway 	}
277fe2869c8SKris Kennaway 
278fe2869c8SKris Kennaway 	numBlocks = inputLen/128;
279fe2869c8SKris Kennaway 
280fe2869c8SKris Kennaway 	switch (cipher->mode) {
281fe2869c8SKris Kennaway 	case MODE_ECB:
282fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
2835129dcfcSHajimu UMEMOTO 			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
284fe2869c8SKris Kennaway 			input += 16;
285fe2869c8SKris Kennaway 			outBuffer += 16;
286fe2869c8SKris Kennaway 		}
287fe2869c8SKris Kennaway 		break;
288fe2869c8SKris Kennaway 
289fe2869c8SKris Kennaway 	case MODE_CBC:
2903011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */
2915129dcfcSHajimu UMEMOTO 		memcpy(iv, cipher->IV, 16);
2923011d4b3SHajimu UMEMOTO #else
293*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV   ));
294*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
295*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
296*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
2973011d4b3SHajimu UMEMOTO #endif
298fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
2995129dcfcSHajimu UMEMOTO 			rijndaelDecrypt(key->rk, key->Nr, input, block);
300*d3d79e96SJohn Baldwin 			((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]);
301*d3d79e96SJohn Baldwin 			((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]);
302*d3d79e96SJohn Baldwin 			((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]);
303*d3d79e96SJohn Baldwin 			((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]);
3043011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
3055129dcfcSHajimu UMEMOTO 			memcpy(iv, input, 16);
3065129dcfcSHajimu UMEMOTO 			memcpy(outBuffer, block, 16);
3073011d4b3SHajimu UMEMOTO #else
308*d3d79e96SJohn Baldwin 			*((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0];
309*d3d79e96SJohn Baldwin 			*((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1];
310*d3d79e96SJohn Baldwin 			*((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2];
311*d3d79e96SJohn Baldwin 			*((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3];
3123011d4b3SHajimu UMEMOTO #endif
313fe2869c8SKris Kennaway 			input += 16;
314fe2869c8SKris Kennaway 			outBuffer += 16;
315fe2869c8SKris Kennaway 		}
316fe2869c8SKris Kennaway 		break;
317fe2869c8SKris Kennaway 
318fe2869c8SKris Kennaway 	case MODE_CFB1:
3193011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */
3205129dcfcSHajimu UMEMOTO 		memcpy(iv, cipher->IV, 16);
3213011d4b3SHajimu UMEMOTO #else
322*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV));
323*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
324*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
325*d3d79e96SJohn Baldwin 		*((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
3263011d4b3SHajimu UMEMOTO #endif
327fe2869c8SKris Kennaway 		for (i = numBlocks; i > 0; i--) {
328fe2869c8SKris Kennaway 			for (k = 0; k < 128; k++) {
329*d3d79e96SJohn Baldwin 				*((uint32_t*) block    ) = *((uint32_t*)iv[0]);
330*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
331*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
332*d3d79e96SJohn Baldwin 				*((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
3335129dcfcSHajimu UMEMOTO 				rijndaelEncrypt(key->ek, key->Nr, block,
3345129dcfcSHajimu UMEMOTO 				    block);
3359132d507SHajimu UMEMOTO 				iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
3369132d507SHajimu UMEMOTO 				iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
3379132d507SHajimu UMEMOTO 				iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
3389132d507SHajimu UMEMOTO 				iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
3399132d507SHajimu UMEMOTO 				iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
3409132d507SHajimu UMEMOTO 				iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
3419132d507SHajimu UMEMOTO 				iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
3429132d507SHajimu UMEMOTO 				iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
3439132d507SHajimu UMEMOTO 				iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
3449132d507SHajimu UMEMOTO 				iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
3459132d507SHajimu UMEMOTO 				iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
3469132d507SHajimu UMEMOTO 				iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
3479132d507SHajimu UMEMOTO 				iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
3489132d507SHajimu UMEMOTO 				iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
3499132d507SHajimu UMEMOTO 				iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
3509132d507SHajimu UMEMOTO 				iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
3519132d507SHajimu UMEMOTO 				outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
352fe2869c8SKris Kennaway 			}
3538f21478bSHajimu UMEMOTO 		}
354fe2869c8SKris Kennaway 		break;
355fe2869c8SKris Kennaway 
356fe2869c8SKris Kennaway 	default:
357fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
358fe2869c8SKris Kennaway 	}
359fe2869c8SKris Kennaway 
36007024904SConrad Meyer 	explicit_bzero(block, sizeof(block));
361fe2869c8SKris Kennaway 	return 128*numBlocks;
362fe2869c8SKris Kennaway }
363fe2869c8SKris Kennaway 
364fe2869c8SKris Kennaway int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
365133cdd9eSDag-Erling Smørgrav 		const BYTE *input, int inputOctets, BYTE *outBuffer) {
36607024904SConrad Meyer 	int i, numBlocks, padLen, rval;
367*d3d79e96SJohn Baldwin 	uint8_t block[16];
368*d3d79e96SJohn Baldwin 	uint32_t iv[4];
369fe2869c8SKris Kennaway 
370fe2869c8SKris Kennaway 	if (cipher == NULL ||
371fe2869c8SKris Kennaway 		key == NULL ||
372fe2869c8SKris Kennaway 		key->direction == DIR_ENCRYPT) {
373fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
374fe2869c8SKris Kennaway 	}
375fe2869c8SKris Kennaway 	if (input == NULL || inputOctets <= 0) {
376fe2869c8SKris Kennaway 		return 0; /* nothing to do */
377fe2869c8SKris Kennaway 	}
378fe2869c8SKris Kennaway 	if (inputOctets % 16 != 0) {
379fe2869c8SKris Kennaway 		return BAD_DATA;
380fe2869c8SKris Kennaway 	}
381fe2869c8SKris Kennaway 
382fe2869c8SKris Kennaway 	numBlocks = inputOctets/16;
383fe2869c8SKris Kennaway 
384fe2869c8SKris Kennaway 	switch (cipher->mode) {
385fe2869c8SKris Kennaway 	case MODE_ECB:
386fe2869c8SKris Kennaway 		/* all blocks but last */
387fe2869c8SKris Kennaway 		for (i = numBlocks - 1; i > 0; i--) {
3885129dcfcSHajimu UMEMOTO 			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
389fe2869c8SKris Kennaway 			input += 16;
390fe2869c8SKris Kennaway 			outBuffer += 16;
391fe2869c8SKris Kennaway 		}
392fe2869c8SKris Kennaway 		/* last block */
3935129dcfcSHajimu UMEMOTO 		rijndaelDecrypt(key->rk, key->Nr, input, block);
394fe2869c8SKris Kennaway 		padLen = block[15];
395fe2869c8SKris Kennaway 		if (padLen >= 16) {
39607024904SConrad Meyer 			rval = BAD_DATA;
39707024904SConrad Meyer 			goto out;
398fe2869c8SKris Kennaway 		}
399fe2869c8SKris Kennaway 		for (i = 16 - padLen; i < 16; i++) {
400fe2869c8SKris Kennaway 			if (block[i] != padLen) {
40107024904SConrad Meyer 				rval = BAD_DATA;
40207024904SConrad Meyer 				goto out;
403fe2869c8SKris Kennaway 			}
404fe2869c8SKris Kennaway 		}
4055129dcfcSHajimu UMEMOTO 		memcpy(outBuffer, block, 16 - padLen);
406fe2869c8SKris Kennaway 		break;
407fe2869c8SKris Kennaway 
408fe2869c8SKris Kennaway 	case MODE_CBC:
4095129dcfcSHajimu UMEMOTO 		memcpy(iv, cipher->IV, 16);
410fe2869c8SKris Kennaway 		/* all blocks but last */
411fe2869c8SKris Kennaway 		for (i = numBlocks - 1; i > 0; i--) {
4125129dcfcSHajimu UMEMOTO 			rijndaelDecrypt(key->rk, key->Nr, input, block);
413*d3d79e96SJohn Baldwin 			((uint32_t*)block)[0] ^= iv[0];
414*d3d79e96SJohn Baldwin 			((uint32_t*)block)[1] ^= iv[1];
415*d3d79e96SJohn Baldwin 			((uint32_t*)block)[2] ^= iv[2];
416*d3d79e96SJohn Baldwin 			((uint32_t*)block)[3] ^= iv[3];
4175129dcfcSHajimu UMEMOTO 			memcpy(iv, input, 16);
4185129dcfcSHajimu UMEMOTO 			memcpy(outBuffer, block, 16);
419fe2869c8SKris Kennaway 			input += 16;
420fe2869c8SKris Kennaway 			outBuffer += 16;
421fe2869c8SKris Kennaway 		}
422fe2869c8SKris Kennaway 		/* last block */
4235129dcfcSHajimu UMEMOTO 		rijndaelDecrypt(key->rk, key->Nr, input, block);
424*d3d79e96SJohn Baldwin 		((uint32_t*)block)[0] ^= iv[0];
425*d3d79e96SJohn Baldwin 		((uint32_t*)block)[1] ^= iv[1];
426*d3d79e96SJohn Baldwin 		((uint32_t*)block)[2] ^= iv[2];
427*d3d79e96SJohn Baldwin 		((uint32_t*)block)[3] ^= iv[3];
428fe2869c8SKris Kennaway 		padLen = block[15];
429fe2869c8SKris Kennaway 		if (padLen <= 0 || padLen > 16) {
43007024904SConrad Meyer 			rval = BAD_DATA;
43107024904SConrad Meyer 			goto out;
432fe2869c8SKris Kennaway 		}
433fe2869c8SKris Kennaway 		for (i = 16 - padLen; i < 16; i++) {
434fe2869c8SKris Kennaway 			if (block[i] != padLen) {
43507024904SConrad Meyer 				rval = BAD_DATA;
43607024904SConrad Meyer 				goto out;
437fe2869c8SKris Kennaway 			}
438fe2869c8SKris Kennaway 		}
4395129dcfcSHajimu UMEMOTO 		memcpy(outBuffer, block, 16 - padLen);
440fe2869c8SKris Kennaway 		break;
441fe2869c8SKris Kennaway 
442fe2869c8SKris Kennaway 	default:
443fe2869c8SKris Kennaway 		return BAD_CIPHER_STATE;
444fe2869c8SKris Kennaway 	}
445fe2869c8SKris Kennaway 
44607024904SConrad Meyer 	rval = 16*numBlocks - padLen;
44707024904SConrad Meyer 
44807024904SConrad Meyer out:
44907024904SConrad Meyer 	explicit_bzero(block, sizeof(block));
45007024904SConrad Meyer 	return rval;
451fe2869c8SKris Kennaway }
452