Copying the rijndael (aka AES) cryptographic algorithm into the freebsd_wlan
folder, as it is used by the crypto_ccmp module, only. Though there would be no sense in making AES available to the FreeBSD compat layer in general. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@34799 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
# $FreeBSD$
|
||||||
|
|
||||||
|
PROG=test00
|
||||||
|
NO_MAN=
|
||||||
|
SRCS= ${PROG}.c rijndael-alg-fst.c rijndael-api-fst.c
|
||||||
|
|
||||||
|
CFLAGS += -I${.CURDIR}/../.. -g -static
|
||||||
|
|
||||||
|
.include <bsd.prog.mk>
|
||||||
|
|
||||||
|
test: ${PROG}
|
||||||
|
./${PROG}
|
||||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,441 @@
|
|||||||
|
/* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rijndael-api-fst.c v2.3 April '2000
|
||||||
|
*
|
||||||
|
* Optimised ANSI C code
|
||||||
|
*
|
||||||
|
* authors: v1.0: Antoon Bosselaers
|
||||||
|
* v2.0: Vincent Rijmen
|
||||||
|
* v2.1: Vincent Rijmen
|
||||||
|
* v2.2: Vincent Rijmen
|
||||||
|
* v2.3: Paulo Barreto
|
||||||
|
* v2.4: Vincent Rijmen
|
||||||
|
*
|
||||||
|
* This code is placed in the public domain.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/param.h>
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#else
|
||||||
|
#include <string.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <crypto/rijndael/rijndael_local.h>
|
||||||
|
#include <crypto/rijndael/rijndael-api-fst.h>
|
||||||
|
|
||||||
|
#ifndef TRUE
|
||||||
|
#define TRUE 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef u_int8_t BYTE;
|
||||||
|
|
||||||
|
int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) {
|
||||||
|
u_int8_t cipherKey[RIJNDAEL_MAXKB];
|
||||||
|
|
||||||
|
if (key == NULL) {
|
||||||
|
return BAD_KEY_INSTANCE;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) {
|
||||||
|
key->direction = direction;
|
||||||
|
} else {
|
||||||
|
return BAD_KEY_DIR;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) {
|
||||||
|
key->keyLen = keyLen;
|
||||||
|
} else {
|
||||||
|
return BAD_KEY_MAT;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (keyMaterial != NULL) {
|
||||||
|
memcpy(key->keyMaterial, keyMaterial, keyLen/8);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* initialize key schedule: */
|
||||||
|
memcpy(cipherKey, key->keyMaterial, keyLen/8);
|
||||||
|
if (direction == DIR_ENCRYPT) {
|
||||||
|
key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen);
|
||||||
|
} else {
|
||||||
|
key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen);
|
||||||
|
}
|
||||||
|
rijndaelKeySetupEnc(key->ek, cipherKey, keyLen);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) {
|
||||||
|
if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) {
|
||||||
|
cipher->mode = mode;
|
||||||
|
} else {
|
||||||
|
return BAD_CIPHER_MODE;
|
||||||
|
}
|
||||||
|
if (IV != NULL) {
|
||||||
|
memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE);
|
||||||
|
} else {
|
||||||
|
memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE);
|
||||||
|
}
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key,
|
||||||
|
BYTE *input, int inputLen, BYTE *outBuffer) {
|
||||||
|
int i, k, numBlocks;
|
||||||
|
u_int8_t block[16], iv[4][4];
|
||||||
|
|
||||||
|
if (cipher == NULL ||
|
||||||
|
key == NULL ||
|
||||||
|
key->direction == DIR_DECRYPT) {
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
if (input == NULL || inputLen <= 0) {
|
||||||
|
return 0; /* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
numBlocks = inputLen/128;
|
||||||
|
|
||||||
|
switch (cipher->mode) {
|
||||||
|
case MODE_ECB:
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CBC:
|
||||||
|
#if 1 /*STRICT_ALIGN*/
|
||||||
|
memcpy(block, cipher->IV, 16);
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
|
||||||
|
((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
|
||||||
|
((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
|
||||||
|
((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
|
||||||
|
#else
|
||||||
|
((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0];
|
||||||
|
((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1];
|
||||||
|
((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2];
|
||||||
|
((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3];
|
||||||
|
#endif
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
for (i = numBlocks - 1; i > 0; i--) {
|
||||||
|
#if 1 /*STRICT_ALIGN*/
|
||||||
|
memcpy(block, outBuffer, 16);
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0];
|
||||||
|
((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1];
|
||||||
|
((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2];
|
||||||
|
((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3];
|
||||||
|
#else
|
||||||
|
((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0];
|
||||||
|
((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1];
|
||||||
|
((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2];
|
||||||
|
((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3];
|
||||||
|
#endif
|
||||||
|
outBuffer += 16;
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CFB1:
|
||||||
|
#if 1 /*STRICT_ALIGN*/
|
||||||
|
memcpy(iv, cipher->IV, 16);
|
||||||
|
#else /* !STRICT_ALIGN */
|
||||||
|
*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV ));
|
||||||
|
*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
|
||||||
|
*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
|
||||||
|
*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
|
||||||
|
#endif /* ?STRICT_ALIGN */
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
for (k = 0; k < 128; k++) {
|
||||||
|
*((u_int32_t*) block ) = *((u_int32_t*)iv[0]);
|
||||||
|
*((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
|
||||||
|
*((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
|
||||||
|
*((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
|
||||||
|
rijndaelEncrypt(key->ek, key->Nr, block,
|
||||||
|
block);
|
||||||
|
outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
|
||||||
|
iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
|
||||||
|
iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
|
||||||
|
iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
|
||||||
|
iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
|
||||||
|
iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
|
||||||
|
iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
|
||||||
|
iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
|
||||||
|
iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
|
||||||
|
iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
|
||||||
|
iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
|
||||||
|
iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
|
||||||
|
iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
|
||||||
|
iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
|
||||||
|
iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
|
||||||
|
iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
|
||||||
|
iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 128*numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Encrypt data partitioned in octets, using RFC 2040-like padding.
|
||||||
|
*
|
||||||
|
* @param input data to be encrypted (octet sequence)
|
||||||
|
* @param inputOctets input length in octets (not bits)
|
||||||
|
* @param outBuffer encrypted output data
|
||||||
|
*
|
||||||
|
* @return length in octets (not bits) of the encrypted output buffer.
|
||||||
|
*/
|
||||||
|
int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key,
|
||||||
|
BYTE *input, int inputOctets, BYTE *outBuffer) {
|
||||||
|
int i, numBlocks, padLen;
|
||||||
|
u_int8_t block[16], *iv, *cp;
|
||||||
|
|
||||||
|
if (cipher == NULL ||
|
||||||
|
key == NULL ||
|
||||||
|
key->direction == DIR_DECRYPT) {
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
if (input == NULL || inputOctets <= 0) {
|
||||||
|
return 0; /* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
numBlocks = inputOctets/16;
|
||||||
|
|
||||||
|
switch (cipher->mode) {
|
||||||
|
case MODE_ECB:
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, input, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
padLen = 16 - (inputOctets - 16*numBlocks);
|
||||||
|
if (padLen <= 0 || padLen > 16)
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
memcpy(block, input, 16 - padLen);
|
||||||
|
for (cp = block + 16 - padLen; cp < block + 16; cp++)
|
||||||
|
*cp = padLen;
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CBC:
|
||||||
|
iv = cipher->IV;
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0];
|
||||||
|
((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1];
|
||||||
|
((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2];
|
||||||
|
((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3];
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
|
||||||
|
iv = outBuffer;
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
padLen = 16 - (inputOctets - 16*numBlocks);
|
||||||
|
if (padLen <= 0 || padLen > 16)
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
for (i = 0; i < 16 - padLen; i++) {
|
||||||
|
block[i] = input[i] ^ iv[i];
|
||||||
|
}
|
||||||
|
for (i = 16 - padLen; i < 16; i++) {
|
||||||
|
block[i] = (BYTE)padLen ^ iv[i];
|
||||||
|
}
|
||||||
|
rijndaelEncrypt(key->rk, key->Nr, block, outBuffer);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 16*(numBlocks + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key,
|
||||||
|
BYTE *input, int inputLen, BYTE *outBuffer) {
|
||||||
|
int i, k, numBlocks;
|
||||||
|
u_int8_t block[16], iv[4][4];
|
||||||
|
|
||||||
|
if (cipher == NULL ||
|
||||||
|
key == NULL ||
|
||||||
|
(cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) {
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
if (input == NULL || inputLen <= 0) {
|
||||||
|
return 0; /* nothing to do */
|
||||||
|
}
|
||||||
|
|
||||||
|
numBlocks = inputLen/128;
|
||||||
|
|
||||||
|
switch (cipher->mode) {
|
||||||
|
case MODE_ECB:
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CBC:
|
||||||
|
#if 1 /*STRICT_ALIGN */
|
||||||
|
memcpy(iv, cipher->IV, 16);
|
||||||
|
#else
|
||||||
|
*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV ));
|
||||||
|
*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
|
||||||
|
*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
|
||||||
|
*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
|
||||||
|
#endif
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, block);
|
||||||
|
((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]);
|
||||||
|
((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]);
|
||||||
|
((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]);
|
||||||
|
((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]);
|
||||||
|
#if 1 /*STRICT_ALIGN*/
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
memcpy(outBuffer, block, 16);
|
||||||
|
#else
|
||||||
|
*((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0];
|
||||||
|
*((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1];
|
||||||
|
*((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2];
|
||||||
|
*((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_t*)block)[3];
|
||||||
|
#endif
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CFB1:
|
||||||
|
#if 1 /*STRICT_ALIGN */
|
||||||
|
memcpy(iv, cipher->IV, 16);
|
||||||
|
#else
|
||||||
|
*((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV));
|
||||||
|
*((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4));
|
||||||
|
*((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8));
|
||||||
|
*((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12));
|
||||||
|
#endif
|
||||||
|
for (i = numBlocks; i > 0; i--) {
|
||||||
|
for (k = 0; k < 128; k++) {
|
||||||
|
*((u_int32_t*) block ) = *((u_int32_t*)iv[0]);
|
||||||
|
*((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]);
|
||||||
|
*((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]);
|
||||||
|
*((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]);
|
||||||
|
rijndaelEncrypt(key->ek, key->Nr, block,
|
||||||
|
block);
|
||||||
|
iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
|
||||||
|
iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
|
||||||
|
iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
|
||||||
|
iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
|
||||||
|
iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
|
||||||
|
iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
|
||||||
|
iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
|
||||||
|
iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
|
||||||
|
iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
|
||||||
|
iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
|
||||||
|
iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
|
||||||
|
iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
|
||||||
|
iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
|
||||||
|
iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
|
||||||
|
iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
|
||||||
|
iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1);
|
||||||
|
outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 128*numBlocks;
|
||||||
|
}
|
||||||
|
|
||||||
|
int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key,
|
||||||
|
BYTE *input, int inputOctets, BYTE *outBuffer) {
|
||||||
|
int i, numBlocks, padLen;
|
||||||
|
u_int8_t block[16];
|
||||||
|
u_int32_t iv[4];
|
||||||
|
|
||||||
|
if (cipher == NULL ||
|
||||||
|
key == NULL ||
|
||||||
|
key->direction == DIR_ENCRYPT) {
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
if (input == NULL || inputOctets <= 0) {
|
||||||
|
return 0; /* nothing to do */
|
||||||
|
}
|
||||||
|
if (inputOctets % 16 != 0) {
|
||||||
|
return BAD_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
|
numBlocks = inputOctets/16;
|
||||||
|
|
||||||
|
switch (cipher->mode) {
|
||||||
|
case MODE_ECB:
|
||||||
|
/* all blocks but last */
|
||||||
|
for (i = numBlocks - 1; i > 0; i--) {
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, outBuffer);
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
/* last block */
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, block);
|
||||||
|
padLen = block[15];
|
||||||
|
if (padLen >= 16) {
|
||||||
|
return BAD_DATA;
|
||||||
|
}
|
||||||
|
for (i = 16 - padLen; i < 16; i++) {
|
||||||
|
if (block[i] != padLen) {
|
||||||
|
return BAD_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(outBuffer, block, 16 - padLen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MODE_CBC:
|
||||||
|
memcpy(iv, cipher->IV, 16);
|
||||||
|
/* all blocks but last */
|
||||||
|
for (i = numBlocks - 1; i > 0; i--) {
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, block);
|
||||||
|
((u_int32_t*)block)[0] ^= iv[0];
|
||||||
|
((u_int32_t*)block)[1] ^= iv[1];
|
||||||
|
((u_int32_t*)block)[2] ^= iv[2];
|
||||||
|
((u_int32_t*)block)[3] ^= iv[3];
|
||||||
|
memcpy(iv, input, 16);
|
||||||
|
memcpy(outBuffer, block, 16);
|
||||||
|
input += 16;
|
||||||
|
outBuffer += 16;
|
||||||
|
}
|
||||||
|
/* last block */
|
||||||
|
rijndaelDecrypt(key->rk, key->Nr, input, block);
|
||||||
|
((u_int32_t*)block)[0] ^= iv[0];
|
||||||
|
((u_int32_t*)block)[1] ^= iv[1];
|
||||||
|
((u_int32_t*)block)[2] ^= iv[2];
|
||||||
|
((u_int32_t*)block)[3] ^= iv[3];
|
||||||
|
padLen = block[15];
|
||||||
|
if (padLen <= 0 || padLen > 16) {
|
||||||
|
return BAD_DATA;
|
||||||
|
}
|
||||||
|
for (i = 16 - padLen; i < 16; i++) {
|
||||||
|
if (block[i] != padLen) {
|
||||||
|
return BAD_DATA;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
memcpy(outBuffer, block, 16 - padLen);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return BAD_CIPHER_STATE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 16*numBlocks - padLen;
|
||||||
|
}
|
||||||
@@ -0,0 +1,73 @@
|
|||||||
|
/* $FreeBSD$ */
|
||||||
|
/* $KAME: rijndael-api-fst.h,v 1.6 2001/05/27 00:23:23 itojun Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rijndael-api-fst.h v2.3 April '2000
|
||||||
|
*
|
||||||
|
* Optimised ANSI C code
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RIJNDAEL_API_FST_H
|
||||||
|
#define __RIJNDAEL_API_FST_H
|
||||||
|
|
||||||
|
#include <crypto/rijndael/rijndael.h>
|
||||||
|
|
||||||
|
/* Generic Defines */
|
||||||
|
#define DIR_ENCRYPT 0 /* Are we encrpyting? */
|
||||||
|
#define DIR_DECRYPT 1 /* Are we decrpyting? */
|
||||||
|
#define MODE_ECB 1 /* Are we ciphering in ECB mode? */
|
||||||
|
#define MODE_CBC 2 /* Are we ciphering in CBC mode? */
|
||||||
|
#define MODE_CFB1 3 /* Are we ciphering in 1-bit CFB mode? */
|
||||||
|
#define BITSPERBLOCK 128 /* Default number of bits in a cipher block */
|
||||||
|
|
||||||
|
/* Error Codes */
|
||||||
|
#define BAD_KEY_DIR -1 /* Key direction is invalid, e.g., unknown value */
|
||||||
|
#define BAD_KEY_MAT -2 /* Key material not of correct length */
|
||||||
|
#define BAD_KEY_INSTANCE -3 /* Key passed is not valid */
|
||||||
|
#define BAD_CIPHER_MODE -4 /* Params struct passed to cipherInit invalid */
|
||||||
|
#define BAD_CIPHER_STATE -5 /* Cipher in wrong state (e.g., not initialized) */
|
||||||
|
#define BAD_BLOCK_LENGTH -6
|
||||||
|
#define BAD_CIPHER_INSTANCE -7
|
||||||
|
#define BAD_DATA -8 /* Data contents are invalid, e.g., invalid padding */
|
||||||
|
#define BAD_OTHER -9 /* Unknown error */
|
||||||
|
|
||||||
|
/* Algorithm-specific Defines */
|
||||||
|
#define RIJNDAEL_MAX_KEY_SIZE 64 /* # of ASCII char's needed to represent a key */
|
||||||
|
#define RIJNDAEL_MAX_IV_SIZE 16 /* # bytes needed to represent an IV */
|
||||||
|
|
||||||
|
/* Typedefs */
|
||||||
|
|
||||||
|
/* The structure for key information */
|
||||||
|
typedef struct {
|
||||||
|
u_int8_t direction; /* Key used for encrypting or decrypting? */
|
||||||
|
int keyLen; /* Length of the key */
|
||||||
|
char keyMaterial[RIJNDAEL_MAX_KEY_SIZE+1]; /* Raw key data in ASCII, e.g., user input or KAT values */
|
||||||
|
int Nr; /* key-length-dependent number of rounds */
|
||||||
|
u_int32_t rk[4*(RIJNDAEL_MAXNR + 1)]; /* key schedule */
|
||||||
|
u_int32_t ek[4*(RIJNDAEL_MAXNR + 1)]; /* CFB1 key schedule (encryption only) */
|
||||||
|
} keyInstance;
|
||||||
|
|
||||||
|
/* The structure for cipher information */
|
||||||
|
typedef struct { /* changed order of the components */
|
||||||
|
u_int8_t mode; /* MODE_ECB, MODE_CBC, or MODE_CFB1 */
|
||||||
|
u_int8_t IV[RIJNDAEL_MAX_IV_SIZE]; /* A possible Initialization Vector for ciphering */
|
||||||
|
} cipherInstance;
|
||||||
|
|
||||||
|
/* Function prototypes */
|
||||||
|
|
||||||
|
int rijndael_makeKey(keyInstance *, u_int8_t, int, char *);
|
||||||
|
|
||||||
|
int rijndael_cipherInit(cipherInstance *, u_int8_t, char *);
|
||||||
|
|
||||||
|
int rijndael_blockEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int,
|
||||||
|
u_int8_t *);
|
||||||
|
int rijndael_padEncrypt(cipherInstance *, keyInstance *, u_int8_t *, int,
|
||||||
|
u_int8_t *);
|
||||||
|
|
||||||
|
int rijndael_blockDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int,
|
||||||
|
u_int8_t *);
|
||||||
|
int rijndael_padDecrypt(cipherInstance *, keyInstance *, u_int8_t *, int,
|
||||||
|
u_int8_t *);
|
||||||
|
|
||||||
|
#endif /* __RIJNDAEL_API_FST_H */
|
||||||
@@ -0,0 +1,59 @@
|
|||||||
|
/* $KAME: rijndael.c,v 1.3 2003/08/28 14:20:22 itojun Exp $ */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* rijndael-alg-fst.c
|
||||||
|
*
|
||||||
|
* @version 3.0 (December 2000)
|
||||||
|
*
|
||||||
|
* Optimised ANSI C code for the Rijndael cipher (now AES)
|
||||||
|
*
|
||||||
|
* @author Vincent Rijmen <[email protected]>
|
||||||
|
* @author Antoon Bosselaers <[email protected]>
|
||||||
|
* @author Paulo Barreto <[email protected]>
|
||||||
|
*
|
||||||
|
* This code is hereby placed in the public domain.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <sys/cdefs.h>
|
||||||
|
__FBSDID("$FreeBSD$");
|
||||||
|
|
||||||
|
#include <sys/types.h>
|
||||||
|
#ifdef _KERNEL
|
||||||
|
#include <sys/systm.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <crypto/rijndael/rijndael.h>
|
||||||
|
|
||||||
|
void
|
||||||
|
rijndael_set_key(rijndael_ctx *ctx, const u_char *key, int bits)
|
||||||
|
{
|
||||||
|
|
||||||
|
ctx->Nr = rijndaelKeySetupEnc(ctx->ek, key, bits);
|
||||||
|
rijndaelKeySetupDec(ctx->dk, key, bits);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rijndael_decrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst)
|
||||||
|
{
|
||||||
|
|
||||||
|
rijndaelDecrypt(ctx->dk, ctx->Nr, src, dst);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
rijndael_encrypt(const rijndael_ctx *ctx, const u_char *src, u_char *dst)
|
||||||
|
{
|
||||||
|
|
||||||
|
rijndaelEncrypt(ctx->ek, ctx->Nr, src, dst);
|
||||||
|
}
|
||||||
@@ -0,0 +1,55 @@
|
|||||||
|
/* $KAME: rijndael.h,v 1.6 2003/08/28 08:36:32 itojun Exp $ */
|
||||||
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* rijndael-alg-fst.h
|
||||||
|
*
|
||||||
|
* @version 3.0 (December 2000)
|
||||||
|
*
|
||||||
|
* Optimised ANSI C code for the Rijndael cipher (now AES)
|
||||||
|
*
|
||||||
|
* @author Vincent Rijmen <[email protected]>
|
||||||
|
* @author Antoon Bosselaers <[email protected]>
|
||||||
|
* @author Paulo Barreto <[email protected]>
|
||||||
|
*
|
||||||
|
* This code is hereby placed in the public domain.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHORS ''AS IS'' AND ANY EXPRESS
|
||||||
|
* OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||||
|
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR CONTRIBUTORS BE
|
||||||
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
|
||||||
|
* BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
|
||||||
|
* OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
|
||||||
|
* EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __RIJNDAEL_H
|
||||||
|
#define __RIJNDAEL_H
|
||||||
|
|
||||||
|
#define RIJNDAEL_MAXKC (256/32)
|
||||||
|
#define RIJNDAEL_MAXKB (256/8)
|
||||||
|
#define RIJNDAEL_MAXNR 14
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
int decrypt;
|
||||||
|
int Nr; /* key-length-dependent number of rounds */
|
||||||
|
uint32_t ek[4 * (RIJNDAEL_MAXNR + 1)]; /* encrypt key schedule */
|
||||||
|
uint32_t dk[4 * (RIJNDAEL_MAXNR + 1)]; /* decrypt key schedule */
|
||||||
|
} rijndael_ctx;
|
||||||
|
|
||||||
|
void rijndael_set_key(rijndael_ctx *, const u_char *, int);
|
||||||
|
void rijndael_decrypt(const rijndael_ctx *, const u_char *, u_char *);
|
||||||
|
void rijndael_encrypt(const rijndael_ctx *, const u_char *, u_char *);
|
||||||
|
|
||||||
|
int rijndaelKeySetupEnc(u_int32_t [/*4*(Nr+1)*/], const u_int8_t [], int);
|
||||||
|
int rijndaelKeySetupDec(u_int32_t [/*4*(Nr+1)*/], const u_int8_t [], int);
|
||||||
|
void rijndaelEncrypt(const u_int32_t [/*4*(Nr+1)*/], int,
|
||||||
|
const u_int8_t[16], u_int8_t [16]);
|
||||||
|
void rijndaelDecrypt(const u_int32_t [/*4*(Nr+1)*/], int,
|
||||||
|
const u_int8_t [16], u_int8_t [16]);
|
||||||
|
|
||||||
|
#endif /* __RIJNDAEL_H */
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
/* $KAME: rijndael_local.h,v 1.5 2003/08/28 08:37:24 itojun Exp $ */
|
||||||
|
/* $FreeBSD$ */
|
||||||
|
|
||||||
|
/* the file should not be used from outside */
|
||||||
|
typedef u_int8_t u8;
|
||||||
|
typedef u_int16_t u16;
|
||||||
|
typedef u_int32_t u32;
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
/*-
|
||||||
|
* Copyright (c) 2003 Poul-Henning Kamp
|
||||||
|
* All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions
|
||||||
|
* are met:
|
||||||
|
* 1. Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
* 2. Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||||
|
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||||
|
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||||
|
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||||
|
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||||
|
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||||
|
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||||
|
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||||
|
* SUCH DAMAGE.
|
||||||
|
*
|
||||||
|
* $FreeBSD$
|
||||||
|
*
|
||||||
|
* This test checks for inplace decryption working. This is the case
|
||||||
|
* where the same buffer is passed as input and output to
|
||||||
|
* rijndael_blockDecrypt().
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/param.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
#include <crypto/rijndael/rijndael-api-fst.h>
|
||||||
|
|
||||||
|
#define LL 32
|
||||||
|
int
|
||||||
|
main(int argc, char **argv)
|
||||||
|
{
|
||||||
|
keyInstance ki;
|
||||||
|
cipherInstance ci;
|
||||||
|
uint8_t key[16];
|
||||||
|
uint8_t in[LL];
|
||||||
|
uint8_t out[LL];
|
||||||
|
int i, j;
|
||||||
|
|
||||||
|
rijndael_cipherInit(&ci, MODE_CBC, NULL);
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
key[i] = i;
|
||||||
|
rijndael_makeKey(&ki, DIR_DECRYPT, 128, key);
|
||||||
|
for (i = 0; i < LL; i++)
|
||||||
|
in[i] = i;
|
||||||
|
rijndael_blockDecrypt(&ci, &ki, in, LL * 8, out);
|
||||||
|
for (i = 0; i < LL; i++)
|
||||||
|
printf("%02x", out[i]);
|
||||||
|
putchar('\n');
|
||||||
|
rijndael_blockDecrypt(&ci, &ki, in, LL * 8, in);
|
||||||
|
j = 0;
|
||||||
|
for (i = 0; i < LL; i++) {
|
||||||
|
printf("%02x", in[i]);
|
||||||
|
if (in[i] != out[i])
|
||||||
|
j++;
|
||||||
|
}
|
||||||
|
putchar('\n');
|
||||||
|
if (j != 0) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error: inplace decryption fails in %d places\n", j);
|
||||||
|
return (1);
|
||||||
|
} else {
|
||||||
|
return (0);
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user