19132d507SHajimu UMEMOTO /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ 2fe2869c8SKris Kennaway 39132d507SHajimu UMEMOTO /* 49132d507SHajimu UMEMOTO * rijndael-api-fst.c v2.3 April '2000 5fe2869c8SKris Kennaway * 69132d507SHajimu UMEMOTO * Optimised ANSI C code 7fe2869c8SKris Kennaway * 89132d507SHajimu UMEMOTO * authors: v1.0: Antoon Bosselaers 99132d507SHajimu UMEMOTO * v2.0: Vincent Rijmen 109132d507SHajimu UMEMOTO * v2.1: Vincent Rijmen 119132d507SHajimu UMEMOTO * v2.2: Vincent Rijmen 129132d507SHajimu UMEMOTO * v2.3: Paulo Barreto 139132d507SHajimu UMEMOTO * v2.4: Vincent Rijmen 14fe2869c8SKris Kennaway * 159132d507SHajimu UMEMOTO * This code is placed in the public domain. 16fe2869c8SKris Kennaway */ 17fe2869c8SKris Kennaway 18ad39da78SDavid E. O'Brien #include <sys/cdefs.h> 19ad39da78SDavid E. O'Brien __FBSDID("$FreeBSD$"); 20ad39da78SDavid E. O'Brien 21fe2869c8SKris Kennaway #include <sys/param.h> 2233841545SHajimu UMEMOTO #ifdef _KERNEL 2333841545SHajimu UMEMOTO #include <sys/systm.h> 2433841545SHajimu UMEMOTO #else 2533841545SHajimu UMEMOTO #include <string.h> 2633841545SHajimu UMEMOTO #endif 275129dcfcSHajimu UMEMOTO 285129dcfcSHajimu UMEMOTO #include <crypto/rijndael/rijndael_local.h> 29fe2869c8SKris Kennaway #include <crypto/rijndael/rijndael-api-fst.h> 309132d507SHajimu UMEMOTO 319132d507SHajimu UMEMOTO #ifndef TRUE 329132d507SHajimu UMEMOTO #define TRUE 1 339132d507SHajimu UMEMOTO #endif 349132d507SHajimu UMEMOTO 35*d3d79e96SJohn Baldwin typedef uint8_t BYTE; 3627da1009SPoul-Henning Kamp 37133cdd9eSDag-Erling Smørgrav int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, 38133cdd9eSDag-Erling Smørgrav const char *keyMaterial) { 39fe2869c8SKris Kennaway 40fe2869c8SKris Kennaway if (key == NULL) { 41fe2869c8SKris Kennaway return BAD_KEY_INSTANCE; 42fe2869c8SKris Kennaway } 43fe2869c8SKris Kennaway 44fe2869c8SKris Kennaway if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 45fe2869c8SKris Kennaway key->direction = direction; 46fe2869c8SKris Kennaway } else { 47fe2869c8SKris Kennaway return BAD_KEY_DIR; 48fe2869c8SKris Kennaway } 49fe2869c8SKris Kennaway 50fe2869c8SKris Kennaway if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 51fe2869c8SKris Kennaway key->keyLen = keyLen; 52fe2869c8SKris Kennaway } else { 53fe2869c8SKris Kennaway return BAD_KEY_MAT; 54fe2869c8SKris Kennaway } 55fe2869c8SKris Kennaway 56fe2869c8SKris Kennaway if (keyMaterial != NULL) { 575129dcfcSHajimu UMEMOTO memcpy(key->keyMaterial, keyMaterial, keyLen/8); 58fe2869c8SKris Kennaway } 59fe2869c8SKris Kennaway 60fe2869c8SKris Kennaway /* initialize key schedule: */ 615129dcfcSHajimu UMEMOTO if (direction == DIR_ENCRYPT) { 6207024904SConrad Meyer key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen); 635129dcfcSHajimu UMEMOTO } else { 6407024904SConrad Meyer key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen); 65fe2869c8SKris Kennaway } 6607024904SConrad Meyer rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen); 67fe2869c8SKris Kennaway return TRUE; 68fe2869c8SKris Kennaway } 69fe2869c8SKris Kennaway 70fe2869c8SKris Kennaway int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 71fe2869c8SKris Kennaway if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 72fe2869c8SKris Kennaway cipher->mode = mode; 73fe2869c8SKris Kennaway } else { 74fe2869c8SKris Kennaway return BAD_CIPHER_MODE; 75fe2869c8SKris Kennaway } 76fe2869c8SKris Kennaway if (IV != NULL) { 775129dcfcSHajimu UMEMOTO memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); 78fe2869c8SKris Kennaway } else { 795129dcfcSHajimu UMEMOTO memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); 80fe2869c8SKris Kennaway } 81fe2869c8SKris Kennaway return TRUE; 82fe2869c8SKris Kennaway } 83fe2869c8SKris Kennaway 84fe2869c8SKris Kennaway int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 85133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputLen, BYTE *outBuffer) { 869132d507SHajimu UMEMOTO int i, k, numBlocks; 87*d3d79e96SJohn Baldwin uint8_t block[16], iv[4][4]; 88fe2869c8SKris Kennaway 89fe2869c8SKris Kennaway if (cipher == NULL || 90fe2869c8SKris Kennaway key == NULL || 91fe2869c8SKris Kennaway key->direction == DIR_DECRYPT) { 92fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 93fe2869c8SKris Kennaway } 94fe2869c8SKris Kennaway if (input == NULL || inputLen <= 0) { 95fe2869c8SKris Kennaway return 0; /* nothing to do */ 96fe2869c8SKris Kennaway } 97fe2869c8SKris Kennaway 98fe2869c8SKris Kennaway numBlocks = inputLen/128; 99fe2869c8SKris Kennaway 100fe2869c8SKris Kennaway switch (cipher->mode) { 101fe2869c8SKris Kennaway case MODE_ECB: 102fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 1035129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 104fe2869c8SKris Kennaway input += 16; 105fe2869c8SKris Kennaway outBuffer += 16; 106fe2869c8SKris Kennaway } 107fe2869c8SKris Kennaway break; 108fe2869c8SKris Kennaway 109fe2869c8SKris Kennaway case MODE_CBC: 1103011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/ 1115129dcfcSHajimu UMEMOTO memcpy(block, cipher->IV, 16); 1125129dcfcSHajimu UMEMOTO memcpy(iv, input, 16); 113*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 114*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 115*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 116*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 1173011d4b3SHajimu UMEMOTO #else 118*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0]; 119*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1]; 120*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2]; 121*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3]; 1223011d4b3SHajimu UMEMOTO #endif 1235129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 124fe2869c8SKris Kennaway input += 16; 1259132d507SHajimu UMEMOTO for (i = numBlocks - 1; i > 0; i--) { 1269132d507SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/ 1275129dcfcSHajimu UMEMOTO memcpy(block, outBuffer, 16); 1285129dcfcSHajimu UMEMOTO memcpy(iv, input, 16); 129*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 130*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 131*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 132*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 1339132d507SHajimu UMEMOTO #else 134*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0]; 135*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1]; 136*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2]; 137*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3]; 1389132d507SHajimu UMEMOTO #endif 139fe2869c8SKris Kennaway outBuffer += 16; 1405129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 1419132d507SHajimu UMEMOTO input += 16; 142fe2869c8SKris Kennaway } 143fe2869c8SKris Kennaway break; 144fe2869c8SKris Kennaway 145fe2869c8SKris Kennaway case MODE_CFB1: 1463011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/ 1475129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16); 1489132d507SHajimu UMEMOTO #else /* !STRICT_ALIGN */ 149*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 150*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 151*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 152*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 1539132d507SHajimu UMEMOTO #endif /* ?STRICT_ALIGN */ 154fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 155fe2869c8SKris Kennaway for (k = 0; k < 128; k++) { 156*d3d79e96SJohn Baldwin *((uint32_t*) block ) = *((uint32_t*)iv[0]); 157*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 158*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 159*d3d79e96SJohn Baldwin *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 1605129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->ek, key->Nr, block, 1615129dcfcSHajimu UMEMOTO block); 1629132d507SHajimu UMEMOTO outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 1639132d507SHajimu UMEMOTO iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 1649132d507SHajimu UMEMOTO iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 1659132d507SHajimu UMEMOTO iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 1669132d507SHajimu UMEMOTO iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 1679132d507SHajimu UMEMOTO iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 1689132d507SHajimu UMEMOTO iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 1699132d507SHajimu UMEMOTO iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 1709132d507SHajimu UMEMOTO iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 1719132d507SHajimu UMEMOTO iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 1729132d507SHajimu UMEMOTO iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 1739132d507SHajimu UMEMOTO iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 1749132d507SHajimu UMEMOTO iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 1759132d507SHajimu UMEMOTO iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 1769132d507SHajimu UMEMOTO iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 1779132d507SHajimu UMEMOTO iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 1789132d507SHajimu UMEMOTO iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 179fe2869c8SKris Kennaway } 1808f21478bSHajimu UMEMOTO } 181fe2869c8SKris Kennaway break; 182fe2869c8SKris Kennaway 183fe2869c8SKris Kennaway default: 184fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 185fe2869c8SKris Kennaway } 186fe2869c8SKris Kennaway 18707024904SConrad Meyer explicit_bzero(block, sizeof(block)); 188fe2869c8SKris Kennaway return 128*numBlocks; 189fe2869c8SKris Kennaway } 190fe2869c8SKris Kennaway 191fe2869c8SKris Kennaway /** 192fe2869c8SKris Kennaway * Encrypt data partitioned in octets, using RFC 2040-like padding. 193fe2869c8SKris Kennaway * 194fe2869c8SKris Kennaway * @param input data to be encrypted (octet sequence) 195fe2869c8SKris Kennaway * @param inputOctets input length in octets (not bits) 196fe2869c8SKris Kennaway * @param outBuffer encrypted output data 197fe2869c8SKris Kennaway * 198fe2869c8SKris Kennaway * @return length in octets (not bits) of the encrypted output buffer. 199fe2869c8SKris Kennaway */ 200fe2869c8SKris Kennaway int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 201133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputOctets, BYTE *outBuffer) { 202fe2869c8SKris Kennaway int i, numBlocks, padLen; 203*d3d79e96SJohn Baldwin uint8_t block[16], *iv, *cp; 204fe2869c8SKris Kennaway 205fe2869c8SKris Kennaway if (cipher == NULL || 206fe2869c8SKris Kennaway key == NULL || 207fe2869c8SKris Kennaway key->direction == DIR_DECRYPT) { 208fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 209fe2869c8SKris Kennaway } 210fe2869c8SKris Kennaway if (input == NULL || inputOctets <= 0) { 211fe2869c8SKris Kennaway return 0; /* nothing to do */ 212fe2869c8SKris Kennaway } 213fe2869c8SKris Kennaway 214fe2869c8SKris Kennaway numBlocks = inputOctets/16; 215fe2869c8SKris Kennaway 216fe2869c8SKris Kennaway switch (cipher->mode) { 217fe2869c8SKris Kennaway case MODE_ECB: 218fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 2195129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 220fe2869c8SKris Kennaway input += 16; 221fe2869c8SKris Kennaway outBuffer += 16; 222fe2869c8SKris Kennaway } 223fe2869c8SKris Kennaway padLen = 16 - (inputOctets - 16*numBlocks); 224eb159f5bSHajimu UMEMOTO if (padLen <= 0 || padLen > 16) 22527da1009SPoul-Henning Kamp return BAD_CIPHER_STATE; 2265129dcfcSHajimu UMEMOTO memcpy(block, input, 16 - padLen); 2279132d507SHajimu UMEMOTO for (cp = block + 16 - padLen; cp < block + 16; cp++) 2289132d507SHajimu UMEMOTO *cp = padLen; 2295129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 230fe2869c8SKris Kennaway break; 231fe2869c8SKris Kennaway 232fe2869c8SKris Kennaway case MODE_CBC: 233fe2869c8SKris Kennaway iv = cipher->IV; 234fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 235*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0]; 236*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1]; 237*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2]; 238*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3]; 2395129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 240fe2869c8SKris Kennaway iv = outBuffer; 241fe2869c8SKris Kennaway input += 16; 242fe2869c8SKris Kennaway outBuffer += 16; 243fe2869c8SKris Kennaway } 244fe2869c8SKris Kennaway padLen = 16 - (inputOctets - 16*numBlocks); 24566476d45SHajimu UMEMOTO if (padLen <= 0 || padLen > 16) 24627da1009SPoul-Henning Kamp return BAD_CIPHER_STATE; 247fe2869c8SKris Kennaway for (i = 0; i < 16 - padLen; i++) { 248fe2869c8SKris Kennaway block[i] = input[i] ^ iv[i]; 249fe2869c8SKris Kennaway } 250fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) { 251fe2869c8SKris Kennaway block[i] = (BYTE)padLen ^ iv[i]; 252fe2869c8SKris Kennaway } 2535129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 254fe2869c8SKris Kennaway break; 255fe2869c8SKris Kennaway 256fe2869c8SKris Kennaway default: 257fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 258fe2869c8SKris Kennaway } 259fe2869c8SKris Kennaway 26007024904SConrad Meyer explicit_bzero(block, sizeof(block)); 261fe2869c8SKris Kennaway return 16*(numBlocks + 1); 262fe2869c8SKris Kennaway } 263fe2869c8SKris Kennaway 264fe2869c8SKris Kennaway int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 265133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputLen, BYTE *outBuffer) { 2669132d507SHajimu UMEMOTO int i, k, numBlocks; 267*d3d79e96SJohn Baldwin uint8_t block[16], iv[4][4]; 268fe2869c8SKris Kennaway 269fe2869c8SKris Kennaway if (cipher == NULL || 270fe2869c8SKris Kennaway key == NULL || 271fe2869c8SKris Kennaway (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 272fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 273fe2869c8SKris Kennaway } 274fe2869c8SKris Kennaway if (input == NULL || inputLen <= 0) { 275fe2869c8SKris Kennaway return 0; /* nothing to do */ 276fe2869c8SKris Kennaway } 277fe2869c8SKris Kennaway 278fe2869c8SKris Kennaway numBlocks = inputLen/128; 279fe2869c8SKris Kennaway 280fe2869c8SKris Kennaway switch (cipher->mode) { 281fe2869c8SKris Kennaway case MODE_ECB: 282fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 2835129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 284fe2869c8SKris Kennaway input += 16; 285fe2869c8SKris Kennaway outBuffer += 16; 286fe2869c8SKris Kennaway } 287fe2869c8SKris Kennaway break; 288fe2869c8SKris Kennaway 289fe2869c8SKris Kennaway case MODE_CBC: 2903011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */ 2915129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16); 2923011d4b3SHajimu UMEMOTO #else 293*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 294*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 295*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 296*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 2973011d4b3SHajimu UMEMOTO #endif 298fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 2995129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block); 300*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]); 301*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]); 302*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]); 303*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]); 3043011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN*/ 3055129dcfcSHajimu UMEMOTO memcpy(iv, input, 16); 3065129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16); 3073011d4b3SHajimu UMEMOTO #else 308*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0]; 309*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1]; 310*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2]; 311*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3]; 3123011d4b3SHajimu UMEMOTO #endif 313fe2869c8SKris Kennaway input += 16; 314fe2869c8SKris Kennaway outBuffer += 16; 315fe2869c8SKris Kennaway } 316fe2869c8SKris Kennaway break; 317fe2869c8SKris Kennaway 318fe2869c8SKris Kennaway case MODE_CFB1: 3193011d4b3SHajimu UMEMOTO #if 1 /*STRICT_ALIGN */ 3205129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16); 3213011d4b3SHajimu UMEMOTO #else 322*d3d79e96SJohn Baldwin *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV)); 323*d3d79e96SJohn Baldwin *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 324*d3d79e96SJohn Baldwin *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 325*d3d79e96SJohn Baldwin *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 3263011d4b3SHajimu UMEMOTO #endif 327fe2869c8SKris Kennaway for (i = numBlocks; i > 0; i--) { 328fe2869c8SKris Kennaway for (k = 0; k < 128; k++) { 329*d3d79e96SJohn Baldwin *((uint32_t*) block ) = *((uint32_t*)iv[0]); 330*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 331*d3d79e96SJohn Baldwin *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 332*d3d79e96SJohn Baldwin *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 3335129dcfcSHajimu UMEMOTO rijndaelEncrypt(key->ek, key->Nr, block, 3345129dcfcSHajimu UMEMOTO block); 3359132d507SHajimu UMEMOTO iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 3369132d507SHajimu UMEMOTO iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 3379132d507SHajimu UMEMOTO iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 3389132d507SHajimu UMEMOTO iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 3399132d507SHajimu UMEMOTO iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 3409132d507SHajimu UMEMOTO iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 3419132d507SHajimu UMEMOTO iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 3429132d507SHajimu UMEMOTO iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 3439132d507SHajimu UMEMOTO iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 3449132d507SHajimu UMEMOTO iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 3459132d507SHajimu UMEMOTO iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 3469132d507SHajimu UMEMOTO iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 3479132d507SHajimu UMEMOTO iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 3489132d507SHajimu UMEMOTO iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 3499132d507SHajimu UMEMOTO iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 3509132d507SHajimu UMEMOTO iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 3519132d507SHajimu UMEMOTO outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 352fe2869c8SKris Kennaway } 3538f21478bSHajimu UMEMOTO } 354fe2869c8SKris Kennaway break; 355fe2869c8SKris Kennaway 356fe2869c8SKris Kennaway default: 357fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 358fe2869c8SKris Kennaway } 359fe2869c8SKris Kennaway 36007024904SConrad Meyer explicit_bzero(block, sizeof(block)); 361fe2869c8SKris Kennaway return 128*numBlocks; 362fe2869c8SKris Kennaway } 363fe2869c8SKris Kennaway 364fe2869c8SKris Kennaway int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 365133cdd9eSDag-Erling Smørgrav const BYTE *input, int inputOctets, BYTE *outBuffer) { 36607024904SConrad Meyer int i, numBlocks, padLen, rval; 367*d3d79e96SJohn Baldwin uint8_t block[16]; 368*d3d79e96SJohn Baldwin uint32_t iv[4]; 369fe2869c8SKris Kennaway 370fe2869c8SKris Kennaway if (cipher == NULL || 371fe2869c8SKris Kennaway key == NULL || 372fe2869c8SKris Kennaway key->direction == DIR_ENCRYPT) { 373fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 374fe2869c8SKris Kennaway } 375fe2869c8SKris Kennaway if (input == NULL || inputOctets <= 0) { 376fe2869c8SKris Kennaway return 0; /* nothing to do */ 377fe2869c8SKris Kennaway } 378fe2869c8SKris Kennaway if (inputOctets % 16 != 0) { 379fe2869c8SKris Kennaway return BAD_DATA; 380fe2869c8SKris Kennaway } 381fe2869c8SKris Kennaway 382fe2869c8SKris Kennaway numBlocks = inputOctets/16; 383fe2869c8SKris Kennaway 384fe2869c8SKris Kennaway switch (cipher->mode) { 385fe2869c8SKris Kennaway case MODE_ECB: 386fe2869c8SKris Kennaway /* all blocks but last */ 387fe2869c8SKris Kennaway for (i = numBlocks - 1; i > 0; i--) { 3885129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 389fe2869c8SKris Kennaway input += 16; 390fe2869c8SKris Kennaway outBuffer += 16; 391fe2869c8SKris Kennaway } 392fe2869c8SKris Kennaway /* last block */ 3935129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block); 394fe2869c8SKris Kennaway padLen = block[15]; 395fe2869c8SKris Kennaway if (padLen >= 16) { 39607024904SConrad Meyer rval = BAD_DATA; 39707024904SConrad Meyer goto out; 398fe2869c8SKris Kennaway } 399fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) { 400fe2869c8SKris Kennaway if (block[i] != padLen) { 40107024904SConrad Meyer rval = BAD_DATA; 40207024904SConrad Meyer goto out; 403fe2869c8SKris Kennaway } 404fe2869c8SKris Kennaway } 4055129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16 - padLen); 406fe2869c8SKris Kennaway break; 407fe2869c8SKris Kennaway 408fe2869c8SKris Kennaway case MODE_CBC: 4095129dcfcSHajimu UMEMOTO memcpy(iv, cipher->IV, 16); 410fe2869c8SKris Kennaway /* all blocks but last */ 411fe2869c8SKris Kennaway for (i = numBlocks - 1; i > 0; i--) { 4125129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block); 413*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= iv[0]; 414*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= iv[1]; 415*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= iv[2]; 416*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= iv[3]; 4175129dcfcSHajimu UMEMOTO memcpy(iv, input, 16); 4185129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16); 419fe2869c8SKris Kennaway input += 16; 420fe2869c8SKris Kennaway outBuffer += 16; 421fe2869c8SKris Kennaway } 422fe2869c8SKris Kennaway /* last block */ 4235129dcfcSHajimu UMEMOTO rijndaelDecrypt(key->rk, key->Nr, input, block); 424*d3d79e96SJohn Baldwin ((uint32_t*)block)[0] ^= iv[0]; 425*d3d79e96SJohn Baldwin ((uint32_t*)block)[1] ^= iv[1]; 426*d3d79e96SJohn Baldwin ((uint32_t*)block)[2] ^= iv[2]; 427*d3d79e96SJohn Baldwin ((uint32_t*)block)[3] ^= iv[3]; 428fe2869c8SKris Kennaway padLen = block[15]; 429fe2869c8SKris Kennaway if (padLen <= 0 || padLen > 16) { 43007024904SConrad Meyer rval = BAD_DATA; 43107024904SConrad Meyer goto out; 432fe2869c8SKris Kennaway } 433fe2869c8SKris Kennaway for (i = 16 - padLen; i < 16; i++) { 434fe2869c8SKris Kennaway if (block[i] != padLen) { 43507024904SConrad Meyer rval = BAD_DATA; 43607024904SConrad Meyer goto out; 437fe2869c8SKris Kennaway } 438fe2869c8SKris Kennaway } 4395129dcfcSHajimu UMEMOTO memcpy(outBuffer, block, 16 - padLen); 440fe2869c8SKris Kennaway break; 441fe2869c8SKris Kennaway 442fe2869c8SKris Kennaway default: 443fe2869c8SKris Kennaway return BAD_CIPHER_STATE; 444fe2869c8SKris Kennaway } 445fe2869c8SKris Kennaway 44607024904SConrad Meyer rval = 16*numBlocks - padLen; 44707024904SConrad Meyer 44807024904SConrad Meyer out: 44907024904SConrad Meyer explicit_bzero(block, sizeof(block)); 45007024904SConrad Meyer return rval; 451fe2869c8SKris Kennaway } 452