1 /* 2 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 3 * All rights reserved. 4 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 5 * their moral rights under the UK Copyright Design and Patents Act 1988 to 6 * be recorded as the authors of this copyright work. 7 * 8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 9 * use this file except in compliance with the License. 10 * 11 * You may obtain a copy of the License at 12 * http://www.apache.org/licenses/LICENSE-2.0 13 * 14 * Unless required by applicable law or agreed to in writing, software 15 * distributed under the License is distributed on an "AS IS" BASIS, 16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 * 18 * See the License for the specific language governing permissions and 19 * limitations under the License. 20 */ 21 #include "config.h" 22 23 #include "crypto.h" 24 #include "packet-show.h" 25 26 #include <string.h> 27 28 #ifdef HAVE_ASSERT_H 29 #include <assert.h> 30 #endif 31 32 #ifdef HAVE_OPENSSL_CAST_H 33 #include <openssl/cast.h> 34 #endif 35 36 #ifdef HAVE_OPENSSL_IDEA_H 37 #include <openssl/idea.h> 38 #endif 39 40 #ifdef HAVE_OPENSSL_AES_H 41 #include <openssl/aes.h> 42 #endif 43 44 #ifdef HAVE_OPENSSL_DES_H 45 #include <openssl/des.h> 46 #endif 47 48 #include "parse_local.h" 49 #include "netpgpdefs.h" 50 51 52 static void 53 std_set_iv(__ops_crypt_t * crypt, const unsigned char *iv) 54 { 55 (void) memcpy(crypt->iv, iv, crypt->blocksize); 56 crypt->num = 0; 57 } 58 59 static void 60 std_set_key(__ops_crypt_t * crypt, const unsigned char *key) 61 { 62 (void) memcpy(crypt->key, key, crypt->keysize); 63 } 64 65 static void 66 std_resync(__ops_crypt_t * decrypt) 67 { 68 if ((size_t) decrypt->num == decrypt->blocksize) 69 return; 70 71 memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ, 72 (unsigned)decrypt->num); 73 (void) memcpy(decrypt->civ, decrypt->siv + decrypt->num, 74 decrypt->blocksize - decrypt->num); 75 decrypt->num = 0; 76 } 77 78 static void 79 std_finish(__ops_crypt_t * crypt) 80 { 81 if (crypt->encrypt_key) { 82 free(crypt->encrypt_key); 83 crypt->encrypt_key = NULL; 84 } 85 if (crypt->decrypt_key) { 86 free(crypt->decrypt_key); 87 crypt->decrypt_key = NULL; 88 } 89 } 90 91 static void 92 cast5_init(__ops_crypt_t * crypt) 93 { 94 if (crypt->encrypt_key) 95 free(crypt->encrypt_key); 96 crypt->encrypt_key = calloc(1, sizeof(CAST_KEY)); 97 CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key); 98 crypt->decrypt_key = calloc(1, sizeof(CAST_KEY)); 99 CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key); 100 } 101 102 static void 103 cast5_block_encrypt(__ops_crypt_t * crypt, void *out, const void *in) 104 { 105 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT); 106 } 107 108 static void 109 cast5_block_decrypt(__ops_crypt_t * crypt, void *out, const void *in) 110 { 111 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT); 112 } 113 114 static void 115 cast5_cfb_encrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 116 { 117 CAST_cfb64_encrypt(in, out, (long)count, 118 crypt->encrypt_key, crypt->iv, &crypt->num, 119 CAST_ENCRYPT); 120 } 121 122 static void 123 cast5_cfb_decrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 124 { 125 CAST_cfb64_encrypt(in, out, (long)count, 126 crypt->encrypt_key, crypt->iv, &crypt->num, 127 CAST_DECRYPT); 128 } 129 130 #define TRAILER "","","","",0,NULL,NULL 131 132 static __ops_crypt_t cast5 = 133 { 134 OPS_SA_CAST5, 135 CAST_BLOCK, 136 CAST_KEY_LENGTH, 137 std_set_iv, 138 std_set_key, 139 cast5_init, 140 std_resync, 141 cast5_block_encrypt, 142 cast5_block_decrypt, 143 cast5_cfb_encrypt, 144 cast5_cfb_decrypt, 145 std_finish, 146 TRAILER 147 }; 148 149 #ifndef OPENSSL_NO_IDEA 150 static void 151 idea_init(__ops_crypt_t * crypt) 152 { 153 assert(crypt->keysize == IDEA_KEY_LENGTH); 154 155 if (crypt->encrypt_key) 156 free(crypt->encrypt_key); 157 crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE)); 158 159 /* note that we don't invert the key when decrypting for CFB mode */ 160 idea_set_encrypt_key(crypt->key, crypt->encrypt_key); 161 162 if (crypt->decrypt_key) 163 free(crypt->decrypt_key); 164 crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE)); 165 166 idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key); 167 } 168 169 static void 170 idea_block_encrypt(__ops_crypt_t * crypt, void *out, const void *in) 171 { 172 idea_ecb_encrypt(in, out, crypt->encrypt_key); 173 } 174 175 static void 176 idea_block_decrypt(__ops_crypt_t * crypt, void *out, const void *in) 177 { 178 idea_ecb_encrypt(in, out, crypt->decrypt_key); 179 } 180 181 static void 182 idea_cfb_encrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 183 { 184 idea_cfb64_encrypt(in, out, (long)count, 185 crypt->encrypt_key, crypt->iv, &crypt->num, 186 CAST_ENCRYPT); 187 } 188 189 static void 190 idea_cfb_decrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 191 { 192 idea_cfb64_encrypt(in, out, (long)count, 193 crypt->decrypt_key, crypt->iv, &crypt->num, 194 CAST_DECRYPT); 195 } 196 197 static const __ops_crypt_t idea = 198 { 199 OPS_SA_IDEA, 200 IDEA_BLOCK, 201 IDEA_KEY_LENGTH, 202 std_set_iv, 203 std_set_key, 204 idea_init, 205 std_resync, 206 idea_block_encrypt, 207 idea_block_decrypt, 208 idea_cfb_encrypt, 209 idea_cfb_decrypt, 210 std_finish, 211 TRAILER 212 }; 213 #endif /* OPENSSL_NO_IDEA */ 214 215 /* AES with 128-bit key (AES) */ 216 217 #define KEYBITS_AES128 128 218 219 static void 220 aes128_init(__ops_crypt_t * crypt) 221 { 222 if (crypt->encrypt_key) 223 free(crypt->encrypt_key); 224 crypt->encrypt_key = calloc(1, sizeof(AES_KEY)); 225 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128, crypt->encrypt_key)) 226 fprintf(stderr, "aes128_init: Error setting encrypt_key\n"); 227 228 if (crypt->decrypt_key) 229 free(crypt->decrypt_key); 230 crypt->decrypt_key = calloc(1, sizeof(AES_KEY)); 231 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128, crypt->decrypt_key)) 232 fprintf(stderr, "aes128_init: Error setting decrypt_key\n"); 233 } 234 235 static void 236 aes_block_encrypt(__ops_crypt_t * crypt, void *out, const void *in) 237 { 238 AES_encrypt(in, out, crypt->encrypt_key); 239 } 240 241 static void 242 aes_block_decrypt(__ops_crypt_t * crypt, void *out, const void *in) 243 { 244 AES_decrypt(in, out, crypt->decrypt_key); 245 } 246 247 static void 248 aes_cfb_encrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 249 { 250 AES_cfb128_encrypt(in, out, (unsigned long)count, 251 crypt->encrypt_key, crypt->iv, &crypt->num, 252 AES_ENCRYPT); 253 } 254 255 static void 256 aes_cfb_decrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 257 { 258 AES_cfb128_encrypt(in, out, (unsigned long)count, 259 crypt->encrypt_key, crypt->iv, &crypt->num, 260 AES_DECRYPT); 261 } 262 263 static const __ops_crypt_t aes128 = 264 { 265 OPS_SA_AES_128, 266 AES_BLOCK_SIZE, 267 KEYBITS_AES128 / 8, 268 std_set_iv, 269 std_set_key, 270 aes128_init, 271 std_resync, 272 aes_block_encrypt, 273 aes_block_decrypt, 274 aes_cfb_encrypt, 275 aes_cfb_decrypt, 276 std_finish, 277 TRAILER 278 }; 279 280 /* AES with 256-bit key */ 281 282 #define KEYBITS_AES256 256 283 284 static void 285 aes256_init(__ops_crypt_t * crypt) 286 { 287 if (crypt->encrypt_key) 288 free(crypt->encrypt_key); 289 crypt->encrypt_key = calloc(1, sizeof(AES_KEY)); 290 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256, crypt->encrypt_key)) 291 fprintf(stderr, "aes256_init: Error setting encrypt_key\n"); 292 293 if (crypt->decrypt_key) 294 free(crypt->decrypt_key); 295 crypt->decrypt_key = calloc(1, sizeof(AES_KEY)); 296 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256, crypt->decrypt_key)) 297 fprintf(stderr, "aes256_init: Error setting decrypt_key\n"); 298 } 299 300 static const __ops_crypt_t aes256 = 301 { 302 OPS_SA_AES_256, 303 AES_BLOCK_SIZE, 304 KEYBITS_AES256 / 8, 305 std_set_iv, 306 std_set_key, 307 aes256_init, 308 std_resync, 309 aes_block_encrypt, 310 aes_block_decrypt, 311 aes_cfb_encrypt, 312 aes_cfb_decrypt, 313 std_finish, 314 TRAILER 315 }; 316 317 /* Triple DES */ 318 319 static void 320 tripledes_init(__ops_crypt_t * crypt) 321 { 322 DES_key_schedule *keys; 323 int n; 324 325 if (crypt->encrypt_key) 326 free(crypt->encrypt_key); 327 keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule)); 328 329 for (n = 0; n < 3; ++n) 330 DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8), 331 &keys[n]); 332 } 333 334 static void 335 tripledes_block_encrypt(__ops_crypt_t * crypt, void *out, 336 const void *in) 337 { 338 DES_key_schedule *keys = crypt->encrypt_key; 339 340 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], DES_ENCRYPT); 341 } 342 343 static void 344 tripledes_block_decrypt(__ops_crypt_t * crypt, void *out, 345 const void *in) 346 { 347 DES_key_schedule *keys = crypt->encrypt_key; 348 349 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], DES_DECRYPT); 350 } 351 352 static void 353 tripledes_cfb_encrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 354 { 355 DES_key_schedule *keys = crypt->encrypt_key; 356 357 DES_ede3_cfb64_encrypt(in, out, (long)count, 358 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, 359 &crypt->num, DES_ENCRYPT); 360 } 361 362 static void 363 tripledes_cfb_decrypt(__ops_crypt_t * crypt, void *out, const void *in, size_t count) 364 { 365 DES_key_schedule *keys = crypt->encrypt_key; 366 367 DES_ede3_cfb64_encrypt(in, out, (long)count, 368 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, 369 &crypt->num, DES_DECRYPT); 370 } 371 372 static const __ops_crypt_t tripledes = 373 { 374 OPS_SA_TRIPLEDES, 375 8, 376 24, 377 std_set_iv, 378 std_set_key, 379 tripledes_init, 380 std_resync, 381 tripledes_block_encrypt, 382 tripledes_block_decrypt, 383 tripledes_cfb_encrypt, 384 tripledes_cfb_decrypt, 385 std_finish, 386 TRAILER 387 }; 388 389 static const __ops_crypt_t * 390 get_proto(__ops_symmetric_algorithm_t alg) 391 { 392 switch (alg) { 393 case OPS_SA_CAST5: 394 return &cast5; 395 396 #ifndef OPENSSL_NO_IDEA 397 case OPS_SA_IDEA: 398 return &idea; 399 #endif /* OPENSSL_NO_IDEA */ 400 401 case OPS_SA_AES_128: 402 return &aes128; 403 404 case OPS_SA_AES_256: 405 return &aes256; 406 407 case OPS_SA_TRIPLEDES: 408 return &tripledes; 409 410 default: 411 fprintf(stderr, "Unknown algorithm: %d (%s)\n", alg, __ops_show_symmetric_algorithm(alg)); 412 /* assert(0); */ 413 } 414 415 return NULL; 416 } 417 418 int 419 __ops_crypt_any(__ops_crypt_t * crypt, __ops_symmetric_algorithm_t alg) 420 { 421 const __ops_crypt_t *ptr = get_proto(alg); 422 if (ptr) { 423 *crypt = *ptr; 424 return 1; 425 } else { 426 (void) memset(crypt, 0x0, sizeof(*crypt)); 427 return 0; 428 } 429 } 430 431 unsigned 432 __ops_block_size(__ops_symmetric_algorithm_t alg) 433 { 434 const __ops_crypt_t *p = get_proto(alg); 435 436 if (!p) 437 return 0; 438 439 return p->blocksize; 440 } 441 442 unsigned 443 __ops_key_size(__ops_symmetric_algorithm_t alg) 444 { 445 const __ops_crypt_t *p = get_proto(alg); 446 447 if (!p) 448 return 0; 449 450 return p->keysize; 451 } 452 453 void 454 __ops_encrypt_init(__ops_crypt_t * encrypt) 455 { 456 /* \todo should there be a separate __ops_encrypt_init? */ 457 __ops_decrypt_init(encrypt); 458 } 459 460 void 461 __ops_decrypt_init(__ops_crypt_t * decrypt) 462 { 463 decrypt->base_init(decrypt); 464 decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv); 465 (void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize); 466 decrypt->num = 0; 467 } 468 469 size_t 470 __ops_decrypt_se(__ops_crypt_t * decrypt, void *outvoid, const void *invoid, size_t count) 471 { 472 unsigned char *out = outvoid; 473 const unsigned char *in = invoid; 474 int saved = count; 475 476 /* 477 * in order to support v3's weird resyncing we have to implement CFB 478 * mode ourselves 479 */ 480 while (count-- > 0) { 481 unsigned char t; 482 483 if ((size_t) decrypt->num == decrypt->blocksize) { 484 (void) memcpy(decrypt->siv, decrypt->civ, decrypt->blocksize); 485 decrypt->block_decrypt(decrypt, decrypt->civ, decrypt->civ); 486 decrypt->num = 0; 487 } 488 t = decrypt->civ[decrypt->num]; 489 *out++ = t ^ (decrypt->civ[decrypt->num++] = *in++); 490 } 491 492 return saved; 493 } 494 495 size_t 496 __ops_encrypt_se(__ops_crypt_t * encrypt, void *outvoid, const void *invoid, 497 size_t count) 498 { 499 unsigned char *out = outvoid; 500 const unsigned char *in = invoid; 501 int saved = count; 502 503 /* 504 * in order to support v3's weird resyncing we have to implement CFB 505 * mode ourselves 506 */ 507 while (count-- > 0) { 508 if ((size_t) encrypt->num == encrypt->blocksize) { 509 (void) memcpy(encrypt->siv, encrypt->civ, encrypt->blocksize); 510 encrypt->block_encrypt(encrypt, encrypt->civ, encrypt->civ); 511 encrypt->num = 0; 512 } 513 encrypt->civ[encrypt->num] = *out++ = encrypt->civ[encrypt->num] ^ *in++; 514 ++encrypt->num; 515 } 516 517 return saved; 518 } 519 520 /** 521 \ingroup HighLevel_Supported 522 \brief Is this Symmetric Algorithm supported? 523 \param alg Symmetric Algorithm to check 524 \return true if supported; else false 525 */ 526 bool 527 __ops_is_sa_supported(__ops_symmetric_algorithm_t alg) 528 { 529 switch (alg) { 530 case OPS_SA_AES_128: 531 case OPS_SA_AES_256: 532 case OPS_SA_CAST5: 533 case OPS_SA_TRIPLEDES: 534 #ifndef OPENSSL_NO_IDEA 535 case OPS_SA_IDEA: 536 #endif 537 return true; 538 539 default: 540 fprintf(stderr, "\nWarning: %s not supported\n", 541 __ops_show_symmetric_algorithm(alg)); 542 return false; 543 } 544 } 545 546 size_t 547 __ops_encrypt_se_ip(__ops_crypt_t * crypt, void *out, const void *in, 548 size_t count) 549 { 550 if (!__ops_is_sa_supported(crypt->algorithm)) 551 /* XXX - agc changed from -1 to 0 */ 552 return 0; 553 554 crypt->cfb_encrypt(crypt, out, in, count); 555 556 /* \todo test this number was encrypted */ 557 return count; 558 } 559 560 size_t 561 __ops_decrypt_se_ip(__ops_crypt_t * crypt, void *out, const void *in, 562 size_t count) 563 { 564 if (!__ops_is_sa_supported(crypt->algorithm)) 565 /* XXX - agc changed from -1 to 0 */ 566 return 0; 567 568 crypt->cfb_decrypt(crypt, out, in, count); 569 570 /* \todo check this number was in fact decrypted */ 571 return count; 572 } 573