1 /*- 2 * Copyright (c) 2009 The NetBSD Foundation, Inc. 3 * All rights reserved. 4 * 5 * This code is derived from software contributed to The NetBSD Foundation 6 * by Alistair Crooks (agc@NetBSD.org) 7 * 8 * Redistribution and use in source and binary forms, with or without 9 * modification, are permitted provided that the following conditions 10 * are met: 11 * 1. Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * 2. Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in the 15 * documentation and/or other materials provided with the distribution. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27 * POSSIBILITY OF SUCH DAMAGE. 28 */ 29 /* 30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 31 * All rights reserved. 32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 33 * their moral rights under the UK Copyright Design and Patents Act 1988 to 34 * be recorded as the authors of this copyright work. 35 * 36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not 37 * use this file except in compliance with the License. 38 * 39 * You may obtain a copy of the License at 40 * http://www.apache.org/licenses/LICENSE-2.0 41 * 42 * Unless required by applicable law or agreed to in writing, software 43 * distributed under the License is distributed on an "AS IS" BASIS, 44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 45 * 46 * See the License for the specific language governing permissions and 47 * limitations under the License. 48 */ 49 #include "config.h" 50 51 #ifdef HAVE_SYS_CDEFS_H 52 #include <sys/cdefs.h> 53 #endif 54 55 #if defined(__NetBSD__) 56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 57 __RCSID("$NetBSD: symmetric.c,v 1.18 2010/11/07 08:39:59 agc Exp $"); 58 #endif 59 60 #include "crypto.h" 61 #include "packet-show.h" 62 63 #include <string.h> 64 65 #ifdef HAVE_OPENSSL_CAST_H 66 #include <openssl/cast.h> 67 #endif 68 69 #ifdef HAVE_OPENSSL_IDEA_H 70 #include <openssl/idea.h> 71 #endif 72 73 #ifdef HAVE_OPENSSL_AES_H 74 #include <openssl/aes.h> 75 #endif 76 77 #ifdef HAVE_OPENSSL_DES_H 78 #include <openssl/des.h> 79 #endif 80 81 #ifdef HAVE_OPENSSL_CAMELLIA_H 82 #include <openssl/camellia.h> 83 #endif 84 85 #include "crypto.h" 86 #include "netpgpdefs.h" 87 88 89 static void 90 std_set_iv(pgp_crypt_t *crypt, const uint8_t *iv) 91 { 92 (void) memcpy(crypt->iv, iv, crypt->blocksize); 93 crypt->num = 0; 94 } 95 96 static void 97 std_set_key(pgp_crypt_t *crypt, const uint8_t *key) 98 { 99 (void) memcpy(crypt->key, key, crypt->keysize); 100 } 101 102 static void 103 std_resync(pgp_crypt_t *decrypt) 104 { 105 if ((size_t) decrypt->num == decrypt->blocksize) { 106 return; 107 } 108 109 memmove(decrypt->civ + decrypt->blocksize - decrypt->num, decrypt->civ, 110 (unsigned)decrypt->num); 111 (void) memcpy(decrypt->civ, decrypt->siv + decrypt->num, 112 decrypt->blocksize - decrypt->num); 113 decrypt->num = 0; 114 } 115 116 static void 117 std_finish(pgp_crypt_t *crypt) 118 { 119 if (crypt->encrypt_key) { 120 free(crypt->encrypt_key); 121 crypt->encrypt_key = NULL; 122 } 123 if (crypt->decrypt_key) { 124 free(crypt->decrypt_key); 125 crypt->decrypt_key = NULL; 126 } 127 } 128 129 static int 130 cast5_init(pgp_crypt_t *crypt) 131 { 132 if (crypt->encrypt_key) { 133 free(crypt->encrypt_key); 134 } 135 if ((crypt->encrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { 136 (void) fprintf(stderr, "cast5_init: alloc failure\n"); 137 return 0; 138 } 139 CAST_set_key(crypt->encrypt_key, (int)crypt->keysize, crypt->key); 140 if ((crypt->decrypt_key = calloc(1, sizeof(CAST_KEY))) == NULL) { 141 (void) fprintf(stderr, "cast5_init: alloc failure\n"); 142 return 0; 143 } 144 CAST_set_key(crypt->decrypt_key, (int)crypt->keysize, crypt->key); 145 return 1; 146 } 147 148 static void 149 cast5_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 150 { 151 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_ENCRYPT); 152 } 153 154 static void 155 cast5_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 156 { 157 CAST_ecb_encrypt(in, out, crypt->encrypt_key, CAST_DECRYPT); 158 } 159 160 static void 161 cast5_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 162 { 163 CAST_cfb64_encrypt(in, out, (long)count, 164 crypt->encrypt_key, crypt->iv, &crypt->num, 165 CAST_ENCRYPT); 166 } 167 168 static void 169 cast5_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 170 { 171 CAST_cfb64_encrypt(in, out, (long)count, 172 crypt->encrypt_key, crypt->iv, &crypt->num, 173 CAST_DECRYPT); 174 } 175 176 #define TRAILER "","","","",0,NULL,NULL 177 178 static pgp_crypt_t cast5 = 179 { 180 PGP_SA_CAST5, 181 CAST_BLOCK, 182 CAST_KEY_LENGTH, 183 std_set_iv, 184 std_set_key, 185 cast5_init, 186 std_resync, 187 cast5_block_encrypt, 188 cast5_block_decrypt, 189 cast5_cfb_encrypt, 190 cast5_cfb_decrypt, 191 std_finish, 192 TRAILER 193 }; 194 195 #ifndef OPENSSL_NO_IDEA 196 static int 197 idea_init(pgp_crypt_t *crypt) 198 { 199 if (crypt->keysize != IDEA_KEY_LENGTH) { 200 (void) fprintf(stderr, "idea_init: keysize wrong\n"); 201 return 0; 202 } 203 204 if (crypt->encrypt_key) { 205 free(crypt->encrypt_key); 206 } 207 if ((crypt->encrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) { 208 (void) fprintf(stderr, "idea_init: alloc failure\n"); 209 return 0; 210 } 211 212 /* note that we don't invert the key when decrypting for CFB mode */ 213 idea_set_encrypt_key(crypt->key, crypt->encrypt_key); 214 215 if (crypt->decrypt_key) { 216 free(crypt->decrypt_key); 217 } 218 if ((crypt->decrypt_key = calloc(1, sizeof(IDEA_KEY_SCHEDULE))) == NULL) { 219 (void) fprintf(stderr, "idea_init: alloc failure\n"); 220 return 0; 221 } 222 223 idea_set_decrypt_key(crypt->encrypt_key, crypt->decrypt_key); 224 return 1; 225 } 226 227 static void 228 idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 229 { 230 idea_ecb_encrypt(in, out, crypt->encrypt_key); 231 } 232 233 static void 234 idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 235 { 236 idea_ecb_encrypt(in, out, crypt->decrypt_key); 237 } 238 239 static void 240 idea_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 241 { 242 idea_cfb64_encrypt(in, out, (long)count, 243 crypt->encrypt_key, crypt->iv, &crypt->num, 244 CAST_ENCRYPT); 245 } 246 247 static void 248 idea_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 249 { 250 idea_cfb64_encrypt(in, out, (long)count, 251 crypt->decrypt_key, crypt->iv, &crypt->num, 252 CAST_DECRYPT); 253 } 254 255 static const pgp_crypt_t idea = 256 { 257 PGP_SA_IDEA, 258 IDEA_BLOCK, 259 IDEA_KEY_LENGTH, 260 std_set_iv, 261 std_set_key, 262 idea_init, 263 std_resync, 264 idea_block_encrypt, 265 idea_block_decrypt, 266 idea_cfb_encrypt, 267 idea_cfb_decrypt, 268 std_finish, 269 TRAILER 270 }; 271 #endif /* OPENSSL_NO_IDEA */ 272 273 /* AES with 128-bit key (AES) */ 274 275 #define KEYBITS_AES128 128 276 277 static int 278 aes128_init(pgp_crypt_t *crypt) 279 { 280 if (crypt->encrypt_key) { 281 free(crypt->encrypt_key); 282 } 283 if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { 284 (void) fprintf(stderr, "aes128_init: alloc failure\n"); 285 return 0; 286 } 287 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES128, 288 crypt->encrypt_key)) { 289 fprintf(stderr, "aes128_init: Error setting encrypt_key\n"); 290 } 291 292 if (crypt->decrypt_key) { 293 free(crypt->decrypt_key); 294 } 295 if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { 296 (void) fprintf(stderr, "aes128_init: alloc failure\n"); 297 return 0; 298 } 299 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES128, 300 crypt->decrypt_key)) { 301 fprintf(stderr, "aes128_init: Error setting decrypt_key\n"); 302 } 303 return 1; 304 } 305 306 static void 307 aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 308 { 309 AES_encrypt(in, out, crypt->encrypt_key); 310 } 311 312 static void 313 aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 314 { 315 AES_decrypt(in, out, crypt->decrypt_key); 316 } 317 318 static void 319 aes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 320 { 321 AES_cfb128_encrypt(in, out, (unsigned)count, 322 crypt->encrypt_key, crypt->iv, &crypt->num, 323 AES_ENCRYPT); 324 } 325 326 static void 327 aes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 328 { 329 AES_cfb128_encrypt(in, out, (unsigned)count, 330 crypt->encrypt_key, crypt->iv, &crypt->num, 331 AES_DECRYPT); 332 } 333 334 static const pgp_crypt_t aes128 = 335 { 336 PGP_SA_AES_128, 337 AES_BLOCK_SIZE, 338 KEYBITS_AES128 / 8, 339 std_set_iv, 340 std_set_key, 341 aes128_init, 342 std_resync, 343 aes_block_encrypt, 344 aes_block_decrypt, 345 aes_cfb_encrypt, 346 aes_cfb_decrypt, 347 std_finish, 348 TRAILER 349 }; 350 351 /* AES with 256-bit key */ 352 353 #define KEYBITS_AES256 256 354 355 static int 356 aes256_init(pgp_crypt_t *crypt) 357 { 358 if (crypt->encrypt_key) { 359 free(crypt->encrypt_key); 360 } 361 if ((crypt->encrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { 362 (void) fprintf(stderr, "aes256_init: alloc failure\n"); 363 return 0; 364 } 365 if (AES_set_encrypt_key(crypt->key, KEYBITS_AES256, 366 crypt->encrypt_key)) { 367 fprintf(stderr, "aes256_init: Error setting encrypt_key\n"); 368 free(crypt->encrypt_key); 369 crypt->encrypt_key = NULL; 370 return 0; 371 } 372 if (crypt->decrypt_key) { 373 free(crypt->decrypt_key); 374 } 375 if ((crypt->decrypt_key = calloc(1, sizeof(AES_KEY))) == NULL) { 376 (void) fprintf(stderr, "aes256_init: alloc failure\n"); 377 free(crypt->encrypt_key); 378 crypt->encrypt_key = NULL; 379 return 0; 380 } 381 if (AES_set_decrypt_key(crypt->key, KEYBITS_AES256, 382 crypt->decrypt_key)) { 383 fprintf(stderr, "aes256_init: Error setting decrypt_key\n"); 384 free(crypt->encrypt_key); 385 crypt->encrypt_key = NULL; 386 free(crypt->decrypt_key); 387 crypt->decrypt_key = NULL; 388 return 0; 389 } 390 return 1; 391 } 392 393 static const pgp_crypt_t aes256 = 394 { 395 PGP_SA_AES_256, 396 AES_BLOCK_SIZE, 397 KEYBITS_AES256 / 8, 398 std_set_iv, 399 std_set_key, 400 aes256_init, 401 std_resync, 402 aes_block_encrypt, 403 aes_block_decrypt, 404 aes_cfb_encrypt, 405 aes_cfb_decrypt, 406 std_finish, 407 TRAILER 408 }; 409 410 /* Triple DES */ 411 412 static int 413 tripledes_init(pgp_crypt_t *crypt) 414 { 415 DES_key_schedule *keys; 416 int n; 417 418 if (crypt->encrypt_key) { 419 free(crypt->encrypt_key); 420 } 421 if ((keys = crypt->encrypt_key = calloc(1, 3 * sizeof(DES_key_schedule))) == NULL) { 422 (void) fprintf(stderr, "tripledes_init: alloc failure\n"); 423 return 0; 424 } 425 for (n = 0; n < 3; ++n) { 426 DES_set_key((DES_cblock *)(void *)(crypt->key + n * 8), 427 &keys[n]); 428 } 429 return 1; 430 } 431 432 static void 433 tripledes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 434 { 435 DES_key_schedule *keys = crypt->encrypt_key; 436 437 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], 438 DES_ENCRYPT); 439 } 440 441 static void 442 tripledes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 443 { 444 DES_key_schedule *keys = crypt->encrypt_key; 445 446 DES_ecb3_encrypt(__UNCONST(in), out, &keys[0], &keys[1], &keys[2], 447 DES_DECRYPT); 448 } 449 450 static void 451 tripledes_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, 452 size_t count) 453 { 454 DES_key_schedule *keys = crypt->encrypt_key; 455 456 DES_ede3_cfb64_encrypt(in, out, (long)count, 457 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, 458 &crypt->num, DES_ENCRYPT); 459 } 460 461 static void 462 tripledes_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, 463 size_t count) 464 { 465 DES_key_schedule *keys = crypt->encrypt_key; 466 467 DES_ede3_cfb64_encrypt(in, out, (long)count, 468 &keys[0], &keys[1], &keys[2], (DES_cblock *)(void *)crypt->iv, 469 &crypt->num, DES_DECRYPT); 470 } 471 472 static const pgp_crypt_t tripledes = 473 { 474 PGP_SA_TRIPLEDES, 475 8, 476 24, 477 std_set_iv, 478 std_set_key, 479 tripledes_init, 480 std_resync, 481 tripledes_block_encrypt, 482 tripledes_block_decrypt, 483 tripledes_cfb_encrypt, 484 tripledes_cfb_decrypt, 485 std_finish, 486 TRAILER 487 }; 488 489 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) 490 /* Camellia with 128-bit key (CAMELLIA) */ 491 492 #define KEYBITS_CAMELLIA128 128 493 494 static int 495 camellia128_init(pgp_crypt_t *crypt) 496 { 497 if (crypt->encrypt_key) { 498 free(crypt->encrypt_key); 499 } 500 if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { 501 (void) fprintf(stderr, "camellia128_init: alloc failure\n"); 502 return 0; 503 } 504 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->encrypt_key)) { 505 fprintf(stderr, "camellia128_init: Error setting encrypt_key\n"); 506 } 507 if (crypt->decrypt_key) { 508 free(crypt->decrypt_key); 509 } 510 if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { 511 (void) fprintf(stderr, "camellia128_init: alloc failure\n"); 512 return 0; 513 } 514 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA128, crypt->decrypt_key)) { 515 fprintf(stderr, "camellia128_init: Error setting decrypt_key\n"); 516 } 517 return 1; 518 } 519 520 static void 521 camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 522 { 523 Camellia_encrypt(in, out, crypt->encrypt_key); 524 } 525 526 static void 527 camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 528 { 529 Camellia_decrypt(in, out, crypt->decrypt_key); 530 } 531 532 static void 533 camellia_cfb_encrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 534 { 535 Camellia_cfb128_encrypt(in, out, (unsigned)count, 536 crypt->encrypt_key, crypt->iv, &crypt->num, 537 CAMELLIA_ENCRYPT); 538 } 539 540 static void 541 camellia_cfb_decrypt(pgp_crypt_t *crypt, void *out, const void *in, size_t count) 542 { 543 Camellia_cfb128_encrypt(in, out, (unsigned)count, 544 crypt->encrypt_key, crypt->iv, &crypt->num, 545 CAMELLIA_DECRYPT); 546 } 547 548 static const pgp_crypt_t camellia128 = 549 { 550 PGP_SA_CAMELLIA_128, 551 CAMELLIA_BLOCK_SIZE, 552 KEYBITS_CAMELLIA128 / 8, 553 std_set_iv, 554 std_set_key, 555 camellia128_init, 556 std_resync, 557 camellia_block_encrypt, 558 camellia_block_decrypt, 559 camellia_cfb_encrypt, 560 camellia_cfb_decrypt, 561 std_finish, 562 TRAILER 563 }; 564 565 /* Camellia with 256-bit key (CAMELLIA) */ 566 567 #define KEYBITS_CAMELLIA256 256 568 569 static int 570 camellia256_init(pgp_crypt_t *crypt) 571 { 572 if (crypt->encrypt_key) { 573 free(crypt->encrypt_key); 574 } 575 if ((crypt->encrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { 576 (void) fprintf(stderr, "camellia256_init: alloc failure\n"); 577 return 0; 578 } 579 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->encrypt_key)) { 580 fprintf(stderr, "camellia256_init: Error setting encrypt_key\n"); 581 } 582 if (crypt->decrypt_key) { 583 free(crypt->decrypt_key); 584 } 585 if ((crypt->decrypt_key = calloc(1, sizeof(CAMELLIA_KEY))) == NULL) { 586 (void) fprintf(stderr, "camellia256_init: alloc failure\n"); 587 return 0; 588 } 589 if (Camellia_set_key(crypt->key, KEYBITS_CAMELLIA256, crypt->decrypt_key)) { 590 fprintf(stderr, "camellia256_init: Error setting decrypt_key\n"); 591 } 592 return 1; 593 } 594 595 static const pgp_crypt_t camellia256 = 596 { 597 PGP_SA_CAMELLIA_256, 598 CAMELLIA_BLOCK_SIZE, 599 KEYBITS_CAMELLIA256 / 8, 600 std_set_iv, 601 std_set_key, 602 camellia256_init, 603 std_resync, 604 camellia_block_encrypt, 605 camellia_block_decrypt, 606 camellia_cfb_encrypt, 607 camellia_cfb_decrypt, 608 std_finish, 609 TRAILER 610 }; 611 #endif 612 613 614 static const pgp_crypt_t * 615 get_proto(pgp_symm_alg_t alg) 616 { 617 switch (alg) { 618 case PGP_SA_CAST5: 619 return &cast5; 620 #ifndef OPENSSL_NO_IDEA 621 case PGP_SA_IDEA: 622 return &idea; 623 #endif /* OPENSSL_NO_IDEA */ 624 case PGP_SA_AES_128: 625 return &aes128; 626 case PGP_SA_AES_256: 627 return &aes256; 628 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) 629 case PGP_SA_CAMELLIA_128: 630 return &camellia128; 631 case PGP_SA_CAMELLIA_256: 632 return &camellia256; 633 #endif 634 case PGP_SA_TRIPLEDES: 635 return &tripledes; 636 default: 637 (void) fprintf(stderr, "Unknown algorithm: %d (%s)\n", 638 alg, pgp_show_symm_alg(alg)); 639 } 640 return NULL; 641 } 642 643 int 644 pgp_crypt_any(pgp_crypt_t *crypt, pgp_symm_alg_t alg) 645 { 646 const pgp_crypt_t *ptr = get_proto(alg); 647 648 if (ptr) { 649 *crypt = *ptr; 650 return 1; 651 } else { 652 (void) memset(crypt, 0x0, sizeof(*crypt)); 653 return 0; 654 } 655 } 656 657 unsigned 658 pgp_block_size(pgp_symm_alg_t alg) 659 { 660 const pgp_crypt_t *p = get_proto(alg); 661 662 return (p == NULL) ? 0 : (unsigned)p->blocksize; 663 } 664 665 unsigned 666 pgp_key_size(pgp_symm_alg_t alg) 667 { 668 const pgp_crypt_t *p = get_proto(alg); 669 670 return (p == NULL) ? 0 : (unsigned)p->keysize; 671 } 672 673 void 674 pgp_encrypt_init(pgp_crypt_t *encrypt) 675 { 676 /* \todo should there be a separate pgp_encrypt_init? */ 677 pgp_decrypt_init(encrypt); 678 } 679 680 void 681 pgp_decrypt_init(pgp_crypt_t *decrypt) 682 { 683 decrypt->base_init(decrypt); 684 decrypt->block_encrypt(decrypt, decrypt->siv, decrypt->iv); 685 (void) memcpy(decrypt->civ, decrypt->siv, decrypt->blocksize); 686 decrypt->num = 0; 687 } 688 689 size_t 690 pgp_decrypt_se(pgp_crypt_t *decrypt, void *outvoid, const void *invoid, 691 size_t count) 692 { 693 const uint8_t *in = invoid; 694 uint8_t *out = outvoid; 695 int saved = (int)count; 696 697 /* 698 * in order to support v3's weird resyncing we have to implement CFB 699 * mode ourselves 700 */ 701 while (count-- > 0) { 702 uint8_t t; 703 704 if ((size_t) decrypt->num == decrypt->blocksize) { 705 (void) memcpy(decrypt->siv, decrypt->civ, 706 decrypt->blocksize); 707 decrypt->block_decrypt(decrypt, decrypt->civ, 708 decrypt->civ); 709 decrypt->num = 0; 710 } 711 t = decrypt->civ[decrypt->num]; 712 *out++ = t ^ (decrypt->civ[decrypt->num++] = *in++); 713 } 714 715 return (size_t)saved; 716 } 717 718 size_t 719 pgp_encrypt_se(pgp_crypt_t *encrypt, void *outvoid, const void *invoid, 720 size_t count) 721 { 722 const uint8_t *in = invoid; 723 uint8_t *out = outvoid; 724 int saved = (int)count; 725 726 /* 727 * in order to support v3's weird resyncing we have to implement CFB 728 * mode ourselves 729 */ 730 while (count-- > 0) { 731 if ((size_t) encrypt->num == encrypt->blocksize) { 732 (void) memcpy(encrypt->siv, encrypt->civ, 733 encrypt->blocksize); 734 encrypt->block_encrypt(encrypt, encrypt->civ, 735 encrypt->civ); 736 encrypt->num = 0; 737 } 738 encrypt->civ[encrypt->num] = *out++ = 739 encrypt->civ[encrypt->num] ^ *in++; 740 ++encrypt->num; 741 } 742 743 return (size_t)saved; 744 } 745 746 /** 747 \ingroup HighLevel_Supported 748 \brief Is this Symmetric Algorithm supported? 749 \param alg Symmetric Algorithm to check 750 \return 1 if supported; else 0 751 */ 752 unsigned 753 pgp_is_sa_supported(pgp_symm_alg_t alg) 754 { 755 switch (alg) { 756 case PGP_SA_AES_128: 757 case PGP_SA_AES_256: 758 case PGP_SA_CAST5: 759 case PGP_SA_TRIPLEDES: 760 #if defined(HAVE_OPENSSL_CAMELLIA_H) && !defined(OPENSSL_NO_CAMELLIA) 761 case PGP_SA_CAMELLIA_128: 762 case PGP_SA_CAMELLIA_256: 763 #endif 764 #ifndef OPENSSL_NO_IDEA 765 case PGP_SA_IDEA: 766 #endif 767 return 1; 768 769 default: 770 fprintf(stderr, "\nWarning: %s not supported\n", 771 pgp_show_symm_alg(alg)); 772 return 0; 773 } 774 } 775 776 size_t 777 pgp_encrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in, 778 size_t count) 779 { 780 if (!pgp_is_sa_supported(crypt->alg)) { 781 return 0; 782 } 783 784 crypt->cfb_encrypt(crypt, out, in, count); 785 786 /* \todo test this number was encrypted */ 787 return count; 788 } 789 790 size_t 791 pgp_decrypt_se_ip(pgp_crypt_t *crypt, void *out, const void *in, 792 size_t count) 793 { 794 if (!pgp_is_sa_supported(crypt->alg)) { 795 return 0; 796 } 797 798 crypt->cfb_decrypt(crypt, out, in, count); 799 800 /* \todo check this number was in fact decrypted */ 801 return count; 802 } 803