1 /* $FreeBSD: src/sys/crypto/rijndael/rijndael-api-fst.c,v 1.12 2005/03/11 16:26:10 ume Exp $ */ 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 #ifdef _KERNEL 21 #include <sys/systm.h> 22 #else 23 #include <string.h> 24 #endif 25 26 #include <crypto/rijndael/rijndael_local.h> 27 #include <crypto/rijndael/rijndael-api-fst.h> 28 29 #ifndef TRUE 30 #define TRUE 1 31 #endif 32 33 typedef u_int8_t BYTE; 34 35 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, char *keyMaterial) { 36 u_int8_t cipherKey[RIJNDAEL_MAXKB]; 37 38 if (key == NULL) { 39 return BAD_KEY_INSTANCE; 40 } 41 42 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 43 key->direction = direction; 44 } else { 45 return BAD_KEY_DIR; 46 } 47 48 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 49 key->keyLen = keyLen; 50 } else { 51 return BAD_KEY_MAT; 52 } 53 54 if (keyMaterial != NULL) { 55 memcpy(key->keyMaterial, keyMaterial, keyLen/8); 56 } 57 58 /* initialize key schedule: */ 59 memcpy(cipherKey, key->keyMaterial, keyLen/8); 60 if (direction == DIR_ENCRYPT) { 61 key->Nr = rijndaelKeySetupEnc(key->rk, cipherKey, keyLen); 62 } else { 63 key->Nr = rijndaelKeySetupDec(key->rk, cipherKey, keyLen); 64 } 65 rijndaelKeySetupEnc(key->ek, cipherKey, keyLen); 66 return TRUE; 67 } 68 69 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 70 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 71 cipher->mode = mode; 72 } else { 73 return BAD_CIPHER_MODE; 74 } 75 if (IV != NULL) { 76 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); 77 } else { 78 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); 79 } 80 return TRUE; 81 } 82 83 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 84 BYTE *input, int inputLen, BYTE *outBuffer) { 85 int i, k, numBlocks; 86 u_int8_t block[16], iv[4][4]; 87 88 if (cipher == NULL || 89 key == NULL || 90 key->direction == DIR_DECRYPT) { 91 return BAD_CIPHER_STATE; 92 } 93 if (input == NULL || inputLen <= 0) { 94 return 0; /* nothing to do */ 95 } 96 97 numBlocks = inputLen/128; 98 99 switch (cipher->mode) { 100 case MODE_ECB: 101 for (i = numBlocks; i > 0; i--) { 102 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 103 input += 16; 104 outBuffer += 16; 105 } 106 break; 107 108 case MODE_CBC: 109 #if 1 /*STRICT_ALIGN*/ 110 memcpy(block, cipher->IV, 16); 111 memcpy(iv, input, 16); 112 ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0]; 113 ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1]; 114 ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2]; 115 ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3]; 116 #else 117 ((u_int32_t*)block)[0] = ((u_int32_t*)cipher->IV)[0] ^ ((u_int32_t*)input)[0]; 118 ((u_int32_t*)block)[1] = ((u_int32_t*)cipher->IV)[1] ^ ((u_int32_t*)input)[1]; 119 ((u_int32_t*)block)[2] = ((u_int32_t*)cipher->IV)[2] ^ ((u_int32_t*)input)[2]; 120 ((u_int32_t*)block)[3] = ((u_int32_t*)cipher->IV)[3] ^ ((u_int32_t*)input)[3]; 121 #endif 122 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 123 input += 16; 124 for (i = numBlocks - 1; i > 0; i--) { 125 #if 1 /*STRICT_ALIGN*/ 126 memcpy(block, outBuffer, 16); 127 memcpy(iv, input, 16); 128 ((u_int32_t*)block)[0] ^= ((u_int32_t*)iv)[0]; 129 ((u_int32_t*)block)[1] ^= ((u_int32_t*)iv)[1]; 130 ((u_int32_t*)block)[2] ^= ((u_int32_t*)iv)[2]; 131 ((u_int32_t*)block)[3] ^= ((u_int32_t*)iv)[3]; 132 #else 133 ((u_int32_t*)block)[0] = ((u_int32_t*)outBuffer)[0] ^ ((u_int32_t*)input)[0]; 134 ((u_int32_t*)block)[1] = ((u_int32_t*)outBuffer)[1] ^ ((u_int32_t*)input)[1]; 135 ((u_int32_t*)block)[2] = ((u_int32_t*)outBuffer)[2] ^ ((u_int32_t*)input)[2]; 136 ((u_int32_t*)block)[3] = ((u_int32_t*)outBuffer)[3] ^ ((u_int32_t*)input)[3]; 137 #endif 138 outBuffer += 16; 139 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 140 input += 16; 141 } 142 break; 143 144 case MODE_CFB1: 145 #if 1 /*STRICT_ALIGN*/ 146 memcpy(iv, cipher->IV, 16); 147 #else /* !STRICT_ALIGN */ 148 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV )); 149 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); 150 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); 151 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); 152 #endif /* ?STRICT_ALIGN */ 153 for (i = numBlocks; i > 0; i--) { 154 for (k = 0; k < 128; k++) { 155 *((u_int32_t*) block ) = *((u_int32_t*)iv[0]); 156 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]); 157 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]); 158 *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]); 159 rijndaelEncrypt(key->ek, key->Nr, block, 160 block); 161 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 162 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 163 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 164 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 165 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 166 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 167 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 168 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 169 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 170 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 171 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 172 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 173 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 174 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 175 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 176 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 177 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 178 } 179 } 180 break; 181 182 default: 183 return BAD_CIPHER_STATE; 184 } 185 186 return 128*numBlocks; 187 } 188 189 /** 190 * Encrypt data partitioned in octets, using RFC 2040-like padding. 191 * 192 * @param input data to be encrypted (octet sequence) 193 * @param inputOctets input length in octets (not bits) 194 * @param outBuffer encrypted output data 195 * 196 * @return length in octets (not bits) of the encrypted output buffer. 197 */ 198 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 199 BYTE *input, int inputOctets, BYTE *outBuffer) { 200 int i, numBlocks, padLen; 201 u_int8_t block[16], *iv, *cp; 202 203 if (cipher == NULL || 204 key == NULL || 205 key->direction == DIR_DECRYPT) { 206 return BAD_CIPHER_STATE; 207 } 208 if (input == NULL || inputOctets <= 0) { 209 return 0; /* nothing to do */ 210 } 211 212 numBlocks = inputOctets/16; 213 214 switch (cipher->mode) { 215 case MODE_ECB: 216 for (i = numBlocks; i > 0; i--) { 217 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 218 input += 16; 219 outBuffer += 16; 220 } 221 padLen = 16 - (inputOctets - 16*numBlocks); 222 if (padLen <= 0 || padLen > 16) 223 return BAD_CIPHER_STATE; 224 memcpy(block, input, 16 - padLen); 225 for (cp = block + 16 - padLen; cp < block + 16; cp++) 226 *cp = padLen; 227 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 228 break; 229 230 case MODE_CBC: 231 iv = cipher->IV; 232 for (i = numBlocks; i > 0; i--) { 233 ((u_int32_t*)block)[0] = ((u_int32_t*)input)[0] ^ ((u_int32_t*)iv)[0]; 234 ((u_int32_t*)block)[1] = ((u_int32_t*)input)[1] ^ ((u_int32_t*)iv)[1]; 235 ((u_int32_t*)block)[2] = ((u_int32_t*)input)[2] ^ ((u_int32_t*)iv)[2]; 236 ((u_int32_t*)block)[3] = ((u_int32_t*)input)[3] ^ ((u_int32_t*)iv)[3]; 237 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 238 iv = outBuffer; 239 input += 16; 240 outBuffer += 16; 241 } 242 padLen = 16 - (inputOctets - 16*numBlocks); 243 if (padLen <= 0 || padLen > 16) 244 return BAD_CIPHER_STATE; 245 for (i = 0; i < 16 - padLen; i++) { 246 block[i] = input[i] ^ iv[i]; 247 } 248 for (i = 16 - padLen; i < 16; i++) { 249 block[i] = (BYTE)padLen ^ iv[i]; 250 } 251 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 252 break; 253 254 default: 255 return BAD_CIPHER_STATE; 256 } 257 258 return 16*(numBlocks + 1); 259 } 260 261 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 262 BYTE *input, int inputLen, BYTE *outBuffer) { 263 int i, k, numBlocks; 264 u_int8_t block[16], iv[4][4]; 265 266 if (cipher == NULL || 267 key == NULL || 268 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 269 return BAD_CIPHER_STATE; 270 } 271 if (input == NULL || inputLen <= 0) { 272 return 0; /* nothing to do */ 273 } 274 275 numBlocks = inputLen/128; 276 277 switch (cipher->mode) { 278 case MODE_ECB: 279 for (i = numBlocks; i > 0; i--) { 280 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 281 input += 16; 282 outBuffer += 16; 283 } 284 break; 285 286 case MODE_CBC: 287 #if 1 /*STRICT_ALIGN */ 288 memcpy(iv, cipher->IV, 16); 289 #else 290 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV )); 291 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); 292 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); 293 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); 294 #endif 295 for (i = numBlocks; i > 0; i--) { 296 rijndaelDecrypt(key->rk, key->Nr, input, block); 297 ((u_int32_t*)block)[0] ^= *((u_int32_t*)iv[0]); 298 ((u_int32_t*)block)[1] ^= *((u_int32_t*)iv[1]); 299 ((u_int32_t*)block)[2] ^= *((u_int32_t*)iv[2]); 300 ((u_int32_t*)block)[3] ^= *((u_int32_t*)iv[3]); 301 #if 1 /*STRICT_ALIGN*/ 302 memcpy(iv, input, 16); 303 memcpy(outBuffer, block, 16); 304 #else 305 *((u_int32_t*)iv[0]) = ((u_int32_t*)input)[0]; ((u_int32_t*)outBuffer)[0] = ((u_int32_t*)block)[0]; 306 *((u_int32_t*)iv[1]) = ((u_int32_t*)input)[1]; ((u_int32_t*)outBuffer)[1] = ((u_int32_t*)block)[1]; 307 *((u_int32_t*)iv[2]) = ((u_int32_t*)input)[2]; ((u_int32_t*)outBuffer)[2] = ((u_int32_t*)block)[2]; 308 *((u_int32_t*)iv[3]) = ((u_int32_t*)input)[3]; ((u_int32_t*)outBuffer)[3] = ((u_int32_t*)block)[3]; 309 #endif 310 input += 16; 311 outBuffer += 16; 312 } 313 break; 314 315 case MODE_CFB1: 316 #if 1 /*STRICT_ALIGN */ 317 memcpy(iv, cipher->IV, 16); 318 #else 319 *((u_int32_t*)iv[0]) = *((u_int32_t*)(cipher->IV)); 320 *((u_int32_t*)iv[1]) = *((u_int32_t*)(cipher->IV+ 4)); 321 *((u_int32_t*)iv[2]) = *((u_int32_t*)(cipher->IV+ 8)); 322 *((u_int32_t*)iv[3]) = *((u_int32_t*)(cipher->IV+12)); 323 #endif 324 for (i = numBlocks; i > 0; i--) { 325 for (k = 0; k < 128; k++) { 326 *((u_int32_t*) block ) = *((u_int32_t*)iv[0]); 327 *((u_int32_t*)(block+ 4)) = *((u_int32_t*)iv[1]); 328 *((u_int32_t*)(block+ 8)) = *((u_int32_t*)iv[2]); 329 *((u_int32_t*)(block+12)) = *((u_int32_t*)iv[3]); 330 rijndaelEncrypt(key->ek, key->Nr, block, 331 block); 332 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 333 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 334 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 335 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 336 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 337 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 338 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 339 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 340 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 341 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 342 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 343 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 344 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 345 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 346 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 347 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 348 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 349 } 350 } 351 break; 352 353 default: 354 return BAD_CIPHER_STATE; 355 } 356 357 return 128*numBlocks; 358 } 359 360 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 361 BYTE *input, int inputOctets, BYTE *outBuffer) { 362 int i, numBlocks, padLen; 363 u_int8_t block[16]; 364 u_int32_t iv[4]; 365 366 if (cipher == NULL || 367 key == NULL || 368 key->direction == DIR_ENCRYPT) { 369 return BAD_CIPHER_STATE; 370 } 371 if (input == NULL || inputOctets <= 0) { 372 return 0; /* nothing to do */ 373 } 374 if (inputOctets % 16 != 0) { 375 return BAD_DATA; 376 } 377 378 numBlocks = inputOctets/16; 379 380 switch (cipher->mode) { 381 case MODE_ECB: 382 /* all blocks but last */ 383 for (i = numBlocks - 1; i > 0; i--) { 384 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 385 input += 16; 386 outBuffer += 16; 387 } 388 /* last block */ 389 rijndaelDecrypt(key->rk, key->Nr, input, block); 390 padLen = block[15]; 391 if (padLen >= 16) { 392 return BAD_DATA; 393 } 394 for (i = 16 - padLen; i < 16; i++) { 395 if (block[i] != padLen) { 396 return BAD_DATA; 397 } 398 } 399 memcpy(outBuffer, block, 16 - padLen); 400 break; 401 402 case MODE_CBC: 403 memcpy(iv, cipher->IV, 16); 404 /* all blocks but last */ 405 for (i = numBlocks - 1; i > 0; i--) { 406 rijndaelDecrypt(key->rk, key->Nr, input, block); 407 ((u_int32_t*)block)[0] ^= iv[0]; 408 ((u_int32_t*)block)[1] ^= iv[1]; 409 ((u_int32_t*)block)[2] ^= iv[2]; 410 ((u_int32_t*)block)[3] ^= iv[3]; 411 memcpy(iv, input, 16); 412 memcpy(outBuffer, block, 16); 413 input += 16; 414 outBuffer += 16; 415 } 416 /* last block */ 417 rijndaelDecrypt(key->rk, key->Nr, input, block); 418 ((u_int32_t*)block)[0] ^= iv[0]; 419 ((u_int32_t*)block)[1] ^= iv[1]; 420 ((u_int32_t*)block)[2] ^= iv[2]; 421 ((u_int32_t*)block)[3] ^= iv[3]; 422 padLen = block[15]; 423 if (padLen <= 0 || padLen > 16) { 424 return BAD_DATA; 425 } 426 for (i = 16 - padLen; i < 16; i++) { 427 if (block[i] != padLen) { 428 return BAD_DATA; 429 } 430 } 431 memcpy(outBuffer, block, 16 - padLen); 432 break; 433 434 default: 435 return BAD_CIPHER_STATE; 436 } 437 438 return 16*numBlocks - padLen; 439 } 440