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