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