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
18fe2869c8SKris Kennaway #include <sys/param.h>
1933841545SHajimu UMEMOTO #ifdef _KERNEL
2033841545SHajimu UMEMOTO #include <sys/systm.h>
2133841545SHajimu UMEMOTO #else
2233841545SHajimu UMEMOTO #include <string.h>
2333841545SHajimu UMEMOTO #endif
245129dcfcSHajimu UMEMOTO
255129dcfcSHajimu UMEMOTO #include <crypto/rijndael/rijndael_local.h>
26fe2869c8SKris Kennaway #include <crypto/rijndael/rijndael-api-fst.h>
279132d507SHajimu UMEMOTO
289132d507SHajimu UMEMOTO #ifndef TRUE
299132d507SHajimu UMEMOTO #define TRUE 1
309132d507SHajimu UMEMOTO #endif
319132d507SHajimu UMEMOTO
32*d3d79e96SJohn Baldwin typedef uint8_t BYTE;
3327da1009SPoul-Henning Kamp
rijndael_makeKey(keyInstance * key,BYTE direction,int keyLen,const char * keyMaterial)34133cdd9eSDag-Erling Smørgrav int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen,
35133cdd9eSDag-Erling Smørgrav const char *keyMaterial) {
36fe2869c8SKris Kennaway
37fe2869c8SKris Kennaway if (key == NULL) {
38fe2869c8SKris Kennaway return BAD_KEY_INSTANCE;
39fe2869c8SKris Kennaway }
40fe2869c8SKris Kennaway
41fe2869c8SKris Kennaway if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
42fe2869c8SKris Kennaway key->direction = direction;
43fe2869c8SKris Kennaway } else {
44fe2869c8SKris Kennaway return BAD_KEY_DIR;
45fe2869c8SKris Kennaway }
46fe2869c8SKris Kennaway
47fe2869c8SKris Kennaway if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
48fe2869c8SKris Kennaway key->keyLen = keyLen;
49fe2869c8SKris Kennaway } else {
50fe2869c8SKris Kennaway return BAD_KEY_MAT;
51fe2869c8SKris Kennaway }
52fe2869c8SKris Kennaway
53fe2869c8SKris Kennaway if (keyMaterial != NULL) {
545129dcfcSHajimu UMEMOTO memcpy(key->keyMaterial, keyMaterial, keyLen/8);
55fe2869c8SKris Kennaway }
56fe2869c8SKris Kennaway
57fe2869c8SKris Kennaway /* initialize key schedule: */
585129dcfcSHajimu UMEMOTO if (direction == DIR_ENCRYPT) {
5907024904SConrad Meyer key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen);
605129dcfcSHajimu UMEMOTO } else {
6107024904SConrad Meyer key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen);
62fe2869c8SKris Kennaway }
6307024904SConrad Meyer rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen);
64fe2869c8SKris Kennaway return TRUE;
65fe2869c8SKris Kennaway }
66fe2869c8SKris Kennaway
rijndael_cipherInit(cipherInstance * cipher,BYTE mode,char * IV)67fe2869c8SKris Kennaway int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
68fe2869c8SKris Kennaway if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
69fe2869c8SKris Kennaway cipher->mode = mode;
70fe2869c8SKris Kennaway } else {
71fe2869c8SKris Kennaway return BAD_CIPHER_MODE;
72fe2869c8SKris Kennaway }
73fe2869c8SKris Kennaway if (IV != NULL) {
745129dcfcSHajimu UMEMOTO memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
75fe2869c8SKris Kennaway } else {
765129dcfcSHajimu UMEMOTO memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
77fe2869c8SKris Kennaway }
78fe2869c8SKris Kennaway return TRUE;
79fe2869c8SKris Kennaway }
80fe2869c8SKris Kennaway
rijndael_blockEncrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputLen,BYTE * outBuffer)81fe2869c8SKris Kennaway int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
82133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputLen, BYTE *outBuffer) {
839132d507SHajimu UMEMOTO int i, k, numBlocks;
84*d3d79e96SJohn Baldwin uint8_t block[16], iv[4][4];
85fe2869c8SKris Kennaway
86fe2869c8SKris Kennaway if (cipher == NULL ||
87fe2869c8SKris Kennaway key == NULL ||
88fe2869c8SKris Kennaway key->direction == DIR_DECRYPT) {
89fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
90fe2869c8SKris Kennaway }
91fe2869c8SKris Kennaway if (input == NULL || inputLen <= 0) {
92fe2869c8SKris Kennaway return 0; /* nothing to do */
93fe2869c8SKris Kennaway }
94fe2869c8SKris Kennaway
95fe2869c8SKris Kennaway numBlocks = inputLen/128;
96fe2869c8SKris Kennaway
97fe2869c8SKris Kennaway switch (cipher->mode) {
98fe2869c8SKris Kennaway case MODE_ECB:
99fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
1005129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
101fe2869c8SKris Kennaway input += 16;
102fe2869c8SKris Kennaway outBuffer += 16;
103fe2869c8SKris Kennaway }
104fe2869c8SKris Kennaway break;
105fe2869c8SKris Kennaway
106fe2869c8SKris Kennaway case MODE_CBC:
1073011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1085129dcfcSHajimu UMEMOTO memcpy(block, cipher->IV, 16);
1095129dcfcSHajimu UMEMOTO memcpy(iv, input, 16);
110*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
111*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
112*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
113*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
1143011d4b3SHajimu UMEMOTO #else
115*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0];
116*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1];
117*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2];
118*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3];
1193011d4b3SHajimu UMEMOTO #endif
1205129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
121fe2869c8SKris Kennaway input += 16;
1229132d507SHajimu UMEMOTO for (i = numBlocks - 1; i > 0; i--) {
1239132d507SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1245129dcfcSHajimu UMEMOTO memcpy(block, outBuffer, 16);
1255129dcfcSHajimu UMEMOTO memcpy(iv, input, 16);
126*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0];
127*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1];
128*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2];
129*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3];
1309132d507SHajimu UMEMOTO #else
131*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0];
132*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1];
133*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2];
134*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3];
1359132d507SHajimu UMEMOTO #endif
136fe2869c8SKris Kennaway outBuffer += 16;
1375129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
1389132d507SHajimu UMEMOTO input += 16;
139fe2869c8SKris Kennaway }
140fe2869c8SKris Kennaway break;
141fe2869c8SKris Kennaway
142fe2869c8SKris Kennaway case MODE_CFB1:
1433011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
1445129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16);
1459132d507SHajimu UMEMOTO #else /* !STRICT_ALIGN */
146*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV ));
147*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
148*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
149*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
1509132d507SHajimu UMEMOTO #endif /* ?STRICT_ALIGN */
151fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
152fe2869c8SKris Kennaway for (k = 0; k < 128; k++) {
153*d3d79e96SJohn Baldwin *((uint32_t*) block ) = *((uint32_t*)iv[0]);
154*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
155*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
156*d3d79e96SJohn Baldwin *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
1575129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->ek, key->Nr, block,
1585129dcfcSHajimu UMEMOTO block);
1599132d507SHajimu UMEMOTO outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
1609132d507SHajimu UMEMOTO iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
1619132d507SHajimu UMEMOTO iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
1629132d507SHajimu UMEMOTO iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
1639132d507SHajimu UMEMOTO iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
1649132d507SHajimu UMEMOTO iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
1659132d507SHajimu UMEMOTO iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
1669132d507SHajimu UMEMOTO iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
1679132d507SHajimu UMEMOTO iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
1689132d507SHajimu UMEMOTO iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
1699132d507SHajimu UMEMOTO iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
1709132d507SHajimu UMEMOTO iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
1719132d507SHajimu UMEMOTO iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
1729132d507SHajimu UMEMOTO iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
1739132d507SHajimu UMEMOTO iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
1749132d507SHajimu UMEMOTO iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
1759132d507SHajimu UMEMOTO iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
176fe2869c8SKris Kennaway }
1778f21478bSHajimu UMEMOTO }
178fe2869c8SKris Kennaway break;
179fe2869c8SKris Kennaway
180fe2869c8SKris Kennaway default:
181fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
182fe2869c8SKris Kennaway }
183fe2869c8SKris Kennaway
18407024904SConrad Meyer explicit_bzero(block, sizeof(block));
185fe2869c8SKris Kennaway return 128*numBlocks;
186fe2869c8SKris Kennaway }
187fe2869c8SKris Kennaway
188fe2869c8SKris Kennaway /**
189fe2869c8SKris Kennaway * Encrypt data partitioned in octets, using RFC 2040-like padding.
190fe2869c8SKris Kennaway *
191fe2869c8SKris Kennaway * @param input data to be encrypted (octet sequence)
192fe2869c8SKris Kennaway * @param inputOctets input length in octets (not bits)
193fe2869c8SKris Kennaway * @param outBuffer encrypted output data
194fe2869c8SKris Kennaway *
195fe2869c8SKris Kennaway * @return length in octets (not bits) of the encrypted output buffer.
196fe2869c8SKris Kennaway */
rijndael_padEncrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputOctets,BYTE * outBuffer)197fe2869c8SKris Kennaway int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
198133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputOctets, BYTE *outBuffer) {
199fe2869c8SKris Kennaway int i, numBlocks, padLen;
200*d3d79e96SJohn Baldwin uint8_t block[16], *iv, *cp;
201fe2869c8SKris Kennaway
202fe2869c8SKris Kennaway if (cipher == NULL ||
203fe2869c8SKris Kennaway key == NULL ||
204fe2869c8SKris Kennaway key->direction == DIR_DECRYPT) {
205fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
206fe2869c8SKris Kennaway }
207fe2869c8SKris Kennaway if (input == NULL || inputOctets <= 0) {
208fe2869c8SKris Kennaway return 0; /* nothing to do */
209fe2869c8SKris Kennaway }
210fe2869c8SKris Kennaway
211fe2869c8SKris Kennaway numBlocks = inputOctets/16;
212fe2869c8SKris Kennaway
213fe2869c8SKris Kennaway switch (cipher->mode) {
214fe2869c8SKris Kennaway case MODE_ECB:
215fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
2165129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
217fe2869c8SKris Kennaway input += 16;
218fe2869c8SKris Kennaway outBuffer += 16;
219fe2869c8SKris Kennaway }
220fe2869c8SKris Kennaway padLen = 16 - (inputOctets - 16*numBlocks);
221eb159f5bSHajimu UMEMOTO if (padLen <= 0 || padLen > 16)
22227da1009SPoul-Henning Kamp return BAD_CIPHER_STATE;
2235129dcfcSHajimu UMEMOTO memcpy(block, input, 16 - padLen);
2249132d507SHajimu UMEMOTO for (cp = block + 16 - padLen; cp < block + 16; cp++)
2259132d507SHajimu UMEMOTO *cp = padLen;
2265129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
227fe2869c8SKris Kennaway break;
228fe2869c8SKris Kennaway
229fe2869c8SKris Kennaway case MODE_CBC:
230fe2869c8SKris Kennaway iv = cipher->IV;
231fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
232*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0];
233*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1];
234*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2];
235*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3];
2365129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
237fe2869c8SKris Kennaway iv = outBuffer;
238fe2869c8SKris Kennaway input += 16;
239fe2869c8SKris Kennaway outBuffer += 16;
240fe2869c8SKris Kennaway }
241fe2869c8SKris Kennaway padLen = 16 - (inputOctets - 16*numBlocks);
24266476d45SHajimu UMEMOTO if (padLen <= 0 || padLen > 16)
24327da1009SPoul-Henning Kamp return BAD_CIPHER_STATE;
244fe2869c8SKris Kennaway for (i = 0; i < 16 - padLen; i++) {
245fe2869c8SKris Kennaway block[i] = input[i] ^ iv[i];
246fe2869c8SKris Kennaway }
247fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) {
248fe2869c8SKris Kennaway block[i] = (BYTE)padLen ^ iv[i];
249fe2869c8SKris Kennaway }
2505129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
251fe2869c8SKris Kennaway break;
252fe2869c8SKris Kennaway
253fe2869c8SKris Kennaway default:
254fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
255fe2869c8SKris Kennaway }
256fe2869c8SKris Kennaway
25707024904SConrad Meyer explicit_bzero(block, sizeof(block));
258fe2869c8SKris Kennaway return 16*(numBlocks + 1);
259fe2869c8SKris Kennaway }
260fe2869c8SKris Kennaway
rijndael_blockDecrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputLen,BYTE * outBuffer)261fe2869c8SKris Kennaway int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
262133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputLen, BYTE *outBuffer) {
2639132d507SHajimu UMEMOTO int i, k, numBlocks;
264*d3d79e96SJohn Baldwin uint8_t block[16], iv[4][4];
265fe2869c8SKris Kennaway
266fe2869c8SKris Kennaway if (cipher == NULL ||
267fe2869c8SKris Kennaway key == NULL ||
268fe2869c8SKris Kennaway (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
269fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
270fe2869c8SKris Kennaway }
271fe2869c8SKris Kennaway if (input == NULL || inputLen <= 0) {
272fe2869c8SKris Kennaway return 0; /* nothing to do */
273fe2869c8SKris Kennaway }
274fe2869c8SKris Kennaway
275fe2869c8SKris Kennaway numBlocks = inputLen/128;
276fe2869c8SKris Kennaway
277fe2869c8SKris Kennaway switch (cipher->mode) {
278fe2869c8SKris Kennaway case MODE_ECB:
279fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
2805129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
281fe2869c8SKris Kennaway input += 16;
282fe2869c8SKris Kennaway outBuffer += 16;
283fe2869c8SKris Kennaway }
284fe2869c8SKris Kennaway break;
285fe2869c8SKris Kennaway
286fe2869c8SKris Kennaway case MODE_CBC:
2873011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */
2885129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16);
2893011d4b3SHajimu UMEMOTO #else
290*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV ));
291*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
292*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
293*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
2943011d4b3SHajimu UMEMOTO #endif
295fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
2965129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block);
297*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]);
298*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]);
299*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]);
300*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]);
3013011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/
3025129dcfcSHajimu UMEMOTO memcpy(iv, input, 16);
3035129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16);
3043011d4b3SHajimu UMEMOTO #else
305*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0];
306*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1];
307*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2];
308*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3];
3093011d4b3SHajimu UMEMOTO #endif
310fe2869c8SKris Kennaway input += 16;
311fe2869c8SKris Kennaway outBuffer += 16;
312fe2869c8SKris Kennaway }
313fe2869c8SKris Kennaway break;
314fe2869c8SKris Kennaway
315fe2869c8SKris Kennaway case MODE_CFB1:
3163011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */
3175129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16);
3183011d4b3SHajimu UMEMOTO #else
319*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV));
320*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4));
321*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8));
322*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12));
3233011d4b3SHajimu UMEMOTO #endif
324fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) {
325fe2869c8SKris Kennaway for (k = 0; k < 128; k++) {
326*d3d79e96SJohn Baldwin *((uint32_t*) block ) = *((uint32_t*)iv[0]);
327*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]);
328*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]);
329*d3d79e96SJohn Baldwin *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]);
3305129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->ek, key->Nr, block,
3315129dcfcSHajimu UMEMOTO block);
3329132d507SHajimu UMEMOTO iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
3339132d507SHajimu UMEMOTO iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
3349132d507SHajimu UMEMOTO iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
3359132d507SHajimu UMEMOTO iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
3369132d507SHajimu UMEMOTO iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
3379132d507SHajimu UMEMOTO iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
3389132d507SHajimu UMEMOTO iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
3399132d507SHajimu UMEMOTO iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
3409132d507SHajimu UMEMOTO iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
3419132d507SHajimu UMEMOTO iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
3429132d507SHajimu UMEMOTO iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
3439132d507SHajimu UMEMOTO iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
3449132d507SHajimu UMEMOTO iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
3459132d507SHajimu UMEMOTO iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
3469132d507SHajimu UMEMOTO iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
3479132d507SHajimu UMEMOTO iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
3489132d507SHajimu UMEMOTO outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
349fe2869c8SKris Kennaway }
3508f21478bSHajimu UMEMOTO }
351fe2869c8SKris Kennaway break;
352fe2869c8SKris Kennaway
353fe2869c8SKris Kennaway default:
354fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
355fe2869c8SKris Kennaway }
356fe2869c8SKris Kennaway
35707024904SConrad Meyer explicit_bzero(block, sizeof(block));
358fe2869c8SKris Kennaway return 128*numBlocks;
359fe2869c8SKris Kennaway }
360fe2869c8SKris Kennaway
rijndael_padDecrypt(cipherInstance * cipher,keyInstance * key,const BYTE * input,int inputOctets,BYTE * outBuffer)361fe2869c8SKris Kennaway int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
362133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputOctets, BYTE *outBuffer) {
36307024904SConrad Meyer int i, numBlocks, padLen, rval;
364*d3d79e96SJohn Baldwin uint8_t block[16];
365*d3d79e96SJohn Baldwin uint32_t iv[4];
366fe2869c8SKris Kennaway
367fe2869c8SKris Kennaway if (cipher == NULL ||
368fe2869c8SKris Kennaway key == NULL ||
369fe2869c8SKris Kennaway key->direction == DIR_ENCRYPT) {
370fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
371fe2869c8SKris Kennaway }
372fe2869c8SKris Kennaway if (input == NULL || inputOctets <= 0) {
373fe2869c8SKris Kennaway return 0; /* nothing to do */
374fe2869c8SKris Kennaway }
375fe2869c8SKris Kennaway if (inputOctets % 16 != 0) {
376fe2869c8SKris Kennaway return BAD_DATA;
377fe2869c8SKris Kennaway }
378fe2869c8SKris Kennaway
379fe2869c8SKris Kennaway numBlocks = inputOctets/16;
380fe2869c8SKris Kennaway
381fe2869c8SKris Kennaway switch (cipher->mode) {
382fe2869c8SKris Kennaway case MODE_ECB:
383fe2869c8SKris Kennaway /* all blocks but last */
384fe2869c8SKris Kennaway for (i = numBlocks - 1; i > 0; i--) {
3855129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
386fe2869c8SKris Kennaway input += 16;
387fe2869c8SKris Kennaway outBuffer += 16;
388fe2869c8SKris Kennaway }
389fe2869c8SKris Kennaway /* last block */
3905129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block);
391fe2869c8SKris Kennaway padLen = block[15];
392fe2869c8SKris Kennaway if (padLen >= 16) {
39307024904SConrad Meyer rval = BAD_DATA;
39407024904SConrad Meyer goto out;
395fe2869c8SKris Kennaway }
396fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) {
397fe2869c8SKris Kennaway if (block[i] != padLen) {
39807024904SConrad Meyer rval = BAD_DATA;
39907024904SConrad Meyer goto out;
400fe2869c8SKris Kennaway }
401fe2869c8SKris Kennaway }
4025129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16 - padLen);
403fe2869c8SKris Kennaway break;
404fe2869c8SKris Kennaway
405fe2869c8SKris Kennaway case MODE_CBC:
4065129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16);
407fe2869c8SKris Kennaway /* all blocks but last */
408fe2869c8SKris Kennaway for (i = numBlocks - 1; i > 0; i--) {
4095129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block);
410*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= iv[0];
411*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= iv[1];
412*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= iv[2];
413*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= iv[3];
4145129dcfcSHajimu UMEMOTO memcpy(iv, input, 16);
4155129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16);
416fe2869c8SKris Kennaway input += 16;
417fe2869c8SKris Kennaway outBuffer += 16;
418fe2869c8SKris Kennaway }
419fe2869c8SKris Kennaway /* last block */
4205129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block);
421*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= iv[0];
422*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= iv[1];
423*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= iv[2];
424*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= iv[3];
425fe2869c8SKris Kennaway padLen = block[15];
426fe2869c8SKris Kennaway if (padLen <= 0 || padLen > 16) {
42707024904SConrad Meyer rval = BAD_DATA;
42807024904SConrad Meyer goto out;
429fe2869c8SKris Kennaway }
430fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) {
431fe2869c8SKris Kennaway if (block[i] != padLen) {
43207024904SConrad Meyer rval = BAD_DATA;
43307024904SConrad Meyer goto out;
434fe2869c8SKris Kennaway }
435fe2869c8SKris Kennaway }
4365129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16 - padLen);
437fe2869c8SKris Kennaway break;
438fe2869c8SKris Kennaway
439fe2869c8SKris Kennaway default:
440fe2869c8SKris Kennaway return BAD_CIPHER_STATE;
441fe2869c8SKris Kennaway }
442fe2869c8SKris Kennaway
44307024904SConrad Meyer rval = 16*numBlocks - padLen;
44407024904SConrad Meyer
44507024904SConrad Meyer out:
44607024904SConrad Meyer explicit_bzero(block, sizeof(block));
44707024904SConrad Meyer return rval;
448fe2869c8SKris Kennaway }
449