1 /* $FreeBSD$ */ 2 /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ 3 4 /* 5 * rijndael-api-fst.c v2.3 April '2000 6 * 7 * Optimised ANSI C code 8 * 9 * authors: v1.0: Antoon Bosselaers 10 * v2.0: Vincent Rijmen 11 * v2.1: Vincent Rijmen 12 * v2.2: Vincent Rijmen 13 * v2.3: Paulo Barreto 14 * v2.4: Vincent Rijmen 15 * 16 * This code is placed in the public domain. 17 */ 18 19 #include <sys/param.h> 20 #include <sys/types.h> 21 #ifdef _KERNEL 22 #include <sys/systm.h> 23 #else 24 #include <string.h> 25 #endif 26 #include <crypto/rijndael/rijndael-alg-fst.h> 27 #include <crypto/rijndael/rijndael-api-fst.h> 28 #include <crypto/rijndael/rijndael_local.h> 29 30 #ifndef TRUE 31 #define TRUE 1 32 #endif 33 34 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { 35 word8 k[MAXKC][4]; 36 int i; 37 char *keyMat; 38 39 if (key == NULL) { 40 return BAD_KEY_INSTANCE; 41 } 42 43 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 44 key->direction = direction; 45 } else { 46 return BAD_KEY_DIR; 47 } 48 49 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 50 key->keyLen = keyLen; 51 } else { 52 return BAD_KEY_MAT; 53 } 54 55 if (keyMaterial != NULL) { 56 bcopy(keyMaterial, key->keyMaterial, keyLen/8); 57 } 58 59 key->ROUNDS = keyLen/32 + 6; 60 61 /* initialize key schedule: */ 62 keyMat = key->keyMaterial; 63 for (i = 0; i < key->keyLen/8; i++) { 64 k[i >> 2][i & 3] = (word8)keyMat[i]; 65 } 66 rijndaelKeySched(k, key->keySched, key->ROUNDS); 67 if (direction == DIR_DECRYPT) { 68 rijndaelKeyEncToDec(key->keySched, key->ROUNDS); 69 } 70 71 return TRUE; 72 } 73 74 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 75 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 76 cipher->mode = mode; 77 } else { 78 return BAD_CIPHER_MODE; 79 } 80 if (IV != NULL) { 81 bcopy(IV, cipher->IV, MAX_IV_SIZE); 82 } else { 83 bzero(cipher->IV, MAX_IV_SIZE); 84 } 85 return TRUE; 86 } 87 88 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 89 BYTE *input, int inputLen, BYTE *outBuffer) { 90 int i, k, numBlocks; 91 word8 block[16], iv[4][4]; 92 93 if (cipher == NULL || 94 key == NULL || 95 key->direction == DIR_DECRYPT) { 96 return BAD_CIPHER_STATE; 97 } 98 if (input == NULL || inputLen <= 0) { 99 return 0; /* nothing to do */ 100 } 101 102 numBlocks = inputLen/128; 103 104 switch (cipher->mode) { 105 case MODE_ECB: 106 for (i = numBlocks; i > 0; i--) { 107 rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); 108 input += 16; 109 outBuffer += 16; 110 } 111 break; 112 113 case MODE_CBC: 114 #if 1 /*STRICT_ALIGN*/ 115 bcopy(cipher->IV, block, 16); 116 bcopy(input, iv, 16); 117 ((word32*)block)[0] ^= ((word32*)iv)[0]; 118 ((word32*)block)[1] ^= ((word32*)iv)[1]; 119 ((word32*)block)[2] ^= ((word32*)iv)[2]; 120 ((word32*)block)[3] ^= ((word32*)iv)[3]; 121 #else 122 ((word32*)block)[0] = ((word32*)cipher->IV)[0] ^ ((word32*)input)[0]; 123 ((word32*)block)[1] = ((word32*)cipher->IV)[1] ^ ((word32*)input)[1]; 124 ((word32*)block)[2] = ((word32*)cipher->IV)[2] ^ ((word32*)input)[2]; 125 ((word32*)block)[3] = ((word32*)cipher->IV)[3] ^ ((word32*)input)[3]; 126 #endif 127 rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 128 input += 16; 129 for (i = numBlocks - 1; i > 0; i--) { 130 #if 1 /*STRICT_ALIGN*/ 131 bcopy(outBuffer, block, 16); 132 bcopy(input, iv, 16); 133 ((word32*)block)[0] ^= ((word32*)iv)[0]; 134 ((word32*)block)[1] ^= ((word32*)iv)[1]; 135 ((word32*)block)[2] ^= ((word32*)iv)[2]; 136 ((word32*)block)[3] ^= ((word32*)iv)[3]; 137 #else 138 ((word32*)block)[0] = ((word32*)outBuffer)[0] ^ ((word32*)input)[0]; 139 ((word32*)block)[1] = ((word32*)outBuffer)[1] ^ ((word32*)input)[1]; 140 ((word32*)block)[2] = ((word32*)outBuffer)[2] ^ ((word32*)input)[2]; 141 ((word32*)block)[3] = ((word32*)outBuffer)[3] ^ ((word32*)input)[3]; 142 #endif 143 outBuffer += 16; 144 rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 145 input += 16; 146 } 147 break; 148 149 case MODE_CFB1: 150 #if 1 /*STRICT_ALIGN*/ 151 bcopy(cipher->IV, iv, 16); 152 #else /* !STRICT_ALIGN */ 153 *((word32*)iv[0]) = *((word32*)(cipher->IV )); 154 *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 155 *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 156 *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 157 #endif /* ?STRICT_ALIGN */ 158 for (i = numBlocks; i > 0; i--) { 159 for (k = 0; k < 128; k++) { 160 *((word32*) block ) = *((word32*)iv[0]); 161 *((word32*)(block+ 4)) = *((word32*)iv[1]); 162 *((word32*)(block+ 8)) = *((word32*)iv[2]); 163 *((word32*)(block+12)) = *((word32*)iv[3]); 164 rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); 165 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 166 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 167 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 168 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 169 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 170 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 171 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 172 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 173 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 174 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 175 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 176 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 177 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 178 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 179 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 180 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 181 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 182 } 183 } 184 break; 185 186 default: 187 return BAD_CIPHER_STATE; 188 } 189 190 return 128*numBlocks; 191 } 192 193 /** 194 * Encrypt data partitioned in octets, using RFC 2040-like padding. 195 * 196 * @param input data to be encrypted (octet sequence) 197 * @param inputOctets input length in octets (not bits) 198 * @param outBuffer encrypted output data 199 * 200 * @return length in octets (not bits) of the encrypted output buffer. 201 */ 202 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 203 BYTE *input, int inputOctets, BYTE *outBuffer) { 204 int i, numBlocks, padLen; 205 word8 block[16], *iv, *cp; 206 207 if (cipher == NULL || 208 key == NULL || 209 key->direction == DIR_DECRYPT) { 210 return BAD_CIPHER_STATE; 211 } 212 if (input == NULL || inputOctets <= 0) { 213 return 0; /* nothing to do */ 214 } 215 216 numBlocks = inputOctets/16; 217 218 switch (cipher->mode) { 219 case MODE_ECB: 220 for (i = numBlocks; i > 0; i--) { 221 rijndaelEncrypt(input, outBuffer, key->keySched, key->ROUNDS); 222 input += 16; 223 outBuffer += 16; 224 } 225 padLen = 16 - (inputOctets - 16*numBlocks); 226 if (padLen > 0 && padLen <= 16) 227 return BAD_CIPHER_STATE; 228 bcopy(input, block, 16 - padLen); 229 for (cp = block + 16 - padLen; cp < block + 16; cp++) 230 *cp = padLen; 231 rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 232 break; 233 234 case MODE_CBC: 235 iv = cipher->IV; 236 for (i = numBlocks; i > 0; i--) { 237 ((word32*)block)[0] = ((word32*)input)[0] ^ ((word32*)iv)[0]; 238 ((word32*)block)[1] = ((word32*)input)[1] ^ ((word32*)iv)[1]; 239 ((word32*)block)[2] = ((word32*)input)[2] ^ ((word32*)iv)[2]; 240 ((word32*)block)[3] = ((word32*)input)[3] ^ ((word32*)iv)[3]; 241 rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 242 iv = outBuffer; 243 input += 16; 244 outBuffer += 16; 245 } 246 padLen = 16 - (inputOctets - 16*numBlocks); 247 if (padLen > 0 && padLen <= 16) 248 return BAD_CIPHER_STATE; 249 for (i = 0; i < 16 - padLen; i++) { 250 block[i] = input[i] ^ iv[i]; 251 } 252 for (i = 16 - padLen; i < 16; i++) { 253 block[i] = (BYTE)padLen ^ iv[i]; 254 } 255 rijndaelEncrypt(block, outBuffer, key->keySched, key->ROUNDS); 256 break; 257 258 default: 259 return BAD_CIPHER_STATE; 260 } 261 262 return 16*(numBlocks + 1); 263 } 264 265 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 266 BYTE *input, int inputLen, BYTE *outBuffer) { 267 int i, k, numBlocks; 268 word8 block[16], iv[4][4]; 269 270 if (cipher == NULL || 271 key == NULL || 272 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 273 return BAD_CIPHER_STATE; 274 } 275 if (input == NULL || inputLen <= 0) { 276 return 0; /* nothing to do */ 277 } 278 279 numBlocks = inputLen/128; 280 281 switch (cipher->mode) { 282 case MODE_ECB: 283 for (i = numBlocks; i > 0; i--) { 284 rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); 285 input += 16; 286 outBuffer += 16; 287 } 288 break; 289 290 case MODE_CBC: 291 #if 1 /*STRICT_ALIGN */ 292 bcopy(cipher->IV, iv, 16); 293 #else 294 *((word32*)iv[0]) = *((word32*)(cipher->IV )); 295 *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 296 *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 297 *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 298 #endif 299 for (i = numBlocks; i > 0; i--) { 300 rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 301 ((word32*)block)[0] ^= *((word32*)iv[0]); 302 ((word32*)block)[1] ^= *((word32*)iv[1]); 303 ((word32*)block)[2] ^= *((word32*)iv[2]); 304 ((word32*)block)[3] ^= *((word32*)iv[3]); 305 #if 1 /*STRICT_ALIGN*/ 306 bcopy(input, iv, 16); 307 bcopy(block, outBuffer, 16); 308 #else 309 *((word32*)iv[0]) = ((word32*)input)[0]; ((word32*)outBuffer)[0] = ((word32*)block)[0]; 310 *((word32*)iv[1]) = ((word32*)input)[1]; ((word32*)outBuffer)[1] = ((word32*)block)[1]; 311 *((word32*)iv[2]) = ((word32*)input)[2]; ((word32*)outBuffer)[2] = ((word32*)block)[2]; 312 *((word32*)iv[3]) = ((word32*)input)[3]; ((word32*)outBuffer)[3] = ((word32*)block)[3]; 313 #endif 314 input += 16; 315 outBuffer += 16; 316 } 317 break; 318 319 case MODE_CFB1: 320 #if 1 /*STRICT_ALIGN */ 321 bcopy(cipher->IV, iv, 16); 322 #else 323 *((word32*)iv[0]) = *((word32*)(cipher->IV)); 324 *((word32*)iv[1]) = *((word32*)(cipher->IV+ 4)); 325 *((word32*)iv[2]) = *((word32*)(cipher->IV+ 8)); 326 *((word32*)iv[3]) = *((word32*)(cipher->IV+12)); 327 #endif 328 for (i = numBlocks; i > 0; i--) { 329 for (k = 0; k < 128; k++) { 330 *((word32*) block ) = *((word32*)iv[0]); 331 *((word32*)(block+ 4)) = *((word32*)iv[1]); 332 *((word32*)(block+ 8)) = *((word32*)iv[2]); 333 *((word32*)(block+12)) = *((word32*)iv[3]); 334 rijndaelEncrypt(block, block, key->keySched, key->ROUNDS); 335 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 336 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 337 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 338 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 339 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 340 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 341 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 342 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 343 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 344 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 345 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 346 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 347 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 348 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 349 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 350 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 351 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 352 } 353 } 354 break; 355 356 default: 357 return BAD_CIPHER_STATE; 358 } 359 360 return 128*numBlocks; 361 } 362 363 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 364 BYTE *input, int inputOctets, BYTE *outBuffer) { 365 int i, numBlocks, padLen; 366 word8 block[16]; 367 word32 iv[4]; 368 369 if (cipher == NULL || 370 key == NULL || 371 key->direction == DIR_ENCRYPT) { 372 return BAD_CIPHER_STATE; 373 } 374 if (input == NULL || inputOctets <= 0) { 375 return 0; /* nothing to do */ 376 } 377 if (inputOctets % 16 != 0) { 378 return BAD_DATA; 379 } 380 381 numBlocks = inputOctets/16; 382 383 switch (cipher->mode) { 384 case MODE_ECB: 385 /* all blocks but last */ 386 for (i = numBlocks - 1; i > 0; i--) { 387 rijndaelDecrypt(input, outBuffer, key->keySched, key->ROUNDS); 388 input += 16; 389 outBuffer += 16; 390 } 391 /* last block */ 392 rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 393 padLen = block[15]; 394 if (padLen >= 16) { 395 return BAD_DATA; 396 } 397 for (i = 16 - padLen; i < 16; i++) { 398 if (block[i] != padLen) { 399 return BAD_DATA; 400 } 401 } 402 bcopy(block, outBuffer, 16 - padLen); 403 break; 404 405 case MODE_CBC: 406 bcopy(cipher->IV, iv, 16); 407 /* all blocks but last */ 408 for (i = numBlocks - 1; i > 0; i--) { 409 rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 410 ((word32*)block)[0] ^= iv[0]; 411 ((word32*)block)[1] ^= iv[1]; 412 ((word32*)block)[2] ^= iv[2]; 413 ((word32*)block)[3] ^= iv[3]; 414 bcopy(input, iv, 16); 415 bcopy(block, outBuffer, 16); 416 input += 16; 417 outBuffer += 16; 418 } 419 /* last block */ 420 rijndaelDecrypt(input, block, key->keySched, key->ROUNDS); 421 ((word32*)block)[0] ^= iv[0]; 422 ((word32*)block)[1] ^= iv[1]; 423 ((word32*)block)[2] ^= iv[2]; 424 ((word32*)block)[3] ^= iv[3]; 425 padLen = block[15]; 426 if (padLen <= 0 || padLen > 16) { 427 return BAD_DATA; 428 } 429 for (i = 16 - padLen; i < 16; i++) { 430 if (block[i] != padLen) { 431 return BAD_DATA; 432 } 433 } 434 bcopy(block, outBuffer, 16 - padLen); 435 break; 436 437 default: 438 return BAD_CIPHER_STATE; 439 } 440 441 return 16*numBlocks - padLen; 442 } 443 444 #ifdef INTERMEDIATE_VALUE_KAT 445 /** 446 * cipherUpdateRounds: 447 * 448 * Encrypts/Decrypts exactly one full block a specified number of rounds. 449 * Only used in the Intermediate Value Known Answer Test. 450 * 451 * Returns: 452 * TRUE - on success 453 * BAD_CIPHER_STATE - cipher in bad state (e.g., not initialized) 454 */ 455 int rijndael_cipherUpdateRounds(cipherInstance *cipher, keyInstance *key, 456 BYTE *input, int inputLen, BYTE *outBuffer, int rounds) { 457 int j; 458 word8 block[4][4]; 459 460 if (cipher == NULL || key == NULL) { 461 return BAD_CIPHER_STATE; 462 } 463 464 for (j = 3; j >= 0; j--) { 465 /* parse input stream into rectangular array */ 466 *((word32*)block[j]) = *((word32*)(input+4*j)); 467 } 468 469 switch (key->direction) { 470 case DIR_ENCRYPT: 471 rijndaelEncryptRound(block, key->keySched, key->ROUNDS, rounds); 472 break; 473 474 case DIR_DECRYPT: 475 rijndaelDecryptRound(block, key->keySched, key->ROUNDS, rounds); 476 break; 477 478 default: 479 return BAD_KEY_DIR; 480 } 481 482 for (j = 3; j >= 0; j--) { 483 /* parse rectangular array into output ciphertext bytes */ 484 *((word32*)(outBuffer+4*j)) = *((word32*)block[j]); 485 } 486 487 return TRUE; 488 } 489 #endif /* INTERMEDIATE_VALUE_KAT */ 490