1/**
2 * rijndael-api-fst.c
3 *
4 * @version 2.9 (December 2000)
5 *
6 * Optimised ANSI C code for the Rijndael cipher (now AES)
7 *
8 * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
9 * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
10 * @author Paulo Barreto <paulo.barreto@terra.com.br>
11 *
12 * This code is hereby placed in the public domain.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
15 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
16 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
17 * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
18 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
21 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
22 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
23 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
24 * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 *
26 * Acknowledgements:
27 *
28 * We are deeply indebted to the following people for their bug reports,
29 * fixes, and improvement suggestions to this implementation. Though we
30 * tried to list all contributions, we apologise in advance for any
31 * missing reference.
32 *
33 * Andrew Bales <Andrew.Bales@Honeywell.com>
34 * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
35 * John Skodon <skodonj@webquill.com>
36 */
37#include "db_config.h"
38
39#include "db_int.h"
40#include "dbinc/crypto.h"
41
42#include "crypto/rijndael/rijndael-alg-fst.h"
43#include "crypto/rijndael/rijndael-api-fst.h"
44
45/*
46 * __db_makeKey --
47 *
48 * PUBLIC: int __db_makeKey __P((keyInstance *, int, int, char *));
49 */
50int
51__db_makeKey(key, direction, keyLen, keyMaterial)
52	keyInstance *key;
53	int direction;
54	int keyLen;
55	char *keyMaterial;
56{
57	u8 cipherKey[MAXKB];
58
59	if (key == NULL) {
60		return BAD_KEY_INSTANCE;
61	}
62
63	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
64		key->direction = direction;
65	} else {
66		return BAD_KEY_DIR;
67	}
68
69	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
70		key->keyLen = keyLen;
71	} else {
72		return BAD_KEY_MAT;
73	}
74
75	if (keyMaterial != NULL) {
76		memcpy(cipherKey, keyMaterial, key->keyLen/8);
77	}
78
79	if (direction == DIR_ENCRYPT) {
80		key->Nr = __db_rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
81	} else {
82		key->Nr = __db_rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
83	}
84	__db_rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
85	return TRUE;
86}
87
88/*
89 * __db_cipherInit --
90 *
91 * PUBLIC: int __db_cipherInit __P((cipherInstance *, int, char *));
92 */
93int
94__db_cipherInit(cipher, mode, IV)
95	cipherInstance *cipher;
96	int mode;
97	char *IV;
98{
99	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
100		cipher->mode = mode;
101	} else {
102		return BAD_CIPHER_MODE;
103	}
104	if (IV != NULL) {
105	  memcpy(cipher->IV, IV, MAX_IV_SIZE);
106	}
107	return TRUE;
108}
109
110/*
111 * __db_blockEncrypt --
112 *
113 * PUBLIC: int __db_blockEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
114 * PUBLIC:    size_t, u_int8_t *));
115 */
116int
117__db_blockEncrypt(cipher, key, input, inputLen, outBuffer)
118	cipherInstance *cipher;
119	keyInstance *key;
120	u_int8_t *input;
121	size_t inputLen;
122	u_int8_t *outBuffer;
123{
124	int i, k, t, numBlocks;
125	u8 block[16], *iv;
126	u32 tmpiv[4];
127
128	if (cipher == NULL ||
129		key == NULL ||
130		key->direction == DIR_DECRYPT) {
131		return BAD_CIPHER_STATE;
132	}
133	if (input == NULL || inputLen <= 0) {
134		return 0; /* nothing to do */
135	}
136
137	numBlocks = (int)(inputLen/128);
138
139	switch (cipher->mode) {
140	case MODE_ECB:
141		for (i = numBlocks; i > 0; i--) {
142			__db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
143			input += 16;
144			outBuffer += 16;
145		}
146		break;
147
148	case MODE_CBC:
149		iv = cipher->IV;
150		for (i = numBlocks; i > 0; i--) {
151			memcpy(tmpiv, iv, MAX_IV_SIZE);
152			((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
153			((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
154			((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
155			((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
156			__db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
157			iv = outBuffer;
158			input += 16;
159			outBuffer += 16;
160		}
161		break;
162
163    case MODE_CFB1:
164		iv = cipher->IV;
165	for (i = numBlocks; i > 0; i--) {
166			memcpy(outBuffer, input, 16);
167	    for (k = 0; k < 128; k++) {
168				__db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
169		outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
170		for (t = 0; t < 15; t++) {
171			iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
172		}
173		iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
174	    }
175	    outBuffer += 16;
176	    input += 16;
177	}
178	break;
179
180	default:
181		return BAD_CIPHER_STATE;
182	}
183
184	return 128*numBlocks;
185}
186
187/**
188 * Encrypt data partitioned in octets, using RFC 2040-like padding.
189 *
190 * @param   input           data to be encrypted (octet sequence)
191 * @param   inputOctets		input length in octets (not bits)
192 * @param   outBuffer       encrypted output data
193 *
194 * @return	length in octets (not bits) of the encrypted output buffer.
195 */
196/*
197 * __db_padEncrypt --
198 *
199 * PUBLIC: int __db_padEncrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
200 * PUBLIC:    int, u_int8_t *));
201 */
202int
203__db_padEncrypt(cipher, key, input, inputOctets, outBuffer)
204	cipherInstance *cipher;
205	keyInstance *key;
206	u_int8_t *input;
207	int inputOctets;
208	u_int8_t *outBuffer;
209{
210	int i, numBlocks, padLen;
211	u8 block[16], *iv;
212	u32 tmpiv[4];
213
214	if (cipher == NULL ||
215		key == NULL ||
216		key->direction == DIR_DECRYPT) {
217		return BAD_CIPHER_STATE;
218	}
219	if (input == NULL || inputOctets <= 0) {
220		return 0; /* nothing to do */
221	}
222
223	numBlocks = inputOctets/16;
224
225	switch (cipher->mode) {
226	case MODE_ECB:
227		for (i = numBlocks; i > 0; i--) {
228			__db_rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
229			input += 16;
230			outBuffer += 16;
231		}
232		padLen = 16 - (inputOctets - 16*numBlocks);
233		DB_ASSERT(NULL, padLen > 0 && padLen <= 16);
234		memcpy(block, input, 16 - padLen);
235		memset(block + 16 - padLen, padLen, padLen);
236		__db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
237		break;
238
239	case MODE_CBC:
240		iv = cipher->IV;
241		for (i = numBlocks; i > 0; i--) {
242			memcpy(tmpiv, iv, MAX_IV_SIZE);
243			((u32*)block)[0] = ((u32*)input)[0] ^ tmpiv[0];
244			((u32*)block)[1] = ((u32*)input)[1] ^ tmpiv[1];
245			((u32*)block)[2] = ((u32*)input)[2] ^ tmpiv[2];
246			((u32*)block)[3] = ((u32*)input)[3] ^ tmpiv[3];
247			__db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
248			iv = outBuffer;
249			input += 16;
250			outBuffer += 16;
251		}
252		padLen = 16 - (inputOctets - 16*numBlocks);
253		DB_ASSERT(NULL, padLen > 0 && padLen <= 16);
254		for (i = 0; i < 16 - padLen; i++) {
255			block[i] = input[i] ^ iv[i];
256		}
257		for (i = 16 - padLen; i < 16; i++) {
258			block[i] = (u_int8_t)padLen ^ iv[i];
259		}
260		__db_rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
261		break;
262
263	default:
264		return BAD_CIPHER_STATE;
265	}
266
267	return 16*(numBlocks + 1);
268}
269
270/*
271 * __db_blockDecrypt --
272 *
273 * PUBLIC: int __db_blockDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
274 * PUBLIC:    size_t, u_int8_t *));
275 */
276int
277__db_blockDecrypt(cipher, key, input, inputLen, outBuffer)
278	cipherInstance *cipher;
279	keyInstance *key;
280	u_int8_t *input;
281	size_t inputLen;
282	u_int8_t *outBuffer;
283{
284	int i, k, t, numBlocks;
285	u8 block[16], *iv;
286	u32 tmpiv[4];
287
288	if (cipher == NULL ||
289		key == NULL ||
290		(cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
291		return BAD_CIPHER_STATE;
292	}
293	if (input == NULL || inputLen <= 0) {
294		return 0; /* nothing to do */
295	}
296
297	numBlocks = (int)(inputLen/128);
298
299	switch (cipher->mode) {
300	case MODE_ECB:
301		for (i = numBlocks; i > 0; i--) {
302			__db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
303			input += 16;
304			outBuffer += 16;
305		}
306		break;
307
308	case MODE_CBC:
309		memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
310		for (i = numBlocks; i > 0; i--) {
311			__db_rijndaelDecrypt(key->rk, key->Nr, input, block);
312			((u32*)block)[0] ^= tmpiv[0];
313			((u32*)block)[1] ^= tmpiv[1];
314			((u32*)block)[2] ^= tmpiv[2];
315			((u32*)block)[3] ^= tmpiv[3];
316			memcpy(tmpiv, input, 16);
317			memcpy(outBuffer, block, 16);
318			input += 16;
319			outBuffer += 16;
320		}
321		break;
322
323    case MODE_CFB1:
324		iv = cipher->IV;
325	for (i = numBlocks; i > 0; i--) {
326			memcpy(outBuffer, input, 16);
327	    for (k = 0; k < 128; k++) {
328				__db_rijndaelEncrypt(key->ek, key->Nr, iv, block);
329		for (t = 0; t < 15; t++) {
330			iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
331		}
332		iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
333		outBuffer[k >> 3] ^= (block[0] & (u_int)0x80) >> (k & 7);
334	    }
335	    outBuffer += 16;
336	    input += 16;
337	}
338	break;
339
340	default:
341		return BAD_CIPHER_STATE;
342	}
343
344	return 128*numBlocks;
345}
346
347/*
348 * __db_padDecrypt --
349 *
350 * PUBLIC: int __db_padDecrypt __P((cipherInstance *, keyInstance *, u_int8_t *,
351 * PUBLIC:    int, u_int8_t *));
352 */
353int
354__db_padDecrypt(cipher, key, input, inputOctets, outBuffer)
355	cipherInstance *cipher;
356	keyInstance *key;
357	u_int8_t *input;
358	int inputOctets;
359	u_int8_t *outBuffer;
360{
361	int i, numBlocks, padLen;
362	u8 block[16];
363	u32 tmpiv[4];
364
365	if (cipher == NULL ||
366		key == NULL ||
367		key->direction == DIR_ENCRYPT) {
368		return BAD_CIPHER_STATE;
369	}
370	if (input == NULL || inputOctets <= 0) {
371		return 0; /* nothing to do */
372	}
373	if (inputOctets % 16 != 0) {
374		return BAD_DATA;
375	}
376
377	numBlocks = inputOctets/16;
378
379	switch (cipher->mode) {
380	case MODE_ECB:
381		/* all blocks but last */
382		for (i = numBlocks - 1; i > 0; i--) {
383			__db_rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
384			input += 16;
385			outBuffer += 16;
386		}
387		/* last block */
388		__db_rijndaelDecrypt(key->rk, key->Nr, input, block);
389		padLen = block[15];
390		if (padLen >= 16) {
391			return BAD_DATA;
392		}
393		for (i = 16 - padLen; i < 16; i++) {
394			if (block[i] != padLen) {
395				return BAD_DATA;
396			}
397		}
398		memcpy(outBuffer, block, 16 - padLen);
399		break;
400
401	case MODE_CBC:
402		/* all blocks but last */
403		memcpy(tmpiv, cipher->IV, MAX_IV_SIZE);
404		for (i = numBlocks - 1; i > 0; i--) {
405			__db_rijndaelDecrypt(key->rk, key->Nr, input, block);
406			((u32*)block)[0] ^= tmpiv[0];
407			((u32*)block)[1] ^= tmpiv[1];
408			((u32*)block)[2] ^= tmpiv[2];
409			((u32*)block)[3] ^= tmpiv[3];
410			memcpy(tmpiv, input, 16);
411			memcpy(outBuffer, block, 16);
412			input += 16;
413			outBuffer += 16;
414		}
415		/* last block */
416		__db_rijndaelDecrypt(key->rk, key->Nr, input, block);
417		((u32*)block)[0] ^= tmpiv[0];
418		((u32*)block)[1] ^= tmpiv[1];
419		((u32*)block)[2] ^= tmpiv[2];
420		((u32*)block)[3] ^= tmpiv[3];
421		padLen = block[15];
422		if (padLen <= 0 || padLen > 16) {
423			return BAD_DATA;
424		}
425		for (i = 16 - padLen; i < 16; i++) {
426			if (block[i] != padLen) {
427				return BAD_DATA;
428			}
429		}
430		memcpy(outBuffer, block, 16 - padLen);
431		break;
432
433	default:
434		return BAD_CIPHER_STATE;
435	}
436
437	return 16*numBlocks - padLen;
438}
439
440#ifdef INTERMEDIATE_VALUE_KAT
441/**
442 *	cipherUpdateRounds:
443 *
444 *	Encrypts/Decrypts exactly one full block a specified number of rounds.
445 *	Only used in the Intermediate Value Known Answer Test.
446 *
447 *	Returns:
448 *		TRUE - on success
449 *		BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized)
450 */
451/*
452 * __db_cipherUpdateRounds --
453 *
454 * PUBLIC: int __db_cipherUpdateRounds __P((cipherInstance *, keyInstance *,
455 * PUBLIC:    u_int8_t *, int, u_int8_t *, int));
456 */
457int
458__db_cipherUpdateRounds(cipher, key, input, inputLen, outBuffer, rounds)
459	cipherInstance *cipher;
460	keyInstance *key;
461	u_int8_t *input;
462	size_t inputLen;
463	u_int8_t *outBuffer;
464	int rounds;
465{
466	u8 block[16];
467
468	if (cipher == NULL || key == NULL) {
469		return BAD_CIPHER_STATE;
470	}
471
472	memcpy(block, input, 16);
473
474	switch (key->direction) {
475	case DIR_ENCRYPT:
476		__db_rijndaelEncryptRound(key->rk, key->Nr, block, rounds);
477		break;
478
479	case DIR_DECRYPT:
480		__db_rijndaelDecryptRound(key->rk, key->Nr, block, rounds);
481		break;
482
483	default:
484		return BAD_KEY_DIR;
485	}
486
487	memcpy(outBuffer, block, 16);
488
489	return TRUE;
490}
491#endif /* INTERMEDIATE_VALUE_KAT */
492