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/cdefs.h> 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 uint8_t BYTE; 34 35 int rijndael_makeKey(keyInstance *key, BYTE direction, int keyLen, 36 const char *keyMaterial) { 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 if (direction == DIR_ENCRYPT) { 60 key->Nr = rijndaelKeySetupEnc(key->rk, key->keyMaterial, keyLen); 61 } else { 62 key->Nr = rijndaelKeySetupDec(key->rk, key->keyMaterial, keyLen); 63 } 64 rijndaelKeySetupEnc(key->ek, key->keyMaterial, keyLen); 65 return TRUE; 66 } 67 68 int rijndael_cipherInit(cipherInstance *cipher, BYTE mode, char *IV) { 69 if ((mode == MODE_ECB) || (mode == MODE_CBC) || (mode == MODE_CFB1)) { 70 cipher->mode = mode; 71 } else { 72 return BAD_CIPHER_MODE; 73 } 74 if (IV != NULL) { 75 memcpy(cipher->IV, IV, RIJNDAEL_MAX_IV_SIZE); 76 } else { 77 memset(cipher->IV, 0, RIJNDAEL_MAX_IV_SIZE); 78 } 79 return TRUE; 80 } 81 82 int rijndael_blockEncrypt(cipherInstance *cipher, keyInstance *key, 83 const BYTE *input, int inputLen, BYTE *outBuffer) { 84 int i, k, numBlocks; 85 uint8_t block[16], iv[4][4]; 86 87 if (cipher == NULL || 88 key == NULL || 89 key->direction == DIR_DECRYPT) { 90 return BAD_CIPHER_STATE; 91 } 92 if (input == NULL || inputLen <= 0) { 93 return 0; /* nothing to do */ 94 } 95 96 numBlocks = inputLen/128; 97 98 switch (cipher->mode) { 99 case MODE_ECB: 100 for (i = numBlocks; i > 0; i--) { 101 rijndaelEncrypt(key->rk, key->Nr, input, outBuffer); 102 input += 16; 103 outBuffer += 16; 104 } 105 break; 106 107 case MODE_CBC: 108 #if 1 /*STRICT_ALIGN*/ 109 memcpy(block, cipher->IV, 16); 110 memcpy(iv, input, 16); 111 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 112 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 113 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 114 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 115 #else 116 ((uint32_t*)block)[0] = ((uint32_t*)cipher->IV)[0] ^ ((uint32_t*)input)[0]; 117 ((uint32_t*)block)[1] = ((uint32_t*)cipher->IV)[1] ^ ((uint32_t*)input)[1]; 118 ((uint32_t*)block)[2] = ((uint32_t*)cipher->IV)[2] ^ ((uint32_t*)input)[2]; 119 ((uint32_t*)block)[3] = ((uint32_t*)cipher->IV)[3] ^ ((uint32_t*)input)[3]; 120 #endif 121 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 122 input += 16; 123 for (i = numBlocks - 1; i > 0; i--) { 124 #if 1 /*STRICT_ALIGN*/ 125 memcpy(block, outBuffer, 16); 126 memcpy(iv, input, 16); 127 ((uint32_t*)block)[0] ^= ((uint32_t*)iv)[0]; 128 ((uint32_t*)block)[1] ^= ((uint32_t*)iv)[1]; 129 ((uint32_t*)block)[2] ^= ((uint32_t*)iv)[2]; 130 ((uint32_t*)block)[3] ^= ((uint32_t*)iv)[3]; 131 #else 132 ((uint32_t*)block)[0] = ((uint32_t*)outBuffer)[0] ^ ((uint32_t*)input)[0]; 133 ((uint32_t*)block)[1] = ((uint32_t*)outBuffer)[1] ^ ((uint32_t*)input)[1]; 134 ((uint32_t*)block)[2] = ((uint32_t*)outBuffer)[2] ^ ((uint32_t*)input)[2]; 135 ((uint32_t*)block)[3] = ((uint32_t*)outBuffer)[3] ^ ((uint32_t*)input)[3]; 136 #endif 137 outBuffer += 16; 138 rijndaelEncrypt(key->rk, key->Nr, block, outBuffer); 139 input += 16; 140 } 141 break; 142 143 case MODE_CFB1: 144 #if 1 /*STRICT_ALIGN*/ 145 memcpy(iv, cipher->IV, 16); 146 #else /* !STRICT_ALIGN */ 147 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 148 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 149 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 150 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 151 #endif /* ?STRICT_ALIGN */ 152 for (i = numBlocks; i > 0; i--) { 153 for (k = 0; k < 128; k++) { 154 *((uint32_t*) block ) = *((uint32_t*)iv[0]); 155 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 156 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 157 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 158 rijndaelEncrypt(key->ek, key->Nr, block, 159 block); 160 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 161 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 162 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 163 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 164 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 165 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 166 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 167 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 168 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 169 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 170 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 171 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 172 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 173 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 174 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 175 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 176 iv[3][3] = (iv[3][3] << 1) | ((outBuffer[k/8] >> (7-(k&7))) & 1); 177 } 178 } 179 break; 180 181 default: 182 return BAD_CIPHER_STATE; 183 } 184 185 explicit_bzero(block, sizeof(block)); 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 const BYTE *input, int inputOctets, BYTE *outBuffer) { 200 int i, numBlocks, padLen; 201 uint8_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 ((uint32_t*)block)[0] = ((const uint32_t*)input)[0] ^ ((uint32_t*)iv)[0]; 234 ((uint32_t*)block)[1] = ((const uint32_t*)input)[1] ^ ((uint32_t*)iv)[1]; 235 ((uint32_t*)block)[2] = ((const uint32_t*)input)[2] ^ ((uint32_t*)iv)[2]; 236 ((uint32_t*)block)[3] = ((const uint32_t*)input)[3] ^ ((uint32_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 explicit_bzero(block, sizeof(block)); 259 return 16*(numBlocks + 1); 260 } 261 262 int rijndael_blockDecrypt(cipherInstance *cipher, keyInstance *key, 263 const BYTE *input, int inputLen, BYTE *outBuffer) { 264 int i, k, numBlocks; 265 uint8_t block[16], iv[4][4]; 266 267 if (cipher == NULL || 268 key == NULL || 269 (cipher->mode != MODE_CFB1 && key->direction == DIR_ENCRYPT)) { 270 return BAD_CIPHER_STATE; 271 } 272 if (input == NULL || inputLen <= 0) { 273 return 0; /* nothing to do */ 274 } 275 276 numBlocks = inputLen/128; 277 278 switch (cipher->mode) { 279 case MODE_ECB: 280 for (i = numBlocks; i > 0; i--) { 281 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 282 input += 16; 283 outBuffer += 16; 284 } 285 break; 286 287 case MODE_CBC: 288 #if 1 /*STRICT_ALIGN */ 289 memcpy(iv, cipher->IV, 16); 290 #else 291 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV )); 292 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 293 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 294 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 295 #endif 296 for (i = numBlocks; i > 0; i--) { 297 rijndaelDecrypt(key->rk, key->Nr, input, block); 298 ((uint32_t*)block)[0] ^= *((uint32_t*)iv[0]); 299 ((uint32_t*)block)[1] ^= *((uint32_t*)iv[1]); 300 ((uint32_t*)block)[2] ^= *((uint32_t*)iv[2]); 301 ((uint32_t*)block)[3] ^= *((uint32_t*)iv[3]); 302 #if 1 /*STRICT_ALIGN*/ 303 memcpy(iv, input, 16); 304 memcpy(outBuffer, block, 16); 305 #else 306 *((uint32_t*)iv[0]) = ((uint32_t*)input)[0]; ((uint32_t*)outBuffer)[0] = ((uint32_t*)block)[0]; 307 *((uint32_t*)iv[1]) = ((uint32_t*)input)[1]; ((uint32_t*)outBuffer)[1] = ((uint32_t*)block)[1]; 308 *((uint32_t*)iv[2]) = ((uint32_t*)input)[2]; ((uint32_t*)outBuffer)[2] = ((uint32_t*)block)[2]; 309 *((uint32_t*)iv[3]) = ((uint32_t*)input)[3]; ((uint32_t*)outBuffer)[3] = ((uint32_t*)block)[3]; 310 #endif 311 input += 16; 312 outBuffer += 16; 313 } 314 break; 315 316 case MODE_CFB1: 317 #if 1 /*STRICT_ALIGN */ 318 memcpy(iv, cipher->IV, 16); 319 #else 320 *((uint32_t*)iv[0]) = *((uint32_t*)(cipher->IV)); 321 *((uint32_t*)iv[1]) = *((uint32_t*)(cipher->IV+ 4)); 322 *((uint32_t*)iv[2]) = *((uint32_t*)(cipher->IV+ 8)); 323 *((uint32_t*)iv[3]) = *((uint32_t*)(cipher->IV+12)); 324 #endif 325 for (i = numBlocks; i > 0; i--) { 326 for (k = 0; k < 128; k++) { 327 *((uint32_t*) block ) = *((uint32_t*)iv[0]); 328 *((uint32_t*)(block+ 4)) = *((uint32_t*)iv[1]); 329 *((uint32_t*)(block+ 8)) = *((uint32_t*)iv[2]); 330 *((uint32_t*)(block+12)) = *((uint32_t*)iv[3]); 331 rijndaelEncrypt(key->ek, key->Nr, block, 332 block); 333 iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7); 334 iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7); 335 iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7); 336 iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7); 337 iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7); 338 iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7); 339 iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7); 340 iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7); 341 iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7); 342 iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7); 343 iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7); 344 iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7); 345 iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7); 346 iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7); 347 iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7); 348 iv[3][3] = (iv[3][3] << 1) | ((input[k/8] >> (7-(k&7))) & 1); 349 outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7); 350 } 351 } 352 break; 353 354 default: 355 return BAD_CIPHER_STATE; 356 } 357 358 explicit_bzero(block, sizeof(block)); 359 return 128*numBlocks; 360 } 361 362 int rijndael_padDecrypt(cipherInstance *cipher, keyInstance *key, 363 const BYTE *input, int inputOctets, BYTE *outBuffer) { 364 int i, numBlocks, padLen, rval; 365 uint8_t block[16]; 366 uint32_t iv[4]; 367 368 if (cipher == NULL || 369 key == NULL || 370 key->direction == DIR_ENCRYPT) { 371 return BAD_CIPHER_STATE; 372 } 373 if (input == NULL || inputOctets <= 0) { 374 return 0; /* nothing to do */ 375 } 376 if (inputOctets % 16 != 0) { 377 return BAD_DATA; 378 } 379 380 numBlocks = inputOctets/16; 381 382 switch (cipher->mode) { 383 case MODE_ECB: 384 /* all blocks but last */ 385 for (i = numBlocks - 1; i > 0; i--) { 386 rijndaelDecrypt(key->rk, key->Nr, input, outBuffer); 387 input += 16; 388 outBuffer += 16; 389 } 390 /* last block */ 391 rijndaelDecrypt(key->rk, key->Nr, input, block); 392 padLen = block[15]; 393 if (padLen >= 16) { 394 rval = BAD_DATA; 395 goto out; 396 } 397 for (i = 16 - padLen; i < 16; i++) { 398 if (block[i] != padLen) { 399 rval = BAD_DATA; 400 goto out; 401 } 402 } 403 memcpy(outBuffer, block, 16 - padLen); 404 break; 405 406 case MODE_CBC: 407 memcpy(iv, cipher->IV, 16); 408 /* all blocks but last */ 409 for (i = numBlocks - 1; i > 0; i--) { 410 rijndaelDecrypt(key->rk, key->Nr, input, block); 411 ((uint32_t*)block)[0] ^= iv[0]; 412 ((uint32_t*)block)[1] ^= iv[1]; 413 ((uint32_t*)block)[2] ^= iv[2]; 414 ((uint32_t*)block)[3] ^= iv[3]; 415 memcpy(iv, input, 16); 416 memcpy(outBuffer, block, 16); 417 input += 16; 418 outBuffer += 16; 419 } 420 /* last block */ 421 rijndaelDecrypt(key->rk, key->Nr, input, block); 422 ((uint32_t*)block)[0] ^= iv[0]; 423 ((uint32_t*)block)[1] ^= iv[1]; 424 ((uint32_t*)block)[2] ^= iv[2]; 425 ((uint32_t*)block)[3] ^= iv[3]; 426 padLen = block[15]; 427 if (padLen <= 0 || padLen > 16) { 428 rval = BAD_DATA; 429 goto out; 430 } 431 for (i = 16 - padLen; i < 16; i++) { 432 if (block[i] != padLen) { 433 rval = BAD_DATA; 434 goto out; 435 } 436 } 437 memcpy(outBuffer, block, 16 - padLen); 438 break; 439 440 default: 441 return BAD_CIPHER_STATE; 442 } 443 444 rval = 16*numBlocks - padLen; 445 446 out: 447 explicit_bzero(block, sizeof(block)); 448 return rval; 449 } 450