rijndael-api-fst.c revision 78064
1178481Sjb/* $FreeBSD: head/sys/crypto/rijndael/rijndael-api-fst.c 78064 2001-06-11 12:39:29Z ume $ */ 2178481Sjb/* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ 3178481Sjb 4178481Sjb/* 5178481Sjb * rijndael-api-fst.c v2.3 April '2000 6178481Sjb * 7178481Sjb * Optimised ANSI C code 8178481Sjb * 9178481Sjb * authors: v1.0: Antoon Bosselaers 10178481Sjb * v2.0: Vincent Rijmen 11178481Sjb * v2.1: Vincent Rijmen 12178481Sjb * v2.2: Vincent Rijmen 13178481Sjb * v2.3: Paulo Barreto 14178481Sjb * v2.4: Vincent Rijmen 15178481Sjb * 16178481Sjb * This code is placed in the public domain. 17178481Sjb */ 18178481Sjb 19178481Sjb#include <sys/param.h> 20178481Sjb#include <sys/types.h> 21178481Sjb#ifdef _KERNEL 22178481Sjb#include <sys/systm.h> 23178481Sjb#else 24178481Sjb#include <string.h> 25178481Sjb#endif 26178481Sjb#include <crypto/rijndael/rijndael-alg-fst.h> 27178481Sjb#include <crypto/rijndael/rijndael-api-fst.h> 28178481Sjb#include <crypto/rijndael/rijndael_local.h> 29178481Sjb 30178481Sjbint rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { 31178481Sjb word8 k[MAXKC][4]; 32178481Sjb int i; 33178481Sjb char *keyMat; 34178481Sjb 35178481Sjb if (key == NULL) { 36178481Sjb return BAD_KEY_INSTANCE; 37178481Sjb } 38178481Sjb 39178481Sjb if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 40178481Sjb key->direction = direction; 41178481Sjb } else { 42178481Sjb return BAD_KEY_DIR; 43178481Sjb } 44178481Sjb 45178481Sjb if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 46178481Sjb key->keyLen = keyLen; 47178481Sjb } else { 48178481Sjb return BAD_KEY_MAT; 49178481Sjb } 50178481Sjb 51178481Sjb if (keyMaterial != NULL) { 52178481Sjb bcopy(keyMaterial, key->keyMaterial, keyLen/8); 53178481Sjb } 54178481Sjb 55178481Sjb key->ROUNDS = keyLen/32 + 6; 56178481Sjb 57178481Sjb /* initialize key schedule: */ 58178481Sjb keyMat = key->keyMaterial; 59178481Sjb for (i = 0; i < key->keyLen/8; i++) { 60178481Sjb k[i >> 2][i & 3] = (word8)keyMat[i]; 61178481Sjb } 62178481Sjb rijndaelKeySched(k, key->keySched, key->ROUNDS); 63178481Sjb if (direction == DIR_DECRYPT) { 64178481Sjb rijndaelKeyEncToDec(key->keySched, key->ROUNDS); 65178481Sjb } 66178481Sjb 67178481Sjb return TRUE; 68178481Sjb} 69178481Sjb 70178481Sjbint rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 71178481Sjb if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 72178481Sjb cipher->mode = mode; 73178481Sjb } else { 74178481Sjb return BAD_CIPHER_MODE; 75178481Sjb } 76178481Sjb if (IV != NULL) { 77178481Sjb bcopy(IV, cipher->IV, MAX_IV_SIZE); 78178481Sjb } else { 79178481Sjb bzero(cipher->IV, MAX_IV_SIZE); 80178481Sjb } 81178481Sjb return TRUE; 82178481Sjb} 83178481Sjb 84178481Sjbint rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 85178481Sjb BYTE *input, int inputLen, BYTE *outBuffer) { 86178481Sjb int i, k, numBlocks; 87178481Sjb word8 block[16], iv[4][4]; 88178481Sjb 89178481Sjb if (cipher == NULL || 90178481Sjb key == NULL || 91178481Sjb key->direction == DIR_DECRYPT) { 92178481Sjb return BAD_CIPHER_STATE; 93178481Sjb } 94178481Sjb if (input == NULL || inputLen <= 0) { 95178481Sjb return 0; /* nothing to do */ 96178481Sjb } 97178481Sjb 98178481Sjb numBlocks = inputLen/128; 99178481Sjb 100178481Sjb switch (cipher->mode) { 101178481Sjb case MODE_ECB: 102178481Sjb for (i = numBlocks; i > 0; i--) { 103178481Sjb rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); 104178481Sjb input += 16; 105178481Sjb outBuffer += 16; 106178481Sjb } 107178481Sjb break; 108178481Sjb 109178481Sjb case MODE_CBC: 110178481Sjb#if 1 /*STRICT_ALIGN*/ 111178481Sjb bcopy(cipher->IV, block, 16); 112178481Sjb bcopy(input, iv, 16); 113178481Sjb ((word32*)block)[0] ^= ((word32*)iv)[0]; 114178481Sjb ((word32*)block)[1] ^= ((word32*)iv)[1]; 115178481Sjb ((word32*)block)[2] ^= ((word32*)iv)[2]; 116178481Sjb ((word32*)block)[3] ^= ((word32*)iv)[3]; 117178481Sjb#else 118178481Sjb ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0]; 119178481Sjb ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1]; 120178481Sjb ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2]; 121178481Sjb ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3]; 122178481Sjb#endif 123178481Sjb rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 124178481Sjb input += 16; 125178481Sjb for (i = numBlocks - 1; i > 0; i--) { 126178481Sjb#if 1 /*STRICT_ALIGN*/ 127178481Sjb bcopy(outBuffer, block, 16); 128178481Sjb ((word32*)block)[0] ^= ((word32*)iv)[0]; 129178481Sjb ((word32*)block)[1] ^= ((word32*)iv)[1]; 130178481Sjb ((word32*)block)[2] ^= ((word32*)iv)[2]; 131178481Sjb ((word32*)block)[3] ^= ((word32*)iv)[3]; 132178481Sjb#else 133178481Sjb ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0]; 134178481Sjb ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1]; 135178546Sjb ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2]; 136178481Sjb ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3]; 137178481Sjb#endif 138178481Sjb outBuffer += 16; 139178481Sjb rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 140178481Sjb input += 16; 141178481Sjb } 142178481Sjb break; 143178481Sjb 144178481Sjb case MODE_CFB1: 145178481Sjb#if 1 /*STRICT_ALIGN*/ 146178481Sjb bcopy(cipher->IV, iv, 16); 147178481Sjb#else /* !STRICT_ALIGN */ 148178481Sjb *((word32*)iv[0]) = *((word32*)(cipher->IV )); 149178481Sjb *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 150178481Sjb *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 151178481Sjb *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 152178481Sjb#endif /* ?STRICT_ALIGN */ 153178481Sjb for (i = numBlocks; i > 0; i--) { 154178481Sjb for (k = 0; k < 128; k++) { 155178481Sjb *((word32*) block ) = *((word32*)iv[0]); 156178481Sjb *((word32*)(block+ 4)) = *((word32*)iv[1]); 157178481Sjb *((word32*)(block+ 8)) = *((word32*)iv[2]); 158178481Sjb *((word32*)(block+12)) = *((word32*)iv[3]); 159178481Sjb rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); 160178481Sjb outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 161178481Sjb iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 162178481Sjb iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 163178481Sjb iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 164178481Sjb iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 165178481Sjb iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 166178481Sjb iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 167178481Sjb iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 168178481Sjb iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 169178481Sjb iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 170178481Sjb iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 171178481Sjb iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 172178481Sjb iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 173178481Sjb iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 174178481Sjb iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 175178481Sjb iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 176178481Sjb iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 177178481Sjb } 178178481Sjb } 179178481Sjb break; 180178481Sjb 181178481Sjb default: 182178546Sjb return BAD_CIPHER_STATE; 183178481Sjb } 184178546Sjb 185178481Sjb return 128*numBlocks; 186178481Sjb} 187178546Sjb 188178481Sjb/** 189178481Sjb * Encrypt data partitioned in octets, using RFC 2040-like padding. 190178481Sjb * 191178481Sjb * @param input data to be encrypted (octet sequence) 192178481Sjb * @param inputOctets input length in octets (not bits) 193178546Sjb * @param outBuffer encrypted output data 194178481Sjb * 195178546Sjb * @return length in octets (not bits) of the encrypted output buffer. 196178546Sjb */ 197178481Sjbint rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 198178481Sjb BYTE *input, int inputOctets, BYTE *outBuffer) { 199178481Sjb int i, numBlocks, padLen; 200178481Sjb word8 block[16], *iv, *cp; 201178481Sjb 202178481Sjb if (cipher == NULL || 203178481Sjb key == NULL || 204178481Sjb key->direction == DIR_DECRYPT) { 205178481Sjb return BAD_CIPHER_STATE; 206178481Sjb } 207178481Sjb if (input == NULL || inputOctets <= 0) { 208178481Sjb return 0; /* nothing to do */ 209178481Sjb } 210178481Sjb 211178481Sjb numBlocks = inputOctets/16; 212178481Sjb 213178481Sjb switch (cipher->mode) { 214178481Sjb case MODE_ECB: 215178481Sjb for (i = numBlocks; i > 0; i--) { 216178481Sjb rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); 217178481Sjb input += 16; 218178481Sjb outBuffer += 16; 219178546Sjb } 220178481Sjb padLen = 16 - (inputOctets - 16*numBlocks); 221178481Sjb if (padLen > 0 && padLen <= 16) 222178481Sjb panic("rijndael_padEncrypt(ECB)"); 223178481Sjb bcopy(input, block, 16 - padLen); 224178481Sjb for (cp = block + 16 - padLen; cp < block + 16; cp++) 225178481Sjb *cp = padLen; 226178481Sjb rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 227178481Sjb break; 228178481Sjb 229178481Sjb case MODE_CBC: 230178481Sjb iv = cipher->IV; 231178481Sjb for (i = numBlocks; i > 0; i--) { 232178481Sjb ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0]; 233178481Sjb ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1]; 234178481Sjb ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2]; 235178481Sjb ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3]; 236178481Sjb rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 237178481Sjb iv = outBuffer; 238178481Sjb input += 16; 239178481Sjb outBuffer += 16; 240178481Sjb } 241178481Sjb padLen = 16 - (inputOctets - 16*numBlocks); 242178481Sjb if (padLen > 0 && padLen <= 16) 243178481Sjb panic("rijndael_padEncrypt(CBC)"); 244178481Sjb for (i = 0; i < 16 - padLen; i++) { 245178481Sjb block[i] = input[i] ^ iv[i]; 246178481Sjb } 247178481Sjb for (i = 16 - padLen; i < 16; i++) { 248178481Sjb block[i] = (BYTE)padLen ^ iv[i]; 249178481Sjb } 250178481Sjb rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 251178481Sjb break; 252178481Sjb 253178481Sjb default: 254178481Sjb return BAD_CIPHER_STATE; 255178481Sjb } 256178481Sjb 257178481Sjb return 16*(numBlocks + 1); 258178481Sjb} 259178546Sjb 260178481Sjbint rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 261178481Sjb BYTE *input, int inputLen, BYTE *outBuffer) { 262178481Sjb int i, k, numBlocks; 263178481Sjb word8 block[16], iv[4][4]; 264178481Sjb 265178481Sjb if (cipher == NULL || 266178481Sjb key == NULL || 267178481Sjb (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 268178481Sjb return BAD_CIPHER_STATE; 269178481Sjb } 270178481Sjb if (input == NULL || inputLen <= 0) { 271178481Sjb return 0; /* nothing to do */ 272178481Sjb } 273178481Sjb 274178481Sjb numBlocks = inputLen/128; 275178481Sjb 276178481Sjb switch (cipher->mode) { 277178481Sjb case MODE_ECB: 278178481Sjb for (i = numBlocks; i > 0; i--) { 279178481Sjb rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); 280178481Sjb input += 16; 281178481Sjb outBuffer += 16; 282178481Sjb } 283178481Sjb break; 284178481Sjb 285178481Sjb case MODE_CBC: 286178481Sjb#if 1 /*STRICT_ALIGN */ 287178481Sjb bcopy(cipher->IV, iv, 16); 288178481Sjb#else 289178481Sjb *((word32*)iv[0]) = *((word32*)(cipher->IV )); 290178481Sjb *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 291178481Sjb *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 292178481Sjb *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 293178481Sjb#endif 294178481Sjb for (i = numBlocks; i > 0; i--) { 295178481Sjb rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 296178481Sjb ((word32*)block)[0] ^= *((word32*)iv[0]); 297178481Sjb ((word32*)block)[1] ^= *((word32*)iv[1]); 298178481Sjb ((word32*)block)[2] ^= *((word32*)iv[2]); 299178481Sjb ((word32*)block)[3] ^= *((word32*)iv[3]); 300178481Sjb#if 1 /*STRICT_ALIGN*/ 301178481Sjb bcopy(input, iv, 16); 302178481Sjb bcopy(block, outBuffer, 16); 303178481Sjb#else 304178481Sjb *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0]; 305178481Sjb *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1]; 306178481Sjb *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2]; 307178481Sjb *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3]; 308178481Sjb#endif 309178481Sjb input += 16; 310178481Sjb outBuffer += 16; 311178481Sjb } 312178481Sjb break; 313178481Sjb 314178481Sjb case MODE_CFB1: 315178481Sjb#if 1 /*STRICT_ALIGN */ 316178546Sjb bcopy(cipher->IV, iv, 16); 317178481Sjb#else 318178481Sjb *((word32*)iv[0]) = *((word32*)(cipher->IV)); 319178481Sjb *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 320178481Sjb *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 321178481Sjb *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 322178481Sjb#endif 323178481Sjb for (i = numBlocks; i > 0; i--) { 324178481Sjb for (k = 0; k < 128; k++) { 325178481Sjb *((word32*) block ) = *((word32*)iv[0]); 326178481Sjb *((word32*)(block+ 4)) = *((word32*)iv[1]); 327178481Sjb *((word32*)(block+ 8)) = *((word32*)iv[2]); 328178481Sjb *((word32*)(block+12)) = *((word32*)iv[3]); 329178481Sjb rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); 330178481Sjb iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 331178481Sjb iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 332178481Sjb iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 333178481Sjb iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 334178481Sjb iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 335178481Sjb iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 336178481Sjb iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 337178481Sjb iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 338178546Sjb iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 339178481Sjb iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 340178481Sjb iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 341178481Sjb iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 342178481Sjb iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 343178481Sjb iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 344178481Sjb iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 345178481Sjb iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 346178481Sjb outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 347178481Sjb } 348178481Sjb } 349178481Sjb break; 350178481Sjb 351178481Sjb default: 352178481Sjb return BAD_CIPHER_STATE; 353178481Sjb } 354178481Sjb 355178481Sjb return 128*numBlocks; 356178481Sjb} 357178546Sjb 358178481Sjbint rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 359178481Sjb BYTE *input, int inputOctets, BYTE *outBuffer) { 360178481Sjb int i, numBlocks, padLen; 361178481Sjb word8 block[16]; 362178481Sjb word32 iv[4]; 363178481Sjb 364178481Sjb if (cipher == NULL || 365178481Sjb key == NULL || 366178481Sjb key->direction == DIR_ENCRYPT) { 367178481Sjb return BAD_CIPHER_STATE; 368178481Sjb } 369178481Sjb if (input == NULL || inputOctets <= 0) { 370178481Sjb return 0; /* nothing to do */ 371178481Sjb } 372178481Sjb if (inputOctets % 16 != 0) { 373178481Sjb return BAD_DATA; 374178481Sjb } 375178481Sjb 376178481Sjb numBlocks = inputOctets/16; 377178481Sjb 378178481Sjb switch (cipher->mode) { 379178481Sjb case MODE_ECB: 380178481Sjb /* all blocks but last */ 381178481Sjb for (i = numBlocks - 1; i > 0; i--) { 382178481Sjb rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); 383178481Sjb input += 16; 384178481Sjb outBuffer += 16; 385178481Sjb } 386178481Sjb /* last block */ 387178481Sjb rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 388178481Sjb padLen = block[15]; 389178481Sjb if (padLen >= 16) { 390178481Sjb return BAD_DATA; 391178481Sjb } 392178481Sjb for (i = 16 - padLen; i < 16; i++) { 393178481Sjb if (block[i] != padLen) { 394178481Sjb return BAD_DATA; 395178481Sjb } 396178481Sjb } 397178481Sjb bcopy(block, outBuffer, 16 - padLen); 398178481Sjb break; 399178481Sjb 400178481Sjb case MODE_CBC: 401178481Sjb bcopy(cipher->IV, iv, 16); 402178481Sjb /* all blocks but last */ 403178481Sjb for (i = numBlocks - 1; i > 0; i--) { 404178481Sjb rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 405178481Sjb ((word32*)block)[0] ^= iv[0]; 406178481Sjb ((word32*)block)[1] ^= iv[1]; 407178481Sjb ((word32*)block)[2] ^= iv[2]; 408178481Sjb ((word32*)block)[3] ^= iv[3]; 409178481Sjb bcopy(input, iv, 16); 410178481Sjb bcopy(block, outBuffer, 16); 411178481Sjb input += 16; 412178481Sjb outBuffer += 16; 413178481Sjb } 414178481Sjb /* last block */ 415178481Sjb rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 416178481Sjb ((word32*)block)[0] ^= iv[0]; 417178481Sjb ((word32*)block)[1] ^= iv[1]; 418178481Sjb ((word32*)block)[2] ^= iv[2]; 419178481Sjb ((word32*)block)[3] ^= iv[3]; 420178481Sjb padLen = block[15]; 421178546Sjb if (padLen <= 0 || padLen > 16) { 422178546Sjb return BAD_DATA; 423178481Sjb } 424178481Sjb for (i = 16 - padLen; i < 16; i++) { 425178481Sjb if (block[i] != padLen) { 426178481Sjb return BAD_DATA; 427178481Sjb } 428178481Sjb } 429178481Sjb bcopy(block, outBuffer, 16 - padLen); 430178481Sjb break; 431178481Sjb 432178481Sjb default: 433178546Sjb return BAD_CIPHER_STATE; 434178481Sjb } 435178481Sjb 436178481Sjb return 16*numBlocks - padLen; 437178481Sjb} 438178481Sjb 439178481Sjb#ifdef INTERMEDIATE_VALUE_KAT 440178481Sjb/** 441178481Sjb * cipherUpdateRounds: 442178481Sjb * 443178481Sjb * Encrypts/Decrypts exactly one full block a specified number of rounds. 444178481Sjb * Only used in the Intermediate Value Known Answer Test. 445178546Sjb * 446178481Sjb * Returns: 447178481Sjb * TRUE - on success 448178481Sjb * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) 449178481Sjb */ 450178481Sjbint rijndael_cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, 451178481Sjb BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { 452178481Sjb int j; 453178481Sjb word8 block[4][4]; 454178481Sjb 455178481Sjb if (cipher == NULL || key == NULL) { 456178546Sjb return BAD_CIPHER_STATE; 457178481Sjb } 458178481Sjb 459178481Sjb for (j = 3; j >= 0; j--) { 460178481Sjb /* parse input stream into rectangular array */ 461178481Sjb *((word32*)block[j]) = *((word32*)(input+4*j)); 462178481Sjb } 463178481Sjb 464178546Sjb switch (key->direction) { 465178481Sjb case DIR_ENCRYPT: 466178481Sjb rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds); 467178481Sjb break; 468178481Sjb 469178481Sjb case DIR_DECRYPT: 470178481Sjb rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds); 471178481Sjb break; 472178481Sjb 473178481Sjb default: 474178481Sjb return BAD_KEY_DIR; 475178481Sjb } 476178481Sjb 477178481Sjb for (j = 3; j >= 0; j--) { 478178481Sjb /* parse rectangular array into output ciphertext bytes */ 479178481Sjb *((word32*)(outBuffer+4*j)) = *((word32*)block[j]); 480178481Sjb } 481178481Sjb 482178481Sjb return TRUE; 483178481Sjb} 484178481Sjb#endif /* INTERMEDIATE_VALUE_KAT */ 485178546Sjb