1 /* $KAME: rijndael-api-fst.c,v 1.10 2001/05/27 09:34:18 itojun Exp $ */ 2 3 /* 4 * rijndael-api-fst.c v2.3 April '2000 5 * 6 * Optimised ANSI C code 7 * 8 * authors: v1.0: Antoon Bosselaers 9 * v2.0: Vincent Rijmen 10 * v2.1: Vincent Rijmen 11 * v2.2: Vincent Rijmen 12 * v2.3: Paulo Barreto 13 * v2.4: Vincent Rijmen 14 * 15 * This code is placed in the public domain. 16 */ 17 18 #include <sys/param.h> 19 #ifdef _KERNEL 20 #include <sys/systm.h> 21 #else 22 #include <string.h> 23 #endif 24 25 #include <crypto/rijndael/rijndael_local.h> 26 #include <crypto/rijndael/rijndael-api-fst.h> 27 28 #ifndef TRUE 29 #define TRUE 1 30 #endif 31 32 typedef uint8_t BYTE; 33 34 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, 35 const char *keyMaterial) { 36 37 if (key == NULL) { 38 return BAD_KEY_INSTANCE; 39 } 40 41 if ((direction == DIR_ENCRYPT) || (direction == DIR_DECRYPT)) { 42 key->direction = direction; 43 } else { 44 return BAD_KEY_DIR; 45 } 46 47 if ((keyLen == 128) || (keyLen == 192) || (keyLen == 256)) { 48 key->keyLen = keyLen; 49 } else { 50 return BAD_KEY_MAT; 51 } 52 53 if (keyMaterial != NULL) { 54 memcpy(key->keyMaterial, keyMaterial, keyLen/8); 55 } 56 57 /* initialize key schedule: */ 58 if (direction == DIR_ENCRYPT) { 59 key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen); 60 } else { 61 key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen); 62 } 63 rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen); 64 return TRUE; 65 } 66 67 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 68 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 69 cipher->mode = mode; 70 } else { 71 return BAD_CIPHER_MODE; 72 } 73 if (IV != NULL) { 74 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); 75 } else { 76 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); 77 } 78 return TRUE; 79 } 80 81 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 82 const BYTE *input, int inputLen, BYTE *outBuffer) { 83 int i, k, numBlocks; 84 uint8_t block[16], iv[4][4]; 85 86 if (cipher == NULL || 87 key == NULL || 88 key->direction == DIR_DECRYPT) { 89 return BAD_CIPHER_STATE; 90 } 91 if (input == NULL || inputLen <= 0) { 92 return 0; /* nothing to do */ 93 } 94 95 numBlocks = inputLen/128; 96 97 switch (cipher->mode) { 98 case MODE_ECB: 99 for (i = numBlocks; i > 0; i--) { 100 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 101 input += 16; 102 outBuffer += 16; 103 } 104 break; 105 106 case MODE_CBC: 107 #if 1 /*STRICT_ALIGN*/ 108 memcpy(block, cipher->IV, 16); 109 memcpy(iv, input, 16); 110 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 111 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 112 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 113 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 114 #else 115 ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0]; 116 ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1]; 117 ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2]; 118 ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3]; 119 #endif 120 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 121 input += 16; 122 for (i = numBlocks - 1; i > 0; i--) { 123 #if 1 /*STRICT_ALIGN*/ 124 memcpy(block, outBuffer, 16); 125 memcpy(iv, input, 16); 126 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 127 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 128 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 129 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 130 #else 131 ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0]; 132 ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1]; 133 ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2]; 134 ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3]; 135 #endif 136 outBuffer += 16; 137 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 138 input += 16; 139 } 140 break; 141 142 case MODE_CFB1: 143 #if 1 /*STRICT_ALIGN*/ 144 memcpy(iv, cipher->IV, 16); 145 #else /* !STRICT_ALIGN */ 146 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 147 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 148 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 149 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 150 #endif /* ?STRICT_ALIGN */ 151 for (i = numBlocks; i > 0; i--) { 152 for (k = 0; k < 128; k++) { 153 *((uint32_t*) block ) = *((uint32_t*)iv[0]); 154 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 155 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 156 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 157 rijndaelEncrypt(key->ek, key->Nr, block, 158 block); 159 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 160 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 161 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 162 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 163 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 164 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 165 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 166 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 167 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 168 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 169 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 170 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 171 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 172 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 173 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 174 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 175 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 176 } 177 } 178 break; 179 180 default: 181 return BAD_CIPHER_STATE; 182 } 183 184 explicit_bzero(block, sizeof(block)); 185 return 128*numBlocks; 186 } 187 188 /** 189 * Encrypt data partitioned in octets, using RFC 2040-like padding. 190 * 191 * @param input data to be encrypted (octet sequence) 192 * @param inputOctets input length in octets (not bits) 193 * @param outBuffer encrypted output data 194 * 195 * @return length in octets (not bits) of the encrypted output buffer. 196 */ 197 int rijndael_padEncrypt(cipherInstance *cipher, keyInstance *key, 198 const BYTE *input, int inputOctets, BYTE *outBuffer) { 199 int i, numBlocks, padLen; 200 uint8_t block[16], *iv, *cp; 201 202 if (cipher == NULL || 203 key == NULL || 204 key->direction == DIR_DECRYPT) { 205 return BAD_CIPHER_STATE; 206 } 207 if (input == NULL || inputOctets <= 0) { 208 return 0; /* nothing to do */ 209 } 210 211 numBlocks = inputOctets/16; 212 213 switch (cipher->mode) { 214 case MODE_ECB: 215 for (i = numBlocks; i > 0; i--) { 216 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 217 input += 16; 218 outBuffer += 16; 219 } 220 padLen = 16 - (inputOctets - 16*numBlocks); 221 if (padLen <= 0 || padLen > 16) 222 return BAD_CIPHER_STATE; 223 memcpy(block, input, 16 - padLen); 224 for (cp = block + 16 - padLen; cp < block + 16; cp++) 225 *cp = padLen; 226 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 227 break; 228 229 case MODE_CBC: 230 iv = cipher->IV; 231 for (i = numBlocks; i > 0; i--) { 232 ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0]; 233 ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1]; 234 ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2]; 235 ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_t*)iv)[3]; 236 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 237 iv = outBuffer; 238 input += 16; 239 outBuffer += 16; 240 } 241 padLen = 16 - (inputOctets - 16*numBlocks); 242 if (padLen <= 0 || padLen > 16) 243 return BAD_CIPHER_STATE; 244 for (i = 0; i < 16 - padLen; i++) { 245 block[i] = input[i] ^ iv[i]; 246 } 247 for (i = 16 - padLen; i < 16; i++) { 248 block[i] = (BYTE)padLen ^ iv[i]; 249 } 250 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 251 break; 252 253 default: 254 return BAD_CIPHER_STATE; 255 } 256 257 explicit_bzero(block, sizeof(block)); 258 return 16*(numBlocks + 1); 259 } 260 261 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 262 const BYTE *input, int inputLen, BYTE *outBuffer) { 263 int i, k, numBlocks; 264 uint8_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 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 291 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 292 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 293 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 294 #endif 295 for (i = numBlocks; i > 0; i--) { 296 rijndaelDecrypt(key->rk, key->Nr, input, block); 297 ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]); 298 ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]); 299 ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]); 300 ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]); 301 #if 1 /*STRICT_ALIGN*/ 302 memcpy(iv, input, 16); 303 memcpy(outBuffer, block, 16); 304 #else 305 *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0]; 306 *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1]; 307 *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2]; 308 *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_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 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV)); 320 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 321 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 322 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 323 #endif 324 for (i = numBlocks; i > 0; i--) { 325 for (k = 0; k < 128; k++) { 326 *((uint32_t*) block ) = *((uint32_t*)iv[0]); 327 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 328 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 329 *((uint32_t*)(block+12)) = *((uint32_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 explicit_bzero(block, sizeof(block)); 358 return 128*numBlocks; 359 } 360 361 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 362 const BYTE *input, int inputOctets, BYTE *outBuffer) { 363 int i, numBlocks, padLen, rval; 364 uint8_t block[16]; 365 uint32_t iv[4]; 366 367 if (cipher == NULL || 368 key == NULL || 369 key->direction == DIR_ENCRYPT) { 370 return BAD_CIPHER_STATE; 371 } 372 if (input == NULL || inputOctets <= 0) { 373 return 0; /* nothing to do */ 374 } 375 if (inputOctets % 16 != 0) { 376 return BAD_DATA; 377 } 378 379 numBlocks = inputOctets/16; 380 381 switch (cipher->mode) { 382 case MODE_ECB: 383 /* all blocks but last */ 384 for (i = numBlocks - 1; i > 0; i--) { 385 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 386 input += 16; 387 outBuffer += 16; 388 } 389 /* last block */ 390 rijndaelDecrypt(key->rk, key->Nr, input, block); 391 padLen = block[15]; 392 if (padLen >= 16) { 393 rval = BAD_DATA; 394 goto out; 395 } 396 for (i = 16 - padLen; i < 16; i++) { 397 if (block[i] != padLen) { 398 rval = BAD_DATA; 399 goto out; 400 } 401 } 402 memcpy(outBuffer, block, 16 - padLen); 403 break; 404 405 case MODE_CBC: 406 memcpy(iv, cipher->IV, 16); 407 /* all blocks but last */ 408 for (i = numBlocks - 1; i > 0; i--) { 409 rijndaelDecrypt(key->rk, key->Nr, input, block); 410 ((uint32_t*)block)[0] ^= iv[0]; 411 ((uint32_t*)block)[1] ^= iv[1]; 412 ((uint32_t*)block)[2] ^= iv[2]; 413 ((uint32_t*)block)[3] ^= iv[3]; 414 memcpy(iv, input, 16); 415 memcpy(outBuffer, block, 16); 416 input += 16; 417 outBuffer += 16; 418 } 419 /* last block */ 420 rijndaelDecrypt(key->rk, key->Nr, input, block); 421 ((uint32_t*)block)[0] ^= iv[0]; 422 ((uint32_t*)block)[1] ^= iv[1]; 423 ((uint32_t*)block)[2] ^= iv[2]; 424 ((uint32_t*)block)[3] ^= iv[3]; 425 padLen = block[15]; 426 if (padLen <= 0 || padLen > 16) { 427 rval = BAD_DATA; 428 goto out; 429 } 430 for (i = 16 - padLen; i < 16; i++) { 431 if (block[i] != padLen) { 432 rval = BAD_DATA; 433 goto out; 434 } 435 } 436 memcpy(outBuffer, block, 16 - padLen); 437 break; 438 439 default: 440 return BAD_CIPHER_STATE; 441 } 442 443 rval = 16*numBlocks - padLen; 444 445 out: 446 explicit_bzero(block, sizeof(block)); 447 return rval; 448 } 449