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 89static void 90std_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 96static void 97std_set_key(pgp_crypt_t *crypt, const uint8_t *key) 98{ 99 (void) memcpy(crypt->key, key, crypt->keysize); 100} 101 102static void 103std_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 116static void 117std_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 129static int 130cast5_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 148static void 149cast5_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 154static void 155cast5_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 160static void 161cast5_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 168static void 169cast5_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 178static 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 196static int 197idea_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 227static void 228idea_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 229{ 230 idea_ecb_encrypt(in, out, crypt->encrypt_key); 231} 232 233static void 234idea_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 235{ 236 idea_ecb_encrypt(in, out, crypt->decrypt_key); 237} 238 239static void 240idea_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 247static void 248idea_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 255static 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 277static int 278aes128_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 306static void 307aes_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 308{ 309 AES_encrypt(in, out, crypt->encrypt_key); 310} 311 312static void 313aes_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 314{ 315 AES_decrypt(in, out, crypt->decrypt_key); 316} 317 318static void 319aes_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 326static void 327aes_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 334static 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 355static int 356aes256_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 393static 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 412static int 413tripledes_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 432static void 433tripledes_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 441static void 442tripledes_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 450static void 451tripledes_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 461static void 462tripledes_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 472static 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 494static int 495camellia128_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 520static void 521camellia_block_encrypt(pgp_crypt_t *crypt, void *out, const void *in) 522{ 523 Camellia_encrypt(in, out, crypt->encrypt_key); 524} 525 526static void 527camellia_block_decrypt(pgp_crypt_t *crypt, void *out, const void *in) 528{ 529 Camellia_decrypt(in, out, crypt->decrypt_key); 530} 531 532static void 533camellia_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 540static void 541camellia_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 548static 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 569static int 570camellia256_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 595static 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 614static const pgp_crypt_t * 615get_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 643int 644pgp_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 657unsigned 658pgp_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 665unsigned 666pgp_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 673void 674pgp_encrypt_init(pgp_crypt_t *encrypt) 675{ 676 /* \todo should there be a separate pgp_encrypt_init? */ 677 pgp_decrypt_init(encrypt); 678} 679 680void 681pgp_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 689size_t 690pgp_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 718size_t 719pgp_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*/ 752unsigned 753pgp_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 776size_t 777pgp_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 790size_t 791pgp_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