rijndael-api-fst.c revision 121050
1121050Sume/*	$KAME: rijndael-api-fst.c,v 1.18 2003/07/24 15:10:30 itojun Exp $	*/
267957Skris
3121050Sume/**
4121050Sume * rijndael-api-fst.c
567957Skris *
6121050Sume * @version 2.9 (December 2000)
767957Skris *
8121050Sume * Optimised ANSI C code for the Rijndael cipher (now AES)
967957Skris *
10121050Sume * @author Vincent Rijmen <vincent.rijmen@esat.kuleuven.ac.be>
11121050Sume * @author Antoon Bosselaers <antoon.bosselaers@esat.kuleuven.ac.be>
12121050Sume * @author Paulo Barreto <paulo.barreto@terra.com.br>
13121050Sume *
14121050Sume * This code is hereby placed in the public domain.
15121050Sume *
16121050Sume * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
17121050Sume * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
18121050Sume * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
19121050Sume * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
20121050Sume * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21121050Sume * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22121050Sume * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23121050Sume * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24121050Sume * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25121050Sume * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
26121050Sume * EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27121050Sume *
28121050Sume * Acknowledgements:
29121050Sume *
30121050Sume * We are deeply indebted to the following people for their bug reports,
31121050Sume * fixes, and improvement suggestions to this implementation. Though we
32121050Sume * tried to list all contributions, we apologise in advance for any
33121050Sume * missing reference.
34121050Sume *
35121050Sume * Andrew Bales <Andrew.Bales@Honeywell.com>
36121050Sume * Markus Friedl <markus.friedl@informatik.uni-erlangen.de>
37121050Sume * John Skodon <skodonj@webquill.com>
3867957Skris */
3967957Skris
40116174Sobrien#include <sys/cdefs.h>
41116174Sobrien__FBSDID("$FreeBSD: head/sys/crypto/rijndael/rijndael-api-fst.c 121050 2003-10-12 21:05:05Z ume $");
42116174Sobrien
4367957Skris#include <sys/param.h>
4478064Sume#ifdef _KERNEL
4567957Skris#include <sys/systm.h>
4678064Sume#else
47121050Sume#include <stdlib.h>
4878064Sume#include <string.h>
4978064Sume#endif
50121050Sume
51121050Sume#include <crypto/rijndael/rijndael_local.h>
5267957Skris#include <crypto/rijndael/rijndael-alg-fst.h>
5367957Skris#include <crypto/rijndael/rijndael-api-fst.h>
5467957Skris
5567957Skrisint rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
56121050Sume	u_int8_t cipherKey[RIJNDAEL_MAXKB];
5767957Skris
5867957Skris	if (key == NULL) {
5967957Skris		return BAD_KEY_INSTANCE;
6067957Skris	}
6167957Skris
6267957Skris	if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
6367957Skris		key->direction = direction;
6467957Skris	} else {
6567957Skris		return BAD_KEY_DIR;
6667957Skris	}
6767957Skris
68121050Sume	if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
6967957Skris		key->keyLen = keyLen;
7067957Skris	} else {
7167957Skris		return BAD_KEY_MAT;
7267957Skris	}
7367957Skris
7467957Skris	if (keyMaterial != NULL) {
75121050Sume		memcpy(key->keyMaterial, keyMaterial, keyLen/8);
7667957Skris	}
7767957Skris
7867957Skris	/* initialize key schedule: */
79121050Sume	memcpy(cipherKey, key->keyMaterial, keyLen/8);
80121050Sume	if (direction == DIR_ENCRYPT) {
81121050Sume		key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
82121050Sume	} else {
83121050Sume		key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
8467957Skris	}
85121050Sume	rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
8667957Skris	return TRUE;
8767957Skris}
8867957Skris
8967957Skrisint rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
9067957Skris	if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
9167957Skris		cipher->mode = mode;
9267957Skris	} else {
9367957Skris		return BAD_CIPHER_MODE;
9467957Skris	}
9567957Skris	if (IV != NULL) {
96121050Sume		memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
9767957Skris	} else {
98121050Sume		memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
9967957Skris	}
10067957Skris	return TRUE;
10167957Skris}
10267957Skris
10367957Skrisint rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
10467957Skris		BYTE *input, int inputLen, BYTE *outBuffer) {
105121050Sume	int i, k, t, numBlocks;
106121050Sume	u_int8_t block[16], *iv;
10767957Skris
10867957Skris	if (cipher == NULL ||
10967957Skris		key == NULL ||
11067957Skris		key->direction == DIR_DECRYPT) {
11167957Skris		return BAD_CIPHER_STATE;
11267957Skris	}
11367957Skris	if (input == NULL || inputLen <= 0) {
11467957Skris		return 0; /* nothing to do */
11567957Skris	}
11667957Skris
11767957Skris	numBlocks = inputLen/128;
11867957Skris
11967957Skris	switch (cipher->mode) {
120121050Sume	case MODE_ECB:
12167957Skris		for (i = numBlocks; i > 0; i--) {
122121050Sume			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
12367957Skris			input += 16;
12467957Skris			outBuffer += 16;
12567957Skris		}
12667957Skris		break;
12767957Skris
12867957Skris	case MODE_CBC:
129121050Sume		iv = cipher->IV;
130121050Sume		for (i = numBlocks; i > 0; i--) {
131121050Sume			((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
132121050Sume			((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
133121050Sume			((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
134121050Sume			((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
135121050Sume			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
136121050Sume			iv = outBuffer;
137121050Sume			input += 16;
13867957Skris			outBuffer += 16;
13967957Skris		}
14067957Skris		break;
141121050Sume
142121050Sume    case MODE_CFB1:
143121050Sume		iv = cipher->IV;
144121050Sume        for (i = numBlocks; i > 0; i--) {
145121050Sume			memcpy(outBuffer, input, 16);
146121050Sume            for (k = 0; k < 128; k++) {
147121050Sume				rijndaelEncrypt(key->ek, key->Nr, iv, block);
148121050Sume                outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
149121050Sume                for (t = 0; t < 15; t++) {
150121050Sume                	iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
151121050Sume                }
152121050Sume               	iv[15] = (iv[15] << 1) | ((outBuffer[k >> 3] >> (7 - (k & 7))) & 1);
153121050Sume            }
154121050Sume            outBuffer += 16;
155121050Sume            input += 16;
156121050Sume        }
157121050Sume        break;
158121050Sume
15967957Skris	default:
16067957Skris		return BAD_CIPHER_STATE;
16167957Skris	}
16267957Skris
16367957Skris	return 128*numBlocks;
16467957Skris}
16567957Skris
16667957Skris/**
16767957Skris * Encrypt data partitioned in octets, using RFC 2040-like padding.
16867957Skris *
16967957Skris * @param   input           data to be encrypted (octet sequence)
17067957Skris * @param   inputOctets		input length in octets (not bits)
17167957Skris * @param   outBuffer       encrypted output data
17267957Skris *
17367957Skris * @return	length in octets (not bits) of the encrypted output buffer.
17467957Skris */
17567957Skrisint rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
17667957Skris		BYTE *input, int inputOctets, BYTE *outBuffer) {
17767957Skris	int i, numBlocks, padLen;
178121050Sume	u_int8_t block[16], *iv;
17967957Skris
18067957Skris	if (cipher == NULL ||
18167957Skris		key == NULL ||
18267957Skris		key->direction == DIR_DECRYPT) {
18367957Skris		return BAD_CIPHER_STATE;
18467957Skris	}
18567957Skris	if (input == NULL || inputOctets <= 0) {
18667957Skris		return 0; /* nothing to do */
18767957Skris	}
18867957Skris
18967957Skris	numBlocks = inputOctets/16;
19067957Skris
19167957Skris	switch (cipher->mode) {
192121050Sume	case MODE_ECB:
19367957Skris		for (i = numBlocks; i > 0; i--) {
194121050Sume			rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
19567957Skris			input += 16;
19667957Skris			outBuffer += 16;
19767957Skris		}
19867957Skris		padLen = 16 - (inputOctets - 16*numBlocks);
199120157Sume		if (padLen <= 0 || padLen > 16)
200105099Sphk			return BAD_CIPHER_STATE;
201121050Sume		memcpy(block, input, 16 - padLen);
202121050Sume		memset(block + 16 - padLen, padLen, padLen);
203121050Sume		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
20467957Skris		break;
20567957Skris
20667957Skris	case MODE_CBC:
20767957Skris		iv = cipher->IV;
20867957Skris		for (i = numBlocks; i > 0; i--) {
209121050Sume			((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
210121050Sume			((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
211121050Sume			((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
212121050Sume			((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
213121050Sume			rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
21467957Skris			iv = outBuffer;
21567957Skris			input += 16;
21667957Skris			outBuffer += 16;
21767957Skris		}
21867957Skris		padLen = 16 - (inputOctets - 16*numBlocks);
219120206Sume		if (padLen <= 0 || padLen > 16)
220105099Sphk			return BAD_CIPHER_STATE;
22167957Skris		for (i = 0; i < 16 - padLen; i++) {
22267957Skris			block[i] = input[i] ^ iv[i];
22367957Skris		}
22467957Skris		for (i = 16 - padLen; i < 16; i++) {
22567957Skris			block[i] = (BYTE)padLen ^ iv[i];
22667957Skris		}
227121050Sume		rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
22867957Skris		break;
22967957Skris
23067957Skris	default:
23167957Skris		return BAD_CIPHER_STATE;
23267957Skris	}
23367957Skris
23467957Skris	return 16*(numBlocks + 1);
23567957Skris}
23667957Skris
23767957Skrisint rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
23867957Skris		BYTE *input, int inputLen, BYTE *outBuffer) {
239121050Sume	int i, k, t, numBlocks;
240121050Sume	u_int8_t block[16], *iv;
24167957Skris
24267957Skris	if (cipher == NULL ||
24367957Skris		key == NULL ||
24467957Skris		(cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
24567957Skris		return BAD_CIPHER_STATE;
24667957Skris	}
24767957Skris	if (input == NULL || inputLen <= 0) {
24867957Skris		return 0; /* nothing to do */
24967957Skris	}
25067957Skris
25167957Skris	numBlocks = inputLen/128;
25267957Skris
25367957Skris	switch (cipher->mode) {
254121050Sume	case MODE_ECB:
255121050Sume		for (i = numBlocks; i > 0; i--) {
256121050Sume			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
25767957Skris			input += 16;
25867957Skris			outBuffer += 16;
25967957Skris		}
26067957Skris		break;
26167957Skris
26267957Skris	case MODE_CBC:
263121050Sume		iv = cipher->IV;
26467957Skris		for (i = numBlocks; i > 0; i--) {
265121050Sume			rijndaelDecrypt(key->rk, key->Nr, input, block);
266121050Sume			((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
267121050Sume			((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
268121050Sume			((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
269121050Sume			((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
270121050Sume			memcpy(cipher->IV, input, 16);
271121050Sume			memcpy(outBuffer, block, 16);
27267957Skris			input += 16;
27367957Skris			outBuffer += 16;
27467957Skris		}
27567957Skris		break;
27667957Skris
277121050Sume    case MODE_CFB1:
278121050Sume		iv = cipher->IV;
279121050Sume        for (i = numBlocks; i > 0; i--) {
280121050Sume			memcpy(outBuffer, input, 16);
281121050Sume            for (k = 0; k < 128; k++) {
282121050Sume				rijndaelEncrypt(key->ek, key->Nr, iv, block);
283121050Sume                for (t = 0; t < 15; t++) {
284121050Sume                	iv[t] = (iv[t] << 1) | (iv[t + 1] >> 7);
285121050Sume                }
286121050Sume               	iv[15] = (iv[15] << 1) | ((input[k >> 3] >> (7 - (k & 7))) & 1);
287121050Sume                outBuffer[k >> 3] ^= (block[0] & 0x80U) >> (k & 7);
288121050Sume            }
289121050Sume            outBuffer += 16;
290121050Sume            input += 16;
291121050Sume        }
292121050Sume        break;
293121050Sume
29467957Skris	default:
29567957Skris		return BAD_CIPHER_STATE;
29667957Skris	}
29767957Skris
29867957Skris	return 128*numBlocks;
29967957Skris}
30067957Skris
30167957Skrisint rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
30267957Skris		BYTE *input, int inputOctets, BYTE *outBuffer) {
30367957Skris	int i, numBlocks, padLen;
304121050Sume	u_int8_t block[16];
30567957Skris
30667957Skris	if (cipher == NULL ||
30767957Skris		key == NULL ||
30867957Skris		key->direction == DIR_ENCRYPT) {
30967957Skris		return BAD_CIPHER_STATE;
31067957Skris	}
31167957Skris	if (input == NULL || inputOctets <= 0) {
31267957Skris		return 0; /* nothing to do */
31367957Skris	}
31467957Skris	if (inputOctets % 16 != 0) {
31567957Skris		return BAD_DATA;
31667957Skris	}
31767957Skris
31867957Skris	numBlocks = inputOctets/16;
31967957Skris
32067957Skris	switch (cipher->mode) {
32167957Skris	case MODE_ECB:
32267957Skris		/* all blocks but last */
323121050Sume		for (i = numBlocks - 1; i > 0; i--) {
324121050Sume			rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
32567957Skris			input += 16;
32667957Skris			outBuffer += 16;
32767957Skris		}
32867957Skris		/* last block */
329121050Sume		rijndaelDecrypt(key->rk, key->Nr, input, block);
33067957Skris		padLen = block[15];
33167957Skris		if (padLen >= 16) {
33267957Skris			return BAD_DATA;
33367957Skris		}
33467957Skris		for (i = 16 - padLen; i < 16; i++) {
33567957Skris			if (block[i] != padLen) {
33667957Skris				return BAD_DATA;
33767957Skris			}
33867957Skris		}
339121050Sume		memcpy(outBuffer, block, 16 - padLen);
34067957Skris		break;
34167957Skris
34267957Skris	case MODE_CBC:
34367957Skris		/* all blocks but last */
34467957Skris		for (i = numBlocks - 1; i > 0; i--) {
345121050Sume			rijndaelDecrypt(key->rk, key->Nr, input, block);
346121050Sume			((u_int32_t*)block)[0] ^= ((u_int32_t*)cipher->IV)[0];
347121050Sume			((u_int32_t*)block)[1] ^= ((u_int32_t*)cipher->IV)[1];
348121050Sume			((u_int32_t*)block)[2] ^= ((u_int32_t*)cipher->IV)[2];
349121050Sume			((u_int32_t*)block)[3] ^= ((u_int32_t*)cipher->IV)[3];
350121050Sume			memcpy(cipher->IV, input, 16);
351121050Sume			memcpy(outBuffer, block, 16);
35267957Skris			input += 16;
35367957Skris			outBuffer += 16;
35467957Skris		}
35567957Skris		/* last block */
356121050Sume		rijndaelDecrypt(key->rk, key->Nr, input, block);
357121050Sume		((u_int32_t*)block)[0] ^= ((u_int32_t*)cipher->IV)[0];
358121050Sume		((u_int32_t*)block)[1] ^= ((u_int32_t*)cipher->IV)[1];
359121050Sume		((u_int32_t*)block)[2] ^= ((u_int32_t*)cipher->IV)[2];
360121050Sume		((u_int32_t*)block)[3] ^= ((u_int32_t*)cipher->IV)[3];
36167957Skris		padLen = block[15];
36267957Skris		if (padLen <= 0 || padLen > 16) {
36367957Skris			return BAD_DATA;
36467957Skris		}
36567957Skris		for (i = 16 - padLen; i < 16; i++) {
36667957Skris			if (block[i] != padLen) {
36767957Skris				return BAD_DATA;
36867957Skris			}
36967957Skris		}
370121050Sume		memcpy(outBuffer, block, 16 - padLen);
37167957Skris		break;
37267957Skris
37367957Skris	default:
37467957Skris		return BAD_CIPHER_STATE;
37567957Skris	}
37667957Skris
37767957Skris	return 16*numBlocks - padLen;
37867957Skris}
37967957Skris
380