1/* ac.c - Alternative interface for asymmetric cryptography. 2 Copyright (C) 2003, 2004, 2005, 2006 3 2007, 2008 Free Software Foundation, Inc. 4 5 This file is part of Libgcrypt. 6 7 Libgcrypt is free software; you can redistribute it and/or modify 8 it under the terms of the GNU Lesser general Public License as 9 published by the Free Software Foundation; either version 2.1 of 10 the License, or (at your option) any later version. 11 12 Libgcrypt is distributed in the hope that it will be useful, 13 but WITHOUT ANY WARRANTY; without even the implied warranty of 14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 GNU Lesser General Public License for more details. 16 17 You should have received a copy of the GNU Lesser General Public 18 License along with this program; if not, see <http://www.gnu.org/licenses/>. 19 */ 20 21#include <config.h> 22#include <errno.h> 23#include <stdlib.h> 24#include <string.h> 25#include <stdio.h> 26#include <stddef.h> 27 28#include "g10lib.h" 29#include "cipher.h" 30#include "mpi.h" 31 32 33 34/* At the moment the ac interface is a wrapper around the pk 35 interface, but this might change somewhen in the future, depending 36 on how many people prefer the ac interface. */ 37 38/* Mapping of flag numbers to the according strings as it is expected 39 for S-expressions. */ 40static struct number_string 41{ 42 int number; 43 const char *string; 44} ac_flags[] = 45 { 46 { GCRY_AC_FLAG_NO_BLINDING, "no-blinding" }, 47 }; 48 49/* The positions in this list correspond to the values contained in 50 the gcry_ac_key_type_t enumeration list. */ 51static const char *ac_key_identifiers[] = 52 { 53 "private-key", 54 "public-key" 55 }; 56 57/* These specifications are needed for key-pair generation; the caller 58 is allowed to pass additional, algorithm-specific `specs' to 59 gcry_ac_key_pair_generate. This list is used for decoding the 60 provided values according to the selected algorithm. */ 61struct gcry_ac_key_generate_spec 62{ 63 int algorithm; /* Algorithm for which this flag is 64 relevant. */ 65 const char *name; /* Name of this flag. */ 66 size_t offset; /* Offset in the cipher-specific spec 67 structure at which the MPI value 68 associated with this flag is to be 69 found. */ 70} ac_key_generate_specs[] = 71 { 72 { GCRY_AC_RSA, "rsa-use-e", offsetof (gcry_ac_key_spec_rsa_t, e) }, 73 { 0 } 74 }; 75 76/* Handle structure. */ 77struct gcry_ac_handle 78{ 79 int algorithm; /* Algorithm ID associated with this 80 handle. */ 81 const char *algorithm_name; /* Name of the algorithm. */ 82 unsigned int flags; /* Flags, not used yet. */ 83 gcry_module_t module; /* Reference to the algorithm 84 module. */ 85}; 86 87/* A named MPI value. */ 88typedef struct gcry_ac_mpi 89{ 90 char *name; /* Self-maintained copy of name. */ 91 gcry_mpi_t mpi; /* MPI value. */ 92 unsigned int flags; /* Flags. */ 93} gcry_ac_mpi_t; 94 95/* A data set, that is simply a list of named MPI values. */ 96struct gcry_ac_data 97{ 98 gcry_ac_mpi_t *data; /* List of named values. */ 99 unsigned int data_n; /* Number of values in DATA. */ 100}; 101 102/* A single key. */ 103struct gcry_ac_key 104{ 105 gcry_ac_data_t data; /* Data in native ac structure. */ 106 gcry_ac_key_type_t type; /* Type of the key. */ 107}; 108 109/* A key pair. */ 110struct gcry_ac_key_pair 111{ 112 gcry_ac_key_t public; 113 gcry_ac_key_t secret; 114}; 115 116 117 118/* 119 * Functions for working with data sets. 120 */ 121 122/* Creates a new, empty data set and store it in DATA. */ 123gcry_error_t 124_gcry_ac_data_new (gcry_ac_data_t *data) 125{ 126 gcry_ac_data_t data_new; 127 gcry_error_t err; 128 129 if (fips_mode ()) 130 return gpg_error (GPG_ERR_NOT_SUPPORTED); 131 132 data_new = gcry_malloc (sizeof (*data_new)); 133 if (! data_new) 134 { 135 err = gcry_error_from_errno (errno); 136 goto out; 137 } 138 139 data_new->data = NULL; 140 data_new->data_n = 0; 141 *data = data_new; 142 err = 0; 143 144 out: 145 146 return err; 147} 148 149/* Destroys all the entries in DATA, but not DATA itself. */ 150static void 151ac_data_values_destroy (gcry_ac_data_t data) 152{ 153 unsigned int i; 154 155 for (i = 0; i < data->data_n; i++) 156 if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC) 157 { 158 gcry_mpi_release (data->data[i].mpi); 159 gcry_free (data->data[i].name); 160 } 161} 162 163/* Destroys the data set DATA. */ 164void 165_gcry_ac_data_destroy (gcry_ac_data_t data) 166{ 167 if (data) 168 { 169 ac_data_values_destroy (data); 170 gcry_free (data->data); 171 gcry_free (data); 172 } 173} 174 175/* This function creates a copy of the array of named MPIs DATA_MPIS, 176 which is of length DATA_MPIS_N; the copy is stored in 177 DATA_MPIS_CP. */ 178static gcry_error_t 179ac_data_mpi_copy (gcry_ac_mpi_t *data_mpis, unsigned int data_mpis_n, 180 gcry_ac_mpi_t **data_mpis_cp) 181{ 182 gcry_ac_mpi_t *data_mpis_new; 183 gcry_error_t err; 184 unsigned int i; 185 gcry_mpi_t mpi; 186 char *label; 187 188 data_mpis_new = gcry_malloc (sizeof (*data_mpis_new) * data_mpis_n); 189 if (! data_mpis_new) 190 { 191 err = gcry_error_from_errno (errno); 192 goto out; 193 } 194 memset (data_mpis_new, 0, sizeof (*data_mpis_new) * data_mpis_n); 195 196 err = 0; 197 for (i = 0; i < data_mpis_n; i++) 198 { 199 /* Copy values. */ 200 201 label = gcry_strdup (data_mpis[i].name); 202 mpi = gcry_mpi_copy (data_mpis[i].mpi); 203 if (! (label && mpi)) 204 { 205 err = gcry_error_from_errno (errno); 206 gcry_mpi_release (mpi); 207 gcry_free (label); 208 break; 209 } 210 211 data_mpis_new[i].flags = GCRY_AC_FLAG_DEALLOC; 212 data_mpis_new[i].name = label; 213 data_mpis_new[i].mpi = mpi; 214 } 215 if (err) 216 goto out; 217 218 *data_mpis_cp = data_mpis_new; 219 err = 0; 220 221 out: 222 223 if (err) 224 if (data_mpis_new) 225 { 226 for (i = 0; i < data_mpis_n; i++) 227 { 228 gcry_mpi_release (data_mpis_new[i].mpi); 229 gcry_free (data_mpis_new[i].name); 230 } 231 gcry_free (data_mpis_new); 232 } 233 234 return err; 235} 236 237/* Create a copy of the data set DATA and store it in DATA_CP. */ 238gcry_error_t 239_gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data) 240{ 241 gcry_ac_mpi_t *data_mpis = NULL; 242 gcry_ac_data_t data_new; 243 gcry_error_t err; 244 245 if (fips_mode ()) 246 return gpg_error (GPG_ERR_NOT_SUPPORTED); 247 248 /* Allocate data set. */ 249 data_new = gcry_malloc (sizeof (*data_new)); 250 if (! data_new) 251 { 252 err = gcry_error_from_errno (errno); 253 goto out; 254 } 255 256 err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis); 257 if (err) 258 goto out; 259 260 data_new->data_n = data->data_n; 261 data_new->data = data_mpis; 262 *data_cp = data_new; 263 264 out: 265 266 if (err) 267 gcry_free (data_new); 268 269 return err; 270} 271 272/* Returns the number of named MPI values inside of the data set 273 DATA. */ 274unsigned int 275_gcry_ac_data_length (gcry_ac_data_t data) 276{ 277 return data->data_n; 278} 279 280 281/* Add the value MPI to DATA with the label NAME. If FLAGS contains 282 GCRY_AC_FLAG_COPY, the data set will contain copies of NAME 283 and MPI. If FLAGS contains GCRY_AC_FLAG_DEALLOC or 284 GCRY_AC_FLAG_COPY, the values contained in the data set will 285 be deallocated when they are to be removed from the data set. */ 286gcry_error_t 287_gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags, 288 const char *name, gcry_mpi_t mpi) 289{ 290 gcry_error_t err; 291 gcry_mpi_t mpi_cp; 292 char *name_cp; 293 unsigned int i; 294 295 name_cp = NULL; 296 mpi_cp = NULL; 297 298 if (fips_mode ()) 299 return gpg_error (GPG_ERR_NOT_SUPPORTED); 300 301 if (flags & ~(GCRY_AC_FLAG_DEALLOC | GCRY_AC_FLAG_COPY)) 302 { 303 err = gcry_error (GPG_ERR_INV_ARG); 304 goto out; 305 } 306 307 if (flags & GCRY_AC_FLAG_COPY) 308 { 309 /* Create copies. */ 310 311 flags |= GCRY_AC_FLAG_DEALLOC; 312 name_cp = gcry_strdup (name); 313 mpi_cp = gcry_mpi_copy (mpi); 314 if (! (name_cp && mpi_cp)) 315 { 316 err = gcry_error_from_errno (errno); 317 goto out; 318 } 319 } 320 321 /* Search for existing entry. */ 322 for (i = 0; i < data->data_n; i++) 323 if (! strcmp (name, data->data[i].name)) 324 break; 325 if (i < data->data_n) 326 { 327 /* An entry for NAME does already exist. */ 328 if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC) 329 { 330 gcry_mpi_release (data->data[i].mpi); 331 gcry_free (data->data[i].name); 332 } 333 } 334 else 335 { 336 /* Create a new entry. */ 337 338 gcry_ac_mpi_t *ac_mpis; 339 340 ac_mpis = gcry_realloc (data->data, 341 sizeof (*data->data) * (data->data_n + 1)); 342 if (! ac_mpis) 343 { 344 err = gcry_error_from_errno (errno); 345 goto out; 346 } 347 348 if (data->data != ac_mpis) 349 data->data = ac_mpis; 350 data->data_n++; 351 } 352 353 data->data[i].name = name_cp ? name_cp : ((char *) name); 354 data->data[i].mpi = mpi_cp ? mpi_cp : mpi; 355 data->data[i].flags = flags; 356 err = 0; 357 358 out: 359 360 if (err) 361 { 362 gcry_mpi_release (mpi_cp); 363 gcry_free (name_cp); 364 } 365 366 return err; 367} 368 369/* Stores the value labelled with NAME found in the data set DATA in 370 MPI. The returned MPI value will be released in case 371 gcry_ac_data_set is used to associate the label NAME with a 372 different MPI value. */ 373gcry_error_t 374_gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags, 375 const char *name, gcry_mpi_t *mpi) 376{ 377 gcry_mpi_t mpi_return; 378 gcry_error_t err; 379 unsigned int i; 380 381 if (fips_mode ()) 382 return gpg_error (GPG_ERR_NOT_SUPPORTED); 383 384 if (flags & ~(GCRY_AC_FLAG_COPY)) 385 { 386 err = gcry_error (GPG_ERR_INV_ARG); 387 goto out; 388 } 389 390 for (i = 0; i < data->data_n; i++) 391 if (! strcmp (name, data->data[i].name)) 392 break; 393 if (i == data->data_n) 394 { 395 err = gcry_error (GPG_ERR_NOT_FOUND); 396 goto out; 397 } 398 399 if (flags & GCRY_AC_FLAG_COPY) 400 { 401 mpi_return = gcry_mpi_copy (data->data[i].mpi); 402 if (! mpi_return) 403 { 404 err = gcry_error_from_errno (errno); /* FIXME? */ 405 goto out; 406 } 407 } 408 else 409 mpi_return = data->data[i].mpi; 410 411 *mpi = mpi_return; 412 err = 0; 413 414 out: 415 416 return err; 417} 418 419/* Stores in NAME and MPI the named MPI value contained in the data 420 set DATA with the index IDX. NAME or MPI may be NULL. The 421 returned MPI value will be released in case gcry_ac_data_set is 422 used to associate the label NAME with a different MPI value. */ 423gcry_error_t 424_gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags, 425 unsigned int idx, 426 const char **name, gcry_mpi_t *mpi) 427{ 428 gcry_error_t err; 429 gcry_mpi_t mpi_cp; 430 char *name_cp; 431 432 name_cp = NULL; 433 mpi_cp = NULL; 434 435 if (fips_mode ()) 436 return gpg_error (GPG_ERR_NOT_SUPPORTED); 437 438 if (flags & ~(GCRY_AC_FLAG_COPY)) 439 { 440 err = gcry_error (GPG_ERR_INV_ARG); 441 goto out; 442 } 443 444 if (idx >= data->data_n) 445 { 446 err = gcry_error (GPG_ERR_INV_ARG); 447 goto out; 448 } 449 450 if (flags & GCRY_AC_FLAG_COPY) 451 { 452 /* Return copies to the user. */ 453 if (name) 454 { 455 name_cp = gcry_strdup (data->data[idx].name); 456 if (! name_cp) 457 { 458 err = gcry_error_from_errno (errno); 459 goto out; 460 } 461 } 462 if (mpi) 463 { 464 mpi_cp = gcry_mpi_copy (data->data[idx].mpi); 465 if (! mpi_cp) 466 { 467 err = gcry_error_from_errno (errno); 468 goto out; 469 } 470 } 471 } 472 473 if (name) 474 *name = name_cp ? name_cp : data->data[idx].name; 475 if (mpi) 476 *mpi = mpi_cp ? mpi_cp : data->data[idx].mpi; 477 err = 0; 478 479 out: 480 481 if (err) 482 { 483 gcry_mpi_release (mpi_cp); 484 gcry_free (name_cp); 485 } 486 487 return err; 488} 489 490/* Convert the data set DATA into a new S-Expression, which is to be 491 stored in SEXP, according to the identifiers contained in 492 IDENTIFIERS. */ 493gcry_error_t 494_gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp, 495 const char **identifiers) 496{ 497 gcry_sexp_t sexp_new; 498 gcry_error_t err; 499 char *sexp_buffer; 500 size_t sexp_buffer_n; 501 size_t identifiers_n; 502 const char *label; 503 gcry_mpi_t mpi; 504 void **arg_list; 505 size_t data_n; 506 unsigned int i; 507 508 sexp_buffer_n = 1; 509 sexp_buffer = NULL; 510 arg_list = NULL; 511 err = 0; 512 513 if (fips_mode ()) 514 return gpg_error (GPG_ERR_NOT_SUPPORTED); 515 516 /* Calculate size of S-expression representation. */ 517 518 i = 0; 519 if (identifiers) 520 while (identifiers[i]) 521 { 522 /* For each identifier, we add "(<IDENTIFIER>)". */ 523 sexp_buffer_n += 1 + strlen (identifiers[i]) + 1; 524 i++; 525 } 526 identifiers_n = i; 527 528 if (! identifiers_n) 529 /* If there are NO identifiers, we still add surrounding braces so 530 that we have a list of named MPI value lists. Otherwise it 531 wouldn't be too much fun to process these lists. */ 532 sexp_buffer_n += 2; 533 534 data_n = _gcry_ac_data_length (data); 535 for (i = 0; i < data_n; i++) 536 { 537 err = gcry_ac_data_get_index (data, 0, i, &label, NULL); 538 if (err) 539 break; 540 /* For each MPI we add "(<LABEL> %m)". */ 541 sexp_buffer_n += 1 + strlen (label) + 4; 542 } 543 if (err) 544 goto out; 545 546 /* Allocate buffer. */ 547 548 sexp_buffer = gcry_malloc (sexp_buffer_n); 549 if (! sexp_buffer) 550 { 551 err = gcry_error_from_errno (errno); 552 goto out; 553 } 554 555 /* Fill buffer. */ 556 557 *sexp_buffer = 0; 558 sexp_buffer_n = 0; 559 560 /* Add identifiers: (<IDENTIFIER0>(<IDENTIFIER1>...)). */ 561 if (identifiers_n) 562 { 563 /* Add nested identifier lists as usual. */ 564 for (i = 0; i < identifiers_n; i++) 565 sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "(%s", 566 identifiers[i]); 567 } 568 else 569 { 570 /* Add special list. */ 571 sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, "("); 572 } 573 574 /* Add MPI list. */ 575 arg_list = gcry_malloc (sizeof (*arg_list) * (data_n + 1)); 576 if (! arg_list) 577 { 578 err = gcry_error_from_errno (errno); 579 goto out; 580 } 581 for (i = 0; i < data_n; i++) 582 { 583 err = gcry_ac_data_get_index (data, 0, i, &label, &mpi); 584 if (err) 585 break; 586 sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, 587 "(%s %%m)", label); 588 arg_list[i] = &data->data[i].mpi; 589 } 590 if (err) 591 goto out; 592 593 if (identifiers_n) 594 { 595 /* Add closing braces for identifier lists as usual. */ 596 for (i = 0; i < identifiers_n; i++) 597 sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")"); 598 } 599 else 600 { 601 /* Add closing braces for special list. */ 602 sexp_buffer_n += sprintf (sexp_buffer + sexp_buffer_n, ")"); 603 } 604 605 /* Construct. */ 606 err = gcry_sexp_build_array (&sexp_new, NULL, sexp_buffer, arg_list); 607 if (err) 608 goto out; 609 610 *sexp = sexp_new; 611 612 out: 613 614 gcry_free (sexp_buffer); 615 gcry_free (arg_list); 616 617 return err; 618} 619 620/* Create a new data set, which is to be stored in DATA_SET, from the 621 S-Expression SEXP, according to the identifiers contained in 622 IDENTIFIERS. */ 623gcry_error_t 624_gcry_ac_data_from_sexp (gcry_ac_data_t *data_set, gcry_sexp_t sexp, 625 const char **identifiers) 626{ 627 gcry_ac_data_t data_set_new; 628 gcry_error_t err; 629 gcry_sexp_t sexp_cur; 630 gcry_sexp_t sexp_tmp; 631 gcry_mpi_t mpi; 632 char *string; 633 const char *data; 634 size_t data_n; 635 size_t sexp_n; 636 unsigned int i; 637 int skip_name; 638 639 data_set_new = NULL; 640 sexp_cur = sexp; 641 sexp_tmp = NULL; 642 string = NULL; 643 mpi = NULL; 644 err = 0; 645 646 if (fips_mode ()) 647 return gpg_error (GPG_ERR_NOT_SUPPORTED); 648 649 /* Process S-expression/identifiers. */ 650 651 if (identifiers) 652 { 653 for (i = 0; identifiers[i]; i++) 654 { 655 /* Next identifier. Extract first data item from 656 SEXP_CUR. */ 657 data = gcry_sexp_nth_data (sexp_cur, 0, &data_n); 658 659 if (! ((data_n == strlen (identifiers[i])) 660 && (! strncmp (data, identifiers[i], data_n)))) 661 { 662 /* Identifier mismatch -> error. */ 663 err = gcry_error (GPG_ERR_INV_SEXP); 664 break; 665 } 666 667 /* Identifier matches. Now we have to distinguish two 668 cases: 669 670 (i) we are at the last identifier: 671 leave loop 672 673 (ii) we are not at the last identifier: 674 extract next element, which is supposed to be a 675 sublist. */ 676 677 if (! identifiers[i + 1]) 678 /* Last identifier. */ 679 break; 680 else 681 { 682 /* Not the last identifier, extract next sublist. */ 683 684 sexp_tmp = gcry_sexp_nth (sexp_cur, 1); 685 if (! sexp_tmp) 686 { 687 /* Missing sublist. */ 688 err = gcry_error (GPG_ERR_INV_SEXP); 689 break; 690 } 691 692 /* Release old SEXP_CUR, in case it is not equal to the 693 original SEXP. */ 694 if (sexp_cur != sexp) 695 gcry_sexp_release (sexp_cur); 696 697 /* Make SEXP_CUR point to the new current sublist. */ 698 sexp_cur = sexp_tmp; 699 sexp_tmp = NULL; 700 } 701 } 702 if (err) 703 goto out; 704 705 if (i) 706 { 707 /* We have at least one identifier in the list, this means 708 the the list of named MPI values is prefixed, this means 709 that we need to skip the first item (the list name), when 710 processing the MPI values. */ 711 skip_name = 1; 712 } 713 else 714 { 715 /* Since there is no identifiers list, the list of named MPI 716 values is not prefixed with a list name, therefore the 717 offset to use is zero. */ 718 skip_name = 0; 719 } 720 } 721 else 722 /* Since there is no identifiers list, the list of named MPI 723 values is not prefixed with a list name, therefore the offset 724 to use is zero. */ 725 skip_name = 0; 726 727 /* Create data set from S-expression data. */ 728 729 err = gcry_ac_data_new (&data_set_new); 730 if (err) 731 goto out; 732 733 /* Figure out amount of named MPIs in SEXP_CUR. */ 734 if (sexp_cur) 735 sexp_n = gcry_sexp_length (sexp_cur) - skip_name; 736 else 737 sexp_n = 0; 738 739 /* Extracte the named MPIs sequentially. */ 740 for (i = 0; i < sexp_n; i++) 741 { 742 /* Store next S-Expression pair, which is supposed to consist of 743 a name and an MPI value, in SEXP_TMP. */ 744 745 sexp_tmp = gcry_sexp_nth (sexp_cur, i + skip_name); 746 if (! sexp_tmp) 747 { 748 err = gcry_error (GPG_ERR_INV_SEXP); 749 break; 750 } 751 752 /* Extract name from current S-Expression pair. */ 753 data = gcry_sexp_nth_data (sexp_tmp, 0, &data_n); 754 string = gcry_malloc (data_n + 1); 755 if (! string) 756 { 757 err = gcry_error_from_errno (errno); 758 break; 759 } 760 memcpy (string, data, data_n); 761 string[data_n] = 0; 762 763 /* Extract MPI value. */ 764 mpi = gcry_sexp_nth_mpi (sexp_tmp, 1, 0); 765 if (! mpi) 766 { 767 err = gcry_error (GPG_ERR_INV_SEXP); /* FIXME? */ 768 break; 769 } 770 771 /* Store named MPI in data_set_new. */ 772 err = gcry_ac_data_set (data_set_new, GCRY_AC_FLAG_DEALLOC, string, mpi); 773 if (err) 774 break; 775 776/* gcry_free (string); */ 777 string = NULL; 778/* gcry_mpi_release (mpi); */ 779 mpi = NULL; 780 781 gcry_sexp_release (sexp_tmp); 782 sexp_tmp = NULL; 783 } 784 if (err) 785 goto out; 786 787 *data_set = data_set_new; 788 789 out: 790 791 if (sexp_cur != sexp) 792 gcry_sexp_release (sexp_cur); 793 gcry_sexp_release (sexp_tmp); 794 gcry_mpi_release (mpi); 795 gcry_free (string); 796 797 if (err) 798 gcry_ac_data_destroy (data_set_new); 799 800 return err; 801} 802 803 804static void 805_gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data) 806{ 807 unsigned char *mpi_buffer; 808 size_t mpi_buffer_n; 809 unsigned int data_n; 810 gcry_error_t err; 811 const char *name; 812 gcry_mpi_t mpi; 813 unsigned int i; 814 815 if (! data) 816 return; 817 818 if (fips_mode ()) 819 return; 820 821 mpi_buffer = NULL; 822 823 data_n = _gcry_ac_data_length (data); 824 for (i = 0; i < data_n; i++) 825 { 826 err = gcry_ac_data_get_index (data, 0, i, &name, &mpi); 827 if (err) 828 { 829 log_error ("failed to dump data set"); 830 break; 831 } 832 833 err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &mpi_buffer, &mpi_buffer_n, mpi); 834 if (err) 835 { 836 log_error ("failed to dump data set"); 837 break; 838 } 839 840 log_printf ("%s%s%s: %s\n", 841 prefix ? prefix : "", 842 prefix ? ": " : "" 843 , name, mpi_buffer); 844 845 gcry_free (mpi_buffer); 846 mpi_buffer = NULL; 847 } 848 849 gcry_free (mpi_buffer); 850} 851 852/* Dump the named MPI values contained in the data set DATA to 853 Libgcrypt's logging stream. */ 854void 855gcry_ac_data_dump (const char *prefix, gcry_ac_data_t data) 856{ 857 _gcry_ac_data_dump (prefix, data); 858} 859 860/* Destroys any values contained in the data set DATA. */ 861void 862_gcry_ac_data_clear (gcry_ac_data_t data) 863{ 864 ac_data_values_destroy (data); 865 gcry_free (data->data); 866 data->data = NULL; 867 data->data_n = 0; 868} 869 870 871 872/* 873 * Implementation of `ac io' objects. 874 */ 875 876/* Initialize AC_IO according to MODE, TYPE and the variable list of 877 arguments AP. The list of variable arguments to specify depends on 878 the given TYPE. */ 879void 880_gcry_ac_io_init_va (gcry_ac_io_t *ac_io, 881 gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, va_list ap) 882{ 883 memset (ac_io, 0, sizeof (*ac_io)); 884 885 if (fips_mode ()) 886 return; 887 888 gcry_assert ((mode == GCRY_AC_IO_READABLE) || (mode == GCRY_AC_IO_WRITABLE)); 889 gcry_assert ((type == GCRY_AC_IO_STRING) || (type == GCRY_AC_IO_STRING)); 890 891 ac_io->mode = mode; 892 ac_io->type = type; 893 894 switch (mode) 895 { 896 case GCRY_AC_IO_READABLE: 897 switch (type) 898 { 899 case GCRY_AC_IO_STRING: 900 ac_io->io.readable.string.data = va_arg (ap, unsigned char *); 901 ac_io->io.readable.string.data_n = va_arg (ap, size_t); 902 break; 903 904 case GCRY_AC_IO_CALLBACK: 905 ac_io->io.readable.callback.cb = va_arg (ap, gcry_ac_data_read_cb_t); 906 ac_io->io.readable.callback.opaque = va_arg (ap, void *); 907 break; 908 } 909 break; 910 case GCRY_AC_IO_WRITABLE: 911 switch (type) 912 { 913 case GCRY_AC_IO_STRING: 914 ac_io->io.writable.string.data = va_arg (ap, unsigned char **); 915 ac_io->io.writable.string.data_n = va_arg (ap, size_t *); 916 break; 917 918 case GCRY_AC_IO_CALLBACK: 919 ac_io->io.writable.callback.cb = va_arg (ap, gcry_ac_data_write_cb_t); 920 ac_io->io.writable.callback.opaque = va_arg (ap, void *); 921 break; 922 } 923 break; 924 } 925} 926 927/* Initialize AC_IO according to MODE, TYPE and the variable list of 928 arguments. The list of variable arguments to specify depends on 929 the given TYPE. */ 930void 931_gcry_ac_io_init (gcry_ac_io_t *ac_io, 932 gcry_ac_io_mode_t mode, gcry_ac_io_type_t type, ...) 933{ 934 va_list ap; 935 936 va_start (ap, type); 937 _gcry_ac_io_init_va (ac_io, mode, type, ap); 938 va_end (ap); 939} 940 941 942/* Write to the IO object AC_IO BUFFER_N bytes from BUFFER. Return 943 zero on success or error code. */ 944static gcry_error_t 945_gcry_ac_io_write (gcry_ac_io_t *ac_io, unsigned char *buffer, size_t buffer_n) 946{ 947 gcry_error_t err; 948 949 gcry_assert (ac_io->mode == GCRY_AC_IO_WRITABLE); 950 err = 0; 951 952 switch (ac_io->type) 953 { 954 case GCRY_AC_IO_STRING: 955 { 956 unsigned char *p; 957 958 if (*ac_io->io.writable.string.data) 959 { 960 p = gcry_realloc (*ac_io->io.writable.string.data, 961 *ac_io->io.writable.string.data_n + buffer_n); 962 if (! p) 963 err = gcry_error_from_errno (errno); 964 else 965 { 966 if (*ac_io->io.writable.string.data != p) 967 *ac_io->io.writable.string.data = p; 968 memcpy (p + *ac_io->io.writable.string.data_n, buffer, buffer_n); 969 *ac_io->io.writable.string.data_n += buffer_n; 970 } 971 } 972 else 973 { 974 if (gcry_is_secure (buffer)) 975 p = gcry_malloc_secure (buffer_n); 976 else 977 p = gcry_malloc (buffer_n); 978 if (! p) 979 err = gcry_error_from_errno (errno); 980 else 981 { 982 memcpy (p, buffer, buffer_n); 983 *ac_io->io.writable.string.data = p; 984 *ac_io->io.writable.string.data_n = buffer_n; 985 } 986 } 987 } 988 break; 989 990 case GCRY_AC_IO_CALLBACK: 991 err = (*ac_io->io.writable.callback.cb) (ac_io->io.writable.callback.opaque, 992 buffer, buffer_n); 993 break; 994 } 995 996 return err; 997} 998 999/* Read *BUFFER_N bytes from the IO object AC_IO into BUFFER; NREAD 1000 bytes have already been read from the object; on success, store the 1001 amount of bytes read in *BUFFER_N; zero bytes read means EOF. 1002 Return zero on success or error code. */ 1003static gcry_error_t 1004_gcry_ac_io_read (gcry_ac_io_t *ac_io, 1005 unsigned int nread, unsigned char *buffer, size_t *buffer_n) 1006{ 1007 gcry_error_t err; 1008 1009 gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE); 1010 err = 0; 1011 1012 switch (ac_io->type) 1013 { 1014 case GCRY_AC_IO_STRING: 1015 { 1016 size_t bytes_available; 1017 size_t bytes_to_read; 1018 size_t bytes_wanted; 1019 1020 bytes_available = ac_io->io.readable.string.data_n - nread; 1021 bytes_wanted = *buffer_n; 1022 1023 if (bytes_wanted > bytes_available) 1024 bytes_to_read = bytes_available; 1025 else 1026 bytes_to_read = bytes_wanted; 1027 1028 memcpy (buffer, ac_io->io.readable.string.data + nread, bytes_to_read); 1029 *buffer_n = bytes_to_read; 1030 err = 0; 1031 break; 1032 } 1033 1034 case GCRY_AC_IO_CALLBACK: 1035 err = (*ac_io->io.readable.callback.cb) 1036 (ac_io->io.readable.callback.opaque, buffer, buffer_n); 1037 break; 1038 } 1039 1040 return err; 1041} 1042 1043/* Read all data available from the IO object AC_IO into newly 1044 allocated memory, storing an appropriate pointer in *BUFFER and the 1045 amount of bytes read in *BUFFER_N. Return zero on success or error 1046 code. */ 1047static gcry_error_t 1048_gcry_ac_io_read_all (gcry_ac_io_t *ac_io, unsigned char **buffer, size_t *buffer_n) 1049{ 1050 unsigned char *buffer_new; 1051 size_t buffer_new_n; 1052 unsigned char buf[BUFSIZ]; 1053 size_t buf_n; 1054 unsigned char *p; 1055 gcry_error_t err; 1056 1057 buffer_new = NULL; 1058 buffer_new_n = 0; 1059 1060 while (1) 1061 { 1062 buf_n = sizeof (buf); 1063 err = _gcry_ac_io_read (ac_io, buffer_new_n, buf, &buf_n); 1064 if (err) 1065 break; 1066 1067 if (buf_n) 1068 { 1069 p = gcry_realloc (buffer_new, buffer_new_n + buf_n); 1070 if (! p) 1071 { 1072 err = gcry_error_from_errno (errno); 1073 break; 1074 } 1075 1076 if (buffer_new != p) 1077 buffer_new = p; 1078 1079 memcpy (buffer_new + buffer_new_n, buf, buf_n); 1080 buffer_new_n += buf_n; 1081 } 1082 else 1083 break; 1084 } 1085 if (err) 1086 goto out; 1087 1088 *buffer_n = buffer_new_n; 1089 *buffer = buffer_new; 1090 1091 out: 1092 1093 if (err) 1094 gcry_free (buffer_new); 1095 1096 return err; 1097} 1098 1099/* Read data chunks from the IO object AC_IO until EOF, feeding them 1100 to the callback function CB. Return zero on success or error 1101 code. */ 1102static gcry_error_t 1103_gcry_ac_io_process (gcry_ac_io_t *ac_io, 1104 gcry_ac_data_write_cb_t cb, void *opaque) 1105{ 1106 unsigned char buffer[BUFSIZ]; 1107 unsigned int nread; 1108 size_t buffer_n; 1109 gcry_error_t err; 1110 1111 nread = 0; 1112 1113 while (1) 1114 { 1115 buffer_n = sizeof (buffer); 1116 err = _gcry_ac_io_read (ac_io, nread, buffer, &buffer_n); 1117 if (err) 1118 break; 1119 if (buffer_n) 1120 { 1121 err = (*cb) (opaque, buffer, buffer_n); 1122 if (err) 1123 break; 1124 nread += buffer_n; 1125 } 1126 else 1127 break; 1128 } 1129 1130 return err; 1131} 1132 1133 1134 1135/* 1136 * Functions for converting data between the native ac and the 1137 * S-expression structure used by the pk interface. 1138 */ 1139 1140/* Extract the S-Expression DATA_SEXP into DATA under the control of 1141 TYPE and NAME. This function assumes that S-Expressions are of the 1142 following structure: 1143 1144 (IDENTIFIER [...] 1145 (ALGORITHM <list of named MPI values>)) */ 1146static gcry_error_t 1147ac_data_extract (const char *identifier, const char *algorithm, 1148 gcry_sexp_t sexp, gcry_ac_data_t *data) 1149{ 1150 gcry_error_t err; 1151 gcry_sexp_t value_sexp; 1152 gcry_sexp_t data_sexp; 1153 size_t data_sexp_n; 1154 gcry_mpi_t value_mpi; 1155 char *value_name; 1156 const char *data_raw; 1157 size_t data_raw_n; 1158 gcry_ac_data_t data_new; 1159 unsigned int i; 1160 1161 value_sexp = NULL; 1162 data_sexp = NULL; 1163 value_name = NULL; 1164 value_mpi = NULL; 1165 data_new = NULL; 1166 1167 /* Verify that the S-expression contains the correct identifier. */ 1168 data_raw = gcry_sexp_nth_data (sexp, 0, &data_raw_n); 1169 if ((! data_raw) || strncmp (identifier, data_raw, data_raw_n)) 1170 { 1171 err = gcry_error (GPG_ERR_INV_SEXP); 1172 goto out; 1173 } 1174 1175 /* Extract inner S-expression. */ 1176 data_sexp = gcry_sexp_find_token (sexp, algorithm, 0); 1177 if (! data_sexp) 1178 { 1179 err = gcry_error (GPG_ERR_INV_SEXP); 1180 goto out; 1181 } 1182 1183 /* Count data elements. */ 1184 data_sexp_n = gcry_sexp_length (data_sexp); 1185 data_sexp_n--; 1186 1187 /* Allocate new data set. */ 1188 err = _gcry_ac_data_new (&data_new); 1189 if (err) 1190 goto out; 1191 1192 /* Iterate through list of data elements and add them to the data 1193 set. */ 1194 for (i = 0; i < data_sexp_n; i++) 1195 { 1196 /* Get the S-expression of the named MPI, that contains the name 1197 and the MPI value. */ 1198 value_sexp = gcry_sexp_nth (data_sexp, i + 1); 1199 if (! value_sexp) 1200 { 1201 err = gcry_error (GPG_ERR_INV_SEXP); 1202 break; 1203 } 1204 1205 /* Extract the name. */ 1206 data_raw = gcry_sexp_nth_data (value_sexp, 0, &data_raw_n); 1207 if (! data_raw) 1208 { 1209 err = gcry_error (GPG_ERR_INV_SEXP); 1210 break; 1211 } 1212 1213 /* Extract the MPI value. */ 1214 value_mpi = gcry_sexp_nth_mpi (value_sexp, 1, GCRYMPI_FMT_USG); 1215 if (! value_mpi) 1216 { 1217 err = gcry_error (GPG_ERR_INTERNAL); /* FIXME? */ 1218 break; 1219 } 1220 1221 /* Duplicate the name. */ 1222 value_name = gcry_malloc (data_raw_n + 1); 1223 if (! value_name) 1224 { 1225 err = gcry_error_from_errno (errno); 1226 break; 1227 } 1228 strncpy (value_name, data_raw, data_raw_n); 1229 value_name[data_raw_n] = 0; 1230 1231 err = _gcry_ac_data_set (data_new, GCRY_AC_FLAG_DEALLOC, value_name, value_mpi); 1232 if (err) 1233 break; 1234 1235 gcry_sexp_release (value_sexp); 1236 value_sexp = NULL; 1237 value_name = NULL; 1238 value_mpi = NULL; 1239 } 1240 if (err) 1241 goto out; 1242 1243 /* Copy out. */ 1244 *data = data_new; 1245 1246 out: 1247 1248 /* Deallocate resources. */ 1249 if (err) 1250 { 1251 _gcry_ac_data_destroy (data_new); 1252 gcry_mpi_release (value_mpi); 1253 gcry_free (value_name); 1254 gcry_sexp_release (value_sexp); 1255 } 1256 gcry_sexp_release (data_sexp); 1257 1258 return err; 1259} 1260 1261/* Construct an S-expression from the DATA and store it in 1262 DATA_SEXP. The S-expression will be of the following structure: 1263 1264 (IDENTIFIER [(flags [...])] 1265 (ALGORITHM <list of named MPI values>)) */ 1266static gcry_error_t 1267ac_data_construct (const char *identifier, int include_flags, 1268 unsigned int flags, const char *algorithm, 1269 gcry_ac_data_t data, gcry_sexp_t *sexp) 1270{ 1271 unsigned int data_length; 1272 gcry_sexp_t sexp_new; 1273 gcry_error_t err; 1274 size_t sexp_format_n; 1275 char *sexp_format; 1276 void **arg_list; 1277 unsigned int i; 1278 1279 arg_list = NULL; 1280 sexp_new = NULL; 1281 sexp_format = NULL; 1282 1283 /* We build a list of arguments to pass to 1284 gcry_sexp_build_array(). */ 1285 data_length = _gcry_ac_data_length (data); 1286 arg_list = gcry_malloc (sizeof (*arg_list) * (data_length * 2)); 1287 if (! arg_list) 1288 { 1289 err = gcry_error_from_errno (errno); 1290 goto out; 1291 } 1292 1293 /* Fill list with MPIs. */ 1294 for (i = 0; i < data_length; i++) 1295 { 1296 char **nameaddr = &data->data[i].name; 1297 1298 arg_list[(i * 2) + 0] = nameaddr; 1299 arg_list[(i * 2) + 1] = &data->data[i].mpi; 1300 } 1301 1302 /* Calculate size of format string. */ 1303 sexp_format_n = (3 1304 + (include_flags ? 7 : 0) 1305 + (algorithm ? (2 + strlen (algorithm)) : 0) 1306 + strlen (identifier)); 1307 1308 for (i = 0; i < data_length; i++) 1309 /* Per-element sizes. */ 1310 sexp_format_n += 6; 1311 1312 if (include_flags) 1313 /* Add flags. */ 1314 for (i = 0; i < DIM (ac_flags); i++) 1315 if (flags & ac_flags[i].number) 1316 sexp_format_n += strlen (ac_flags[i].string) + 1; 1317 1318 /* Done. */ 1319 sexp_format = gcry_malloc (sexp_format_n); 1320 if (! sexp_format) 1321 { 1322 err = gcry_error_from_errno (errno); 1323 goto out; 1324 } 1325 1326 /* Construct the format string. */ 1327 1328 *sexp_format = 0; 1329 strcat (sexp_format, "("); 1330 strcat (sexp_format, identifier); 1331 if (include_flags) 1332 { 1333 strcat (sexp_format, "(flags"); 1334 for (i = 0; i < DIM (ac_flags); i++) 1335 if (flags & ac_flags[i].number) 1336 { 1337 strcat (sexp_format, " "); 1338 strcat (sexp_format, ac_flags[i].string); 1339 } 1340 strcat (sexp_format, ")"); 1341 } 1342 if (algorithm) 1343 { 1344 strcat (sexp_format, "("); 1345 strcat (sexp_format, algorithm); 1346 } 1347 for (i = 0; i < data_length; i++) 1348 strcat (sexp_format, "(%s%m)"); 1349 if (algorithm) 1350 strcat (sexp_format, ")"); 1351 strcat (sexp_format, ")"); 1352 1353 /* Create final S-expression. */ 1354 err = gcry_sexp_build_array (&sexp_new, NULL, sexp_format, arg_list); 1355 if (err) 1356 goto out; 1357 1358 *sexp = sexp_new; 1359 1360 out: 1361 1362 /* Deallocate resources. */ 1363 gcry_free (sexp_format); 1364 gcry_free (arg_list); 1365 if (err) 1366 gcry_sexp_release (sexp_new); 1367 1368 return err; 1369} 1370 1371 1372 1373/* 1374 * Handle management. 1375 */ 1376 1377/* Creates a new handle for the algorithm ALGORITHM and stores it in 1378 HANDLE. FLAGS is not used yet. */ 1379gcry_error_t 1380_gcry_ac_open (gcry_ac_handle_t *handle, 1381 gcry_ac_id_t algorithm, unsigned int flags) 1382{ 1383 gcry_ac_handle_t handle_new; 1384 const char *algorithm_name; 1385 gcry_module_t module; 1386 gcry_error_t err; 1387 1388 *handle = NULL; 1389 module = NULL; 1390 1391 if (fips_mode ()) 1392 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1393 1394 /* Get name. */ 1395 algorithm_name = _gcry_pk_aliased_algo_name (algorithm); 1396 if (! algorithm_name) 1397 { 1398 err = gcry_error (GPG_ERR_PUBKEY_ALGO); 1399 goto out; 1400 } 1401 1402 /* Acquire reference to the pubkey module. */ 1403 err = _gcry_pk_module_lookup (algorithm, &module); 1404 if (err) 1405 goto out; 1406 1407 /* Allocate. */ 1408 handle_new = gcry_malloc (sizeof (*handle_new)); 1409 if (! handle_new) 1410 { 1411 err = gcry_error_from_errno (errno); 1412 goto out; 1413 } 1414 1415 /* Done. */ 1416 handle_new->algorithm = algorithm; 1417 handle_new->algorithm_name = algorithm_name; 1418 handle_new->flags = flags; 1419 handle_new->module = module; 1420 *handle = handle_new; 1421 1422 out: 1423 1424 /* Deallocate resources. */ 1425 if (err) 1426 _gcry_pk_module_release (module); 1427 1428 return err; 1429} 1430 1431 1432/* Destroys the handle HANDLE. */ 1433void 1434_gcry_ac_close (gcry_ac_handle_t handle) 1435{ 1436 /* Release reference to pubkey module. */ 1437 if (handle) 1438 { 1439 _gcry_pk_module_release (handle->module); 1440 gcry_free (handle); 1441 } 1442} 1443 1444 1445 1446/* 1447 * Key management. 1448 */ 1449 1450/* Initialize a key from a given data set. */ 1451/* FIXME/Damn: the argument HANDLE is not only unnecessary, it is 1452 completely WRONG here. */ 1453gcry_error_t 1454_gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle, 1455 gcry_ac_key_type_t type, gcry_ac_data_t data) 1456{ 1457 gcry_ac_data_t data_new; 1458 gcry_ac_key_t key_new; 1459 gcry_error_t err; 1460 1461 (void)handle; 1462 1463 if (fips_mode ()) 1464 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1465 1466 /* Allocate. */ 1467 key_new = gcry_malloc (sizeof (*key_new)); 1468 if (! key_new) 1469 { 1470 err = gcry_error_from_errno (errno); 1471 goto out; 1472 } 1473 1474 /* Copy data set. */ 1475 err = _gcry_ac_data_copy (&data_new, data); 1476 if (err) 1477 goto out; 1478 1479 /* Done. */ 1480 key_new->data = data_new; 1481 key_new->type = type; 1482 *key = key_new; 1483 1484 out: 1485 1486 if (err) 1487 /* Deallocate resources. */ 1488 gcry_free (key_new); 1489 1490 return err; 1491} 1492 1493 1494/* Generates a new key pair via the handle HANDLE of NBITS bits and 1495 stores it in KEY_PAIR. In case non-standard settings are wanted, a 1496 pointer to a structure of type gcry_ac_key_spec_<algorithm>_t, 1497 matching the selected algorithm, can be given as KEY_SPEC. 1498 MISC_DATA is not used yet. */ 1499gcry_error_t 1500_gcry_ac_key_pair_generate (gcry_ac_handle_t handle, unsigned int nbits, 1501 void *key_spec, 1502 gcry_ac_key_pair_t *key_pair, 1503 gcry_mpi_t **misc_data) 1504{ 1505 gcry_sexp_t genkey_sexp_request; 1506 gcry_sexp_t genkey_sexp_reply; 1507 gcry_ac_data_t key_data_secret; 1508 gcry_ac_data_t key_data_public; 1509 gcry_ac_key_pair_t key_pair_new; 1510 gcry_ac_key_t key_secret; 1511 gcry_ac_key_t key_public; 1512 gcry_sexp_t key_sexp; 1513 gcry_error_t err; 1514 char *genkey_format; 1515 size_t genkey_format_n; 1516 void **arg_list; 1517 size_t arg_list_n; 1518 unsigned int i; 1519 unsigned int j; 1520 1521 (void)misc_data; 1522 1523 if (fips_mode ()) 1524 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1525 1526 key_data_secret = NULL; 1527 key_data_public = NULL; 1528 key_secret = NULL; 1529 key_public = NULL; 1530 genkey_format = NULL; 1531 arg_list = NULL; 1532 genkey_sexp_request = NULL; 1533 genkey_sexp_reply = NULL; 1534 key_sexp = NULL; 1535 1536 /* Allocate key pair. */ 1537 key_pair_new = gcry_malloc (sizeof (struct gcry_ac_key_pair)); 1538 if (! key_pair_new) 1539 { 1540 err = gcry_error_from_errno (errno); 1541 goto out; 1542 } 1543 1544 /* Allocate keys. */ 1545 key_secret = gcry_malloc (sizeof (*key_secret)); 1546 if (! key_secret) 1547 { 1548 err = gcry_error_from_errno (errno); 1549 goto out; 1550 } 1551 key_public = gcry_malloc (sizeof (*key_public)); 1552 if (! key_public) 1553 { 1554 err = gcry_error_from_errno (errno); 1555 goto out; 1556 } 1557 1558 /* Calculate size of the format string, that is used for creating 1559 the request S-expression. */ 1560 genkey_format_n = 22; 1561 1562 /* Respect any relevant algorithm specific commands. */ 1563 if (key_spec) 1564 for (i = 0; i < DIM (ac_key_generate_specs); i++) 1565 if (handle->algorithm == ac_key_generate_specs[i].algorithm) 1566 genkey_format_n += 6; 1567 1568 /* Create format string. */ 1569 genkey_format = gcry_malloc (genkey_format_n); 1570 if (! genkey_format) 1571 { 1572 err = gcry_error_from_errno (errno); 1573 goto out; 1574 } 1575 1576 /* Fill format string. */ 1577 *genkey_format = 0; 1578 strcat (genkey_format, "(genkey(%s(nbits%d)"); 1579 if (key_spec) 1580 for (i = 0; i < DIM (ac_key_generate_specs); i++) 1581 if (handle->algorithm == ac_key_generate_specs[i].algorithm) 1582 strcat (genkey_format, "(%s%m)"); 1583 strcat (genkey_format, "))"); 1584 1585 /* Build list of argument pointers, the algorithm name and the nbits 1586 are always needed. */ 1587 arg_list_n = 2; 1588 1589 /* Now the algorithm specific arguments. */ 1590 if (key_spec) 1591 for (i = 0; i < DIM (ac_key_generate_specs); i++) 1592 if (handle->algorithm == ac_key_generate_specs[i].algorithm) 1593 arg_list_n += 2; 1594 1595 /* Allocate list. */ 1596 arg_list = gcry_malloc (sizeof (*arg_list) * arg_list_n); 1597 if (! arg_list) 1598 { 1599 err = gcry_error_from_errno (errno); 1600 goto out; 1601 } 1602 1603 arg_list[0] = (void *) &handle->algorithm_name; 1604 arg_list[1] = (void *) &nbits; 1605 if (key_spec) 1606 for (j = 2, i = 0; i < DIM (ac_key_generate_specs); i++) 1607 if (handle->algorithm == ac_key_generate_specs[i].algorithm) 1608 { 1609 /* Add name of this specification flag and the 1610 according member of the spec strucuture. */ 1611 arg_list[j++] = (void *)(&ac_key_generate_specs[i].name); 1612 arg_list[j++] = (void *) 1613 (((char *) key_spec) 1614 + ac_key_generate_specs[i].offset); 1615 /* FIXME: above seems to suck. */ 1616 } 1617 1618 /* Construct final request S-expression. */ 1619 err = gcry_sexp_build_array (&genkey_sexp_request, 1620 NULL, genkey_format, arg_list); 1621 if (err) 1622 goto out; 1623 1624 /* Perform genkey operation. */ 1625 err = gcry_pk_genkey (&genkey_sexp_reply, genkey_sexp_request); 1626 if (err) 1627 goto out; 1628 1629 key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "private-key", 0); 1630 if (! key_sexp) 1631 { 1632 err = gcry_error (GPG_ERR_INTERNAL); 1633 goto out; 1634 } 1635 err = ac_data_extract ("private-key", handle->algorithm_name, 1636 key_sexp, &key_data_secret); 1637 if (err) 1638 goto out; 1639 1640 gcry_sexp_release (key_sexp); 1641 key_sexp = gcry_sexp_find_token (genkey_sexp_reply, "public-key", 0); 1642 if (! key_sexp) 1643 { 1644 err = gcry_error (GPG_ERR_INTERNAL); 1645 goto out; 1646 } 1647 err = ac_data_extract ("public-key", handle->algorithm_name, 1648 key_sexp, &key_data_public); 1649 if (err) 1650 goto out; 1651 1652 /* Done. */ 1653 1654 key_secret->type = GCRY_AC_KEY_SECRET; 1655 key_secret->data = key_data_secret; 1656 key_public->type = GCRY_AC_KEY_PUBLIC; 1657 key_public->data = key_data_public; 1658 key_pair_new->secret = key_secret; 1659 key_pair_new->public = key_public; 1660 *key_pair = key_pair_new; 1661 1662 out: 1663 1664 /* Deallocate resources. */ 1665 1666 gcry_free (genkey_format); 1667 gcry_free (arg_list); 1668 gcry_sexp_release (genkey_sexp_request); 1669 gcry_sexp_release (genkey_sexp_reply); 1670 gcry_sexp_release (key_sexp); 1671 if (err) 1672 { 1673 _gcry_ac_data_destroy (key_data_secret); 1674 _gcry_ac_data_destroy (key_data_public); 1675 gcry_free (key_secret); 1676 gcry_free (key_public); 1677 gcry_free (key_pair_new); 1678 } 1679 1680 return err; 1681} 1682 1683/* Returns the key of type WHICH out of the key pair KEY_PAIR. */ 1684gcry_ac_key_t 1685_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair, 1686 gcry_ac_key_type_t which) 1687{ 1688 gcry_ac_key_t key; 1689 1690 if (fips_mode ()) 1691 return NULL; 1692 1693 switch (which) 1694 { 1695 case GCRY_AC_KEY_SECRET: 1696 key = key_pair->secret; 1697 break; 1698 1699 case GCRY_AC_KEY_PUBLIC: 1700 key = key_pair->public; 1701 break; 1702 1703 default: 1704 key = NULL; 1705 break; 1706 } 1707 1708 return key; 1709} 1710 1711/* Destroys the key KEY. */ 1712void 1713_gcry_ac_key_destroy (gcry_ac_key_t key) 1714{ 1715 unsigned int i; 1716 1717 if (key) 1718 { 1719 if (key->data) 1720 { 1721 for (i = 0; i < key->data->data_n; i++) 1722 { 1723 if (key->data->data[i].mpi) 1724 gcry_mpi_release (key->data->data[i].mpi); 1725 if (key->data->data[i].name) 1726 gcry_free (key->data->data[i].name); 1727 } 1728 gcry_free (key->data->data); 1729 gcry_free (key->data); 1730 } 1731 gcry_free (key); 1732 } 1733} 1734 1735/* Destroys the key pair KEY_PAIR. */ 1736void 1737_gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair) 1738{ 1739 if (key_pair) 1740 { 1741 gcry_ac_key_destroy (key_pair->secret); 1742 gcry_ac_key_destroy (key_pair->public); 1743 gcry_free (key_pair); 1744 } 1745} 1746 1747/* Returns the data set contained in the key KEY. */ 1748gcry_ac_data_t 1749_gcry_ac_key_data_get (gcry_ac_key_t key) 1750{ 1751 if (fips_mode ()) 1752 return NULL; 1753 return key->data; 1754} 1755 1756/* Verifies that the key KEY is sane via HANDLE. */ 1757gcry_error_t 1758_gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key) 1759{ 1760 gcry_sexp_t key_sexp; 1761 gcry_error_t err; 1762 1763 if (fips_mode ()) 1764 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1765 1766 key_sexp = NULL; 1767 err = ac_data_construct (ac_key_identifiers[key->type], 0, 0, 1768 handle->algorithm_name, key->data, &key_sexp); 1769 if (err) 1770 goto out; 1771 1772 err = gcry_pk_testkey (key_sexp); 1773 1774 out: 1775 1776 gcry_sexp_release (key_sexp); 1777 1778 return gcry_error (err); 1779} 1780 1781/* Stores the number of bits of the key KEY in NBITS via HANDLE. */ 1782gcry_error_t 1783_gcry_ac_key_get_nbits (gcry_ac_handle_t handle, 1784 gcry_ac_key_t key, unsigned int *nbits) 1785{ 1786 gcry_sexp_t key_sexp; 1787 gcry_error_t err; 1788 unsigned int n; 1789 1790 if (fips_mode ()) 1791 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1792 1793 key_sexp = NULL; 1794 1795 err = ac_data_construct (ac_key_identifiers[key->type], 1796 0, 0, handle->algorithm_name, key->data, &key_sexp); 1797 if (err) 1798 goto out; 1799 1800 n = gcry_pk_get_nbits (key_sexp); 1801 if (! n) 1802 { 1803 err = gcry_error (GPG_ERR_PUBKEY_ALGO); 1804 goto out; 1805 } 1806 1807 *nbits = n; 1808 1809 out: 1810 1811 gcry_sexp_release (key_sexp); 1812 1813 return err; 1814} 1815 1816/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via 1817 HANDLE. */ 1818gcry_error_t 1819_gcry_ac_key_get_grip (gcry_ac_handle_t handle, 1820 gcry_ac_key_t key, unsigned char *key_grip) 1821{ 1822 gcry_sexp_t key_sexp; 1823 gcry_error_t err; 1824 unsigned char *ret; 1825 1826 if (fips_mode ()) 1827 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1828 1829 key_sexp = NULL; 1830 err = ac_data_construct (ac_key_identifiers[key->type], 0, 0, 1831 handle->algorithm_name, key->data, &key_sexp); 1832 if (err) 1833 goto out; 1834 1835 ret = gcry_pk_get_keygrip (key_sexp, key_grip); 1836 if (! ret) 1837 { 1838 err = gcry_error (GPG_ERR_INV_OBJ); 1839 goto out; 1840 } 1841 1842 err = 0; 1843 1844 out: 1845 1846 gcry_sexp_release (key_sexp); 1847 1848 return err; 1849} 1850 1851 1852 1853 1854/* 1855 * Functions performing cryptographic operations. 1856 */ 1857 1858/* Encrypts the plain text MPI value DATA_PLAIN with the key public 1859 KEY under the control of the flags FLAGS and stores the resulting 1860 data set into DATA_ENCRYPTED. */ 1861gcry_error_t 1862_gcry_ac_data_encrypt (gcry_ac_handle_t handle, 1863 unsigned int flags, 1864 gcry_ac_key_t key, 1865 gcry_mpi_t data_plain, 1866 gcry_ac_data_t *data_encrypted) 1867{ 1868 gcry_ac_data_t data_encrypted_new; 1869 gcry_ac_data_t data_value; 1870 gcry_sexp_t sexp_request; 1871 gcry_sexp_t sexp_reply; 1872 gcry_sexp_t sexp_key; 1873 gcry_error_t err; 1874 1875 if (fips_mode ()) 1876 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1877 1878 data_encrypted_new = NULL; 1879 sexp_request = NULL; 1880 sexp_reply = NULL; 1881 data_value = NULL; 1882 sexp_key = NULL; 1883 1884 if (key->type != GCRY_AC_KEY_PUBLIC) 1885 { 1886 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 1887 goto out; 1888 } 1889 1890 err = ac_data_construct (ac_key_identifiers[key->type], 0, 0, 1891 handle->algorithm_name, key->data, &sexp_key); 1892 if (err) 1893 goto out; 1894 1895 err = _gcry_ac_data_new (&data_value); 1896 if (err) 1897 goto out; 1898 1899 err = _gcry_ac_data_set (data_value, 0, "value", data_plain); 1900 if (err) 1901 goto out; 1902 1903 err = ac_data_construct ("data", 1, flags, handle->algorithm_name, 1904 data_value, &sexp_request); 1905 if (err) 1906 goto out; 1907 1908 /* FIXME: error vs. errcode? */ 1909 1910 err = gcry_pk_encrypt (&sexp_reply, sexp_request, sexp_key); 1911 if (err) 1912 goto out; 1913 1914 /* Extract data. */ 1915 err = ac_data_extract ("enc-val", handle->algorithm_name, 1916 sexp_reply, &data_encrypted_new); 1917 if (err) 1918 goto out; 1919 1920 *data_encrypted = data_encrypted_new; 1921 1922 out: 1923 1924 /* Deallocate resources. */ 1925 1926 gcry_sexp_release (sexp_request); 1927 gcry_sexp_release (sexp_reply); 1928 gcry_sexp_release (sexp_key); 1929 _gcry_ac_data_destroy (data_value); 1930 1931 return err; 1932} 1933 1934/* Decrypts the encrypted data contained in the data set 1935 DATA_ENCRYPTED with the secret key KEY under the control of the 1936 flags FLAGS and stores the resulting plain text MPI value in 1937 DATA_PLAIN. */ 1938gcry_error_t 1939_gcry_ac_data_decrypt (gcry_ac_handle_t handle, 1940 unsigned int flags, 1941 gcry_ac_key_t key, 1942 gcry_mpi_t *data_plain, 1943 gcry_ac_data_t data_encrypted) 1944{ 1945 gcry_mpi_t data_decrypted; 1946 gcry_sexp_t sexp_request; 1947 gcry_sexp_t sexp_reply; 1948 gcry_sexp_t sexp_value; 1949 gcry_sexp_t sexp_key; 1950 gcry_error_t err; 1951 1952 if (fips_mode ()) 1953 return gpg_error (GPG_ERR_NOT_SUPPORTED); 1954 1955 sexp_request = NULL; 1956 sexp_reply = NULL; 1957 sexp_value = NULL; 1958 sexp_key = NULL; 1959 1960 if (key->type != GCRY_AC_KEY_SECRET) 1961 { 1962 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 1963 goto out; 1964 } 1965 1966 err = ac_data_construct (ac_key_identifiers[key->type], 0, 0, 1967 handle->algorithm_name, key->data, &sexp_key); 1968 if (err) 1969 goto out; 1970 1971 /* Create S-expression from data. */ 1972 err = ac_data_construct ("enc-val", 1, flags, handle->algorithm_name, 1973 data_encrypted, &sexp_request); 1974 if (err) 1975 goto out; 1976 1977 /* Decrypt. */ 1978 err = gcry_pk_decrypt (&sexp_reply, sexp_request, sexp_key); 1979 if (err) 1980 goto out; 1981 1982 /* Extract plain text. */ 1983 sexp_value = gcry_sexp_find_token (sexp_reply, "value", 0); 1984 if (! sexp_value) 1985 { 1986 /* FIXME? */ 1987 err = gcry_error (GPG_ERR_GENERAL); 1988 goto out; 1989 } 1990 1991 data_decrypted = gcry_sexp_nth_mpi (sexp_value, 1, GCRYMPI_FMT_USG); 1992 if (! data_decrypted) 1993 { 1994 err = gcry_error (GPG_ERR_GENERAL); 1995 goto out; 1996 } 1997 1998 *data_plain = data_decrypted; 1999 2000 out: 2001 2002 /* Deallocate resources. */ 2003 gcry_sexp_release (sexp_request); 2004 gcry_sexp_release (sexp_reply); 2005 gcry_sexp_release (sexp_value); 2006 gcry_sexp_release (sexp_key); 2007 2008 return gcry_error (err); 2009 2010} 2011 2012/* Signs the data contained in DATA with the secret key KEY and stores 2013 the resulting signature data set in DATA_SIGNATURE. */ 2014gcry_error_t 2015_gcry_ac_data_sign (gcry_ac_handle_t handle, 2016 gcry_ac_key_t key, 2017 gcry_mpi_t data, 2018 gcry_ac_data_t *data_signature) 2019{ 2020 gcry_ac_data_t data_signed; 2021 gcry_ac_data_t data_value; 2022 gcry_sexp_t sexp_request; 2023 gcry_sexp_t sexp_reply; 2024 gcry_sexp_t sexp_key; 2025 gcry_error_t err; 2026 2027 if (fips_mode ()) 2028 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2029 2030 data_signed = NULL; 2031 data_value = NULL; 2032 sexp_request = NULL; 2033 sexp_reply = NULL; 2034 sexp_key = NULL; 2035 2036 if (key->type != GCRY_AC_KEY_SECRET) 2037 { 2038 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 2039 goto out; 2040 } 2041 2042 err = ac_data_construct (ac_key_identifiers[key->type], 0, 0, 2043 handle->algorithm_name, key->data, &sexp_key); 2044 if (err) 2045 goto out; 2046 2047 err = _gcry_ac_data_new (&data_value); 2048 if (err) 2049 goto out; 2050 2051 err = _gcry_ac_data_set (data_value, 0, "value", data); 2052 if (err) 2053 goto out; 2054 2055 /* Create S-expression holding the data. */ 2056 err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_request); 2057 if (err) 2058 goto out; 2059 2060 /* Sign. */ 2061 err = gcry_pk_sign (&sexp_reply, sexp_request, sexp_key); 2062 if (err) 2063 goto out; 2064 2065 /* Extract data. */ 2066 err = ac_data_extract ("sig-val", handle->algorithm_name, 2067 sexp_reply, &data_signed); 2068 if (err) 2069 goto out; 2070 2071 /* Done. */ 2072 *data_signature = data_signed; 2073 2074 out: 2075 2076 gcry_sexp_release (sexp_request); 2077 gcry_sexp_release (sexp_reply); 2078 gcry_sexp_release (sexp_key); 2079 _gcry_ac_data_destroy (data_value); 2080 2081 return gcry_error (err); 2082} 2083 2084 2085/* Verifies that the signature contained in the data set 2086 DATA_SIGNATURE is indeed the result of signing the data contained 2087 in DATA with the secret key belonging to the public key KEY. */ 2088gcry_error_t 2089_gcry_ac_data_verify (gcry_ac_handle_t handle, 2090 gcry_ac_key_t key, 2091 gcry_mpi_t data, 2092 gcry_ac_data_t data_signature) 2093{ 2094 gcry_sexp_t sexp_signature; 2095 gcry_ac_data_t data_value; 2096 gcry_sexp_t sexp_data; 2097 gcry_sexp_t sexp_key; 2098 gcry_error_t err; 2099 2100 if (fips_mode ()) 2101 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2102 2103 sexp_signature = NULL; 2104 data_value = NULL; 2105 sexp_data = NULL; 2106 sexp_key = NULL; 2107 2108 err = ac_data_construct ("public-key", 0, 0, 2109 handle->algorithm_name, key->data, &sexp_key); 2110 if (err) 2111 goto out; 2112 2113 if (key->type != GCRY_AC_KEY_PUBLIC) 2114 { 2115 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 2116 goto out; 2117 } 2118 2119 /* Construct S-expression holding the signature data. */ 2120 err = ac_data_construct ("sig-val", 1, 0, handle->algorithm_name, 2121 data_signature, &sexp_signature); 2122 if (err) 2123 goto out; 2124 2125 err = _gcry_ac_data_new (&data_value); 2126 if (err) 2127 goto out; 2128 2129 err = _gcry_ac_data_set (data_value, 0, "value", data); 2130 if (err) 2131 goto out; 2132 2133 /* Construct S-expression holding the data. */ 2134 err = ac_data_construct ("data", 1, 0, NULL, data_value, &sexp_data); 2135 if (err) 2136 goto out; 2137 2138 /* Verify signature. */ 2139 err = gcry_pk_verify (sexp_signature, sexp_data, sexp_key); 2140 2141 out: 2142 2143 gcry_sexp_release (sexp_signature); 2144 gcry_sexp_release (sexp_data); 2145 gcry_sexp_release (sexp_key); 2146 _gcry_ac_data_destroy (data_value); 2147 2148 return gcry_error (err); 2149} 2150 2151 2152 2153 2154/* 2155 * Implementation of encoding methods (em). 2156 */ 2157 2158/* Type for functions that encode or decode (hence the name) a 2159 message. */ 2160typedef gcry_error_t (*gcry_ac_em_dencode_t) (unsigned int flags, 2161 void *options, 2162 gcry_ac_io_t *ac_io_read, 2163 gcry_ac_io_t *ac_io_write); 2164 2165/* Fill the buffer BUFFER which is BUFFER_N bytes long with non-zero 2166 random bytes of random level LEVEL. */ 2167static void 2168em_randomize_nonzero (unsigned char *buffer, size_t buffer_n, 2169 gcry_random_level_t level) 2170{ 2171 unsigned char *buffer_rand; 2172 unsigned int buffer_rand_n; 2173 unsigned int zeros; 2174 unsigned int i; 2175 unsigned int j; 2176 2177 for (i = 0; i < buffer_n; i++) 2178 buffer[i] = 0; 2179 2180 do 2181 { 2182 /* Count zeros. */ 2183 for (i = zeros = 0; i < buffer_n; i++) 2184 if (! buffer[i]) 2185 zeros++; 2186 2187 if (zeros) 2188 { 2189 /* Get random bytes. */ 2190 buffer_rand_n = zeros + (zeros / 128); 2191 buffer_rand = gcry_random_bytes_secure (buffer_rand_n, level); 2192 2193 /* Substitute zeros with non-zero random bytes. */ 2194 for (i = j = 0; zeros && (i < buffer_n) && (j < buffer_rand_n); i++) 2195 if (! buffer[i]) 2196 { 2197 while ((j < buffer_rand_n) && (! buffer_rand[j])) 2198 j++; 2199 if (j < buffer_rand_n) 2200 { 2201 buffer[i] = buffer_rand[j++]; 2202 zeros--; 2203 } 2204 else 2205 break; 2206 } 2207 gcry_free (buffer_rand); 2208 } 2209 } 2210 while (zeros); 2211} 2212 2213/* Encode a message according to the Encoding Method for Encryption 2214 `PKCS-V1_5' (EME-PKCS-V1_5). */ 2215static gcry_error_t 2216eme_pkcs_v1_5_encode (unsigned int flags, void *opts, 2217 gcry_ac_io_t *ac_io_read, 2218 gcry_ac_io_t *ac_io_write) 2219{ 2220 gcry_ac_eme_pkcs_v1_5_t *options; 2221 gcry_error_t err; 2222 unsigned char *buffer; 2223 unsigned char *ps; 2224 unsigned char *m; 2225 size_t m_n; 2226 unsigned int ps_n; 2227 unsigned int k; 2228 2229 (void)flags; 2230 2231 options = opts; 2232 buffer = NULL; 2233 m = NULL; 2234 2235 err = _gcry_ac_io_read_all (ac_io_read, &m, &m_n); 2236 if (err) 2237 goto out; 2238 2239 /* Figure out key length in bytes. */ 2240 k = options->key_size / 8; 2241 2242 if (m_n > k - 11) 2243 { 2244 /* Key is too short for message. */ 2245 err = gcry_error (GPG_ERR_TOO_SHORT); 2246 goto out; 2247 } 2248 2249 /* According to this encoding method, the first byte of the encoded 2250 message is zero. This byte will be lost anyway, when the encoded 2251 message is to be converted into an MPI, that's why we skip 2252 it. */ 2253 2254 /* Allocate buffer. */ 2255 buffer = gcry_malloc (k - 1); 2256 if (! buffer) 2257 { 2258 err = gcry_error_from_errno (errno); 2259 goto out; 2260 } 2261 2262 /* Generate an octet string PS of length k - mLen - 3 consisting 2263 of pseudorandomly generated nonzero octets. The length of PS 2264 will be at least eight octets. */ 2265 ps_n = k - m_n - 3; 2266 ps = buffer + 1; 2267 em_randomize_nonzero (ps, ps_n, GCRY_STRONG_RANDOM); 2268 2269 /* Concatenate PS, the message M, and other padding to form an 2270 encoded message EM of length k octets as: 2271 2272 EM = 0x00 || 0x02 || PS || 0x00 || M. */ 2273 2274 buffer[0] = 0x02; 2275 buffer[ps_n + 1] = 0x00; 2276 memcpy (buffer + ps_n + 2, m, m_n); 2277 2278 err = _gcry_ac_io_write (ac_io_write, buffer, k - 1); 2279 2280 out: 2281 2282 gcry_free (buffer); 2283 gcry_free (m); 2284 2285 return err; 2286} 2287 2288/* Decode a message according to the Encoding Method for Encryption 2289 `PKCS-V1_5' (EME-PKCS-V1_5). */ 2290static gcry_error_t 2291eme_pkcs_v1_5_decode (unsigned int flags, void *opts, 2292 gcry_ac_io_t *ac_io_read, 2293 gcry_ac_io_t *ac_io_write) 2294{ 2295 gcry_ac_eme_pkcs_v1_5_t *options; 2296 unsigned char *buffer; 2297 unsigned char *em; 2298 size_t em_n; 2299 gcry_error_t err; 2300 unsigned int i; 2301 unsigned int k; 2302 2303 (void)flags; 2304 2305 options = opts; 2306 buffer = NULL; 2307 em = NULL; 2308 2309 err = _gcry_ac_io_read_all (ac_io_read, &em, &em_n); 2310 if (err) 2311 goto out; 2312 2313 /* Figure out key size. */ 2314 k = options->key_size / 8; 2315 2316 /* Search for zero byte. */ 2317 for (i = 0; (i < em_n) && em[i]; i++); 2318 2319 /* According to this encoding method, the first byte of the encoded 2320 message should be zero. This byte is lost. */ 2321 2322 if (! ((em_n >= 10) 2323 && (em_n == (k - 1)) 2324 && (em[0] == 0x02) 2325 && (i < em_n) 2326 && ((i - 1) >= 8))) 2327 { 2328 err = gcry_error (GPG_ERR_DECRYPT_FAILED); 2329 goto out; 2330 } 2331 2332 i++; 2333 buffer = gcry_malloc (em_n - i); 2334 if (! buffer) 2335 { 2336 err = gcry_error_from_errno (errno); 2337 goto out; 2338 } 2339 2340 memcpy (buffer, em + i, em_n - i); 2341 err = _gcry_ac_io_write (ac_io_write, buffer, em_n - i); 2342 2343 out: 2344 2345 gcry_free (buffer); 2346 gcry_free (em); 2347 2348 return err; 2349} 2350 2351static gcry_error_t 2352emsa_pkcs_v1_5_encode_data_cb (void *opaque, 2353 unsigned char *buffer, size_t buffer_n) 2354{ 2355 gcry_md_hd_t md_handle; 2356 2357 md_handle = opaque; 2358 gcry_md_write (md_handle, buffer, buffer_n); 2359 2360 return 0; 2361} 2362 2363 2364/* Encode a message according to the Encoding Method for Signatures 2365 with Appendix `PKCS-V1_5' (EMSA-PKCS-V1_5). */ 2366static gcry_error_t 2367emsa_pkcs_v1_5_encode (unsigned int flags, void *opts, 2368 gcry_ac_io_t *ac_io_read, 2369 gcry_ac_io_t *ac_io_write) 2370{ 2371 gcry_ac_emsa_pkcs_v1_5_t *options; 2372 gcry_error_t err; 2373 gcry_md_hd_t md; 2374 unsigned char *t; 2375 size_t t_n; 2376 unsigned char *h; 2377 size_t h_n; 2378 unsigned char *ps; 2379 size_t ps_n; 2380 unsigned char *buffer; 2381 size_t buffer_n; 2382 unsigned char asn[100]; /* FIXME, always enough? */ 2383 size_t asn_n; 2384 unsigned int i; 2385 2386 (void)flags; 2387 2388 options = opts; 2389 buffer = NULL; 2390 md = NULL; 2391 ps = NULL; 2392 t = NULL; 2393 2394 /* Create hashing handle and get the necessary information. */ 2395 err = gcry_md_open (&md, options->md, 0); 2396 if (err) 2397 goto out; 2398 2399 asn_n = DIM (asn); 2400 err = gcry_md_algo_info (options->md, GCRYCTL_GET_ASNOID, asn, &asn_n); 2401 if (err) 2402 goto out; 2403 2404 h_n = gcry_md_get_algo_dlen (options->md); 2405 2406 err = _gcry_ac_io_process (ac_io_read, emsa_pkcs_v1_5_encode_data_cb, md); 2407 if (err) 2408 goto out; 2409 2410 h = gcry_md_read (md, 0); 2411 2412 /* Encode the algorithm ID for the hash function and the hash value 2413 into an ASN.1 value of type DigestInfo with the Distinguished 2414 Encoding Rules (DER), where the type DigestInfo has the syntax: 2415 2416 DigestInfo ::== SEQUENCE { 2417 digestAlgorithm AlgorithmIdentifier, 2418 digest OCTET STRING 2419 } 2420 2421 The first field identifies the hash function and the second 2422 contains the hash value. Let T be the DER encoding of the 2423 DigestInfo value and let tLen be the length in octets of T. */ 2424 2425 t_n = asn_n + h_n; 2426 t = gcry_malloc (t_n); 2427 if (! t) 2428 { 2429 err = gcry_error_from_errno (errno); 2430 goto out; 2431 } 2432 2433 for (i = 0; i < asn_n; i++) 2434 t[i] = asn[i]; 2435 for (i = 0; i < h_n; i++) 2436 t[asn_n + i] = h[i]; 2437 2438 /* If emLen < tLen + 11, output "intended encoded message length 2439 too short" and stop. */ 2440 if (options->em_n < t_n + 11) 2441 { 2442 err = gcry_error (GPG_ERR_TOO_SHORT); 2443 goto out; 2444 } 2445 2446 /* Generate an octet string PS consisting of emLen - tLen - 3 octets 2447 with hexadecimal value 0xFF. The length of PS will be at least 8 2448 octets. */ 2449 ps_n = options->em_n - t_n - 3; 2450 ps = gcry_malloc (ps_n); 2451 if (! ps) 2452 { 2453 err = gcry_error_from_errno (errno); 2454 goto out; 2455 } 2456 for (i = 0; i < ps_n; i++) 2457 ps[i] = 0xFF; 2458 2459 /* Concatenate PS, the DER encoding T, and other padding to form the 2460 encoded message EM as: 2461 2462 EM = 0x00 || 0x01 || PS || 0x00 || T. */ 2463 2464 buffer_n = ps_n + t_n + 3; 2465 buffer = gcry_malloc (buffer_n); 2466 if (! buffer) 2467 { 2468 err = gcry_error_from_errno (errno); 2469 goto out; 2470 } 2471 2472 buffer[0] = 0x00; 2473 buffer[1] = 0x01; 2474 for (i = 0; i < ps_n; i++) 2475 buffer[2 + i] = ps[i]; 2476 buffer[2 + ps_n] = 0x00; 2477 for (i = 0; i < t_n; i++) 2478 buffer[3 + ps_n + i] = t[i]; 2479 2480 err = _gcry_ac_io_write (ac_io_write, buffer, buffer_n); 2481 2482 out: 2483 2484 gcry_md_close (md); 2485 2486 gcry_free (buffer); 2487 gcry_free (ps); 2488 gcry_free (t); 2489 2490 return err; 2491} 2492 2493/* `Actions' for data_dencode(). */ 2494typedef enum dencode_action 2495 { 2496 DATA_ENCODE, 2497 DATA_DECODE, 2498 } 2499dencode_action_t; 2500 2501/* Encode or decode a message according to the the encoding method 2502 METHOD; ACTION specifies whether the message that is contained in 2503 BUFFER_IN and of length BUFFER_IN_N should be encoded or decoded. 2504 The resulting message will be stored in a newly allocated buffer in 2505 BUFFER_OUT and BUFFER_OUT_N. */ 2506static gcry_error_t 2507ac_data_dencode (gcry_ac_em_t method, dencode_action_t action, 2508 unsigned int flags, void *options, 2509 gcry_ac_io_t *ac_io_read, 2510 gcry_ac_io_t *ac_io_write) 2511{ 2512 struct 2513 { 2514 gcry_ac_em_t method; 2515 gcry_ac_em_dencode_t encode; 2516 gcry_ac_em_dencode_t decode; 2517 } methods[] = 2518 { 2519 { GCRY_AC_EME_PKCS_V1_5, 2520 eme_pkcs_v1_5_encode, eme_pkcs_v1_5_decode }, 2521 { GCRY_AC_EMSA_PKCS_V1_5, 2522 emsa_pkcs_v1_5_encode, NULL }, 2523 }; 2524 size_t methods_n; 2525 gcry_error_t err; 2526 unsigned int i; 2527 2528 methods_n = sizeof (methods) / sizeof (*methods); 2529 2530 for (i = 0; i < methods_n; i++) 2531 if (methods[i].method == method) 2532 break; 2533 if (i == methods_n) 2534 { 2535 err = gcry_error (GPG_ERR_NOT_FOUND); /* FIXME? */ 2536 goto out; 2537 } 2538 2539 err = 0; 2540 switch (action) 2541 { 2542 case DATA_ENCODE: 2543 if (methods[i].encode) 2544 /* FIXME? */ 2545 err = (*methods[i].encode) (flags, options, ac_io_read, ac_io_write); 2546 break; 2547 2548 case DATA_DECODE: 2549 if (methods[i].decode) 2550 /* FIXME? */ 2551 err = (*methods[i].decode) (flags, options, ac_io_read, ac_io_write); 2552 break; 2553 2554 default: 2555 err = gcry_error (GPG_ERR_INV_ARG); 2556 break; 2557 } 2558 2559 out: 2560 2561 return err; 2562} 2563 2564/* Encode a message according to the encoding method METHOD. OPTIONS 2565 must be a pointer to a method-specific structure 2566 (gcry_ac_em*_t). */ 2567gcry_error_t 2568_gcry_ac_data_encode (gcry_ac_em_t method, 2569 unsigned int flags, void *options, 2570 gcry_ac_io_t *ac_io_read, 2571 gcry_ac_io_t *ac_io_write) 2572{ 2573 if (fips_mode ()) 2574 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2575 2576 return ac_data_dencode (method, DATA_ENCODE, flags, options, 2577 ac_io_read, ac_io_write); 2578} 2579 2580/* Dencode a message according to the encoding method METHOD. OPTIONS 2581 must be a pointer to a method-specific structure 2582 (gcry_ac_em*_t). */ 2583gcry_error_t 2584_gcry_ac_data_decode (gcry_ac_em_t method, 2585 unsigned int flags, void *options, 2586 gcry_ac_io_t *ac_io_read, 2587 gcry_ac_io_t *ac_io_write) 2588{ 2589 if (fips_mode ()) 2590 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2591 2592 return ac_data_dencode (method, DATA_DECODE, flags, options, 2593 ac_io_read, ac_io_write); 2594} 2595 2596/* Convert an MPI into an octet string. */ 2597void 2598_gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n) 2599{ 2600 unsigned long digit; 2601 gcry_mpi_t base; 2602 unsigned int i; 2603 unsigned int n; 2604 gcry_mpi_t m; 2605 gcry_mpi_t d; 2606 2607 if (fips_mode ()) 2608 return; 2609 2610 base = gcry_mpi_new (0); 2611 gcry_mpi_set_ui (base, 256); 2612 2613 n = 0; 2614 m = gcry_mpi_copy (mpi); 2615 while (gcry_mpi_cmp_ui (m, 0)) 2616 { 2617 n++; 2618 gcry_mpi_div (m, NULL, m, base, 0); 2619 } 2620 2621 gcry_mpi_set (m, mpi); 2622 d = gcry_mpi_new (0); 2623 for (i = 0; (i < n) && (i < os_n); i++) 2624 { 2625 gcry_mpi_mod (d, m, base); 2626 _gcry_mpi_get_ui (d, &digit); 2627 gcry_mpi_div (m, NULL, m, base, 0); 2628 os[os_n - i - 1] = (digit & 0xFF); 2629 } 2630 2631 for (; i < os_n; i++) 2632 os[os_n - i - 1] = 0; 2633 2634 gcry_mpi_release (base); 2635 gcry_mpi_release (d); 2636 gcry_mpi_release (m); 2637} 2638 2639/* Convert an MPI into an newly allocated octet string. */ 2640gcry_error_t 2641_gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os, size_t *os_n) 2642{ 2643 unsigned char *buffer; 2644 size_t buffer_n; 2645 gcry_error_t err; 2646 unsigned int nbits; 2647 2648 if (fips_mode ()) 2649 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2650 2651 nbits = gcry_mpi_get_nbits (mpi); 2652 buffer_n = (nbits + 7) / 8; 2653 buffer = gcry_malloc (buffer_n); 2654 if (! buffer) 2655 { 2656 err = gcry_error_from_errno (errno); 2657 goto out; 2658 } 2659 2660 _gcry_ac_mpi_to_os (mpi, buffer, buffer_n); 2661 *os = buffer; 2662 *os_n = buffer_n; 2663 err = 0; 2664 2665 out: 2666 2667 return err; 2668} 2669 2670 2671/* Convert an octet string into an MPI. */ 2672void 2673_gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n) 2674{ 2675 unsigned int i; 2676 gcry_mpi_t xi; 2677 gcry_mpi_t x; 2678 gcry_mpi_t a; 2679 2680 if (fips_mode ()) 2681 return; 2682 2683 a = gcry_mpi_new (0); 2684 gcry_mpi_set_ui (a, 1); 2685 x = gcry_mpi_new (0); 2686 gcry_mpi_set_ui (x, 0); 2687 xi = gcry_mpi_new (0); 2688 2689 for (i = 0; i < os_n; i++) 2690 { 2691 gcry_mpi_mul_ui (xi, a, os[os_n - i - 1]); 2692 gcry_mpi_add (x, x, xi); 2693 gcry_mpi_mul_ui (a, a, 256); 2694 } 2695 2696 gcry_mpi_release (xi); 2697 gcry_mpi_release (a); 2698 2699 gcry_mpi_set (mpi, x); 2700 gcry_mpi_release (x); /* FIXME: correct? */ 2701} 2702 2703 2704 2705/* 2706 * Implementation of Encryption Schemes (ES) and Signature Schemes 2707 * with Appendix (SSA). 2708 */ 2709 2710/* Schemes consist of two things: encoding methods and cryptographic 2711 primitives. 2712 2713 Since encoding methods are accessible through a common API with 2714 method-specific options passed as an anonymous struct, schemes have 2715 to provide functions that construct this method-specific structure; 2716 this is what the functions of type `gcry_ac_dencode_prepare_t' are 2717 there for. */ 2718 2719typedef gcry_error_t (*gcry_ac_dencode_prepare_t) (gcry_ac_handle_t handle, 2720 gcry_ac_key_t key, 2721 void *opts, 2722 void *opts_em); 2723 2724/* The `dencode_prepare' function for ES-PKCS-V1_5. */ 2725static gcry_error_t 2726ac_es_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key, 2727 void *opts, void *opts_em) 2728{ 2729 gcry_ac_eme_pkcs_v1_5_t *options_em; 2730 unsigned int nbits; 2731 gcry_error_t err; 2732 2733 (void)opts; 2734 2735 err = _gcry_ac_key_get_nbits (handle, key, &nbits); 2736 if (err) 2737 goto out; 2738 2739 options_em = opts_em; 2740 options_em->key_size = nbits; 2741 2742 out: 2743 2744 return err; 2745} 2746 2747/* The `dencode_prepare' function for SSA-PKCS-V1_5. */ 2748static gcry_error_t 2749ac_ssa_dencode_prepare_pkcs_v1_5 (gcry_ac_handle_t handle, gcry_ac_key_t key, 2750 void *opts, void *opts_em) 2751{ 2752 gcry_ac_emsa_pkcs_v1_5_t *options_em; 2753 gcry_ac_ssa_pkcs_v1_5_t *options; 2754 gcry_error_t err; 2755 unsigned int k; 2756 2757 options_em = opts_em; 2758 options = opts; 2759 2760 err = _gcry_ac_key_get_nbits (handle, key, &k); 2761 if (err) 2762 goto out; 2763 2764 k = (k + 7) / 8; 2765 options_em->md = options->md; 2766 options_em->em_n = k; 2767 2768 out: 2769 2770 return err; 2771} 2772 2773/* Type holding the information about each supported 2774 Encryption/Signature Scheme. */ 2775typedef struct ac_scheme 2776{ 2777 gcry_ac_scheme_t scheme; 2778 gcry_ac_em_t scheme_encoding; 2779 gcry_ac_dencode_prepare_t dencode_prepare; 2780 size_t options_em_n; 2781} ac_scheme_t; 2782 2783/* List of supported Schemes. */ 2784static ac_scheme_t ac_schemes[] = 2785 { 2786 { GCRY_AC_ES_PKCS_V1_5, GCRY_AC_EME_PKCS_V1_5, 2787 ac_es_dencode_prepare_pkcs_v1_5, 2788 sizeof (gcry_ac_eme_pkcs_v1_5_t) }, 2789 { GCRY_AC_SSA_PKCS_V1_5, GCRY_AC_EMSA_PKCS_V1_5, 2790 ac_ssa_dencode_prepare_pkcs_v1_5, 2791 sizeof (gcry_ac_emsa_pkcs_v1_5_t) } 2792 }; 2793 2794/* Lookup a scheme by it's ID. */ 2795static ac_scheme_t * 2796ac_scheme_get (gcry_ac_scheme_t scheme) 2797{ 2798 ac_scheme_t *ac_scheme; 2799 unsigned int i; 2800 2801 for (i = 0; i < DIM (ac_schemes); i++) 2802 if (scheme == ac_schemes[i].scheme) 2803 break; 2804 if (i == DIM (ac_schemes)) 2805 ac_scheme = NULL; 2806 else 2807 ac_scheme = ac_schemes + i; 2808 2809 return ac_scheme; 2810} 2811 2812/* Prepares the encoding/decoding by creating an according option 2813 structure. */ 2814static gcry_error_t 2815ac_dencode_prepare (gcry_ac_handle_t handle, gcry_ac_key_t key, void *opts, 2816 ac_scheme_t scheme, void **opts_em) 2817{ 2818 gcry_error_t err; 2819 void *options_em; 2820 2821 options_em = gcry_malloc (scheme.options_em_n); 2822 if (! options_em) 2823 { 2824 err = gcry_error_from_errno (errno); 2825 goto out; 2826 } 2827 2828 err = (*scheme.dencode_prepare) (handle, key, opts, options_em); 2829 if (err) 2830 goto out; 2831 2832 *opts_em = options_em; 2833 2834 out: 2835 2836 if (err) 2837 free (options_em); 2838 2839 return err; 2840} 2841 2842/* Convert a data set into a single MPI; currently, this is only 2843 supported for data sets containing a single MPI. */ 2844static gcry_error_t 2845ac_data_set_to_mpi (gcry_ac_data_t data, gcry_mpi_t *mpi) 2846{ 2847 gcry_error_t err; 2848 gcry_mpi_t mpi_new; 2849 unsigned int elems; 2850 2851 elems = _gcry_ac_data_length (data); 2852 2853 if (elems != 1) 2854 { 2855 /* FIXME: I guess, we should be more flexible in this respect by 2856 allowing the actual encryption/signature schemes to implement 2857 this conversion mechanism. */ 2858 err = gcry_error (GPG_ERR_CONFLICT); 2859 goto out; 2860 } 2861 2862 err = _gcry_ac_data_get_index (data, GCRY_AC_FLAG_COPY, 0, NULL, &mpi_new); 2863 if (err) 2864 goto out; 2865 2866 *mpi = mpi_new; 2867 2868 out: 2869 2870 return err; 2871} 2872 2873/* Encrypts the plain text message contained in M, which is of size 2874 M_N, with the public key KEY_PUBLIC according to the Encryption 2875 Scheme SCHEME_ID. HANDLE is used for accessing the low-level 2876 cryptographic primitives. If OPTS is not NULL, it has to be an 2877 anonymous structure specific to the chosen scheme (gcry_ac_es_*_t). 2878 The encrypted message will be stored in C and C_N. */ 2879gcry_error_t 2880_gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle, 2881 gcry_ac_scheme_t scheme_id, 2882 unsigned int flags, void *opts, 2883 gcry_ac_key_t key, 2884 gcry_ac_io_t *io_message, 2885 gcry_ac_io_t *io_cipher) 2886{ 2887 gcry_error_t err; 2888 gcry_ac_io_t io_em; 2889 unsigned char *em; 2890 size_t em_n; 2891 gcry_mpi_t mpi_plain; 2892 gcry_ac_data_t data_encrypted; 2893 gcry_mpi_t mpi_encrypted; 2894 unsigned char *buffer; 2895 size_t buffer_n; 2896 void *opts_em; 2897 ac_scheme_t *scheme; 2898 2899 (void)flags; 2900 2901 if (fips_mode ()) 2902 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2903 2904 data_encrypted = NULL; 2905 mpi_encrypted = NULL; 2906 mpi_plain = NULL; 2907 opts_em = NULL; 2908 buffer = NULL; 2909 em = NULL; 2910 2911 scheme = ac_scheme_get (scheme_id); 2912 if (! scheme) 2913 { 2914 err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME); 2915 goto out; 2916 } 2917 2918 if (key->type != GCRY_AC_KEY_PUBLIC) 2919 { 2920 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 2921 goto out; 2922 } 2923 2924 err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em); 2925 if (err) 2926 goto out; 2927 2928 _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE, 2929 GCRY_AC_IO_STRING, &em, &em_n); 2930 2931 err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em, 2932 io_message, &io_em); 2933 if (err) 2934 goto out; 2935 2936 mpi_plain = gcry_mpi_snew (0); 2937 gcry_ac_os_to_mpi (mpi_plain, em, em_n); 2938 2939 err = _gcry_ac_data_encrypt (handle, 0, key, mpi_plain, &data_encrypted); 2940 if (err) 2941 goto out; 2942 2943 err = ac_data_set_to_mpi (data_encrypted, &mpi_encrypted); 2944 if (err) 2945 goto out; 2946 2947 err = _gcry_ac_mpi_to_os_alloc (mpi_encrypted, &buffer, &buffer_n); 2948 if (err) 2949 goto out; 2950 2951 err = _gcry_ac_io_write (io_cipher, buffer, buffer_n); 2952 2953 out: 2954 2955 gcry_ac_data_destroy (data_encrypted); 2956 gcry_mpi_release (mpi_encrypted); 2957 gcry_mpi_release (mpi_plain); 2958 gcry_free (opts_em); 2959 gcry_free (buffer); 2960 gcry_free (em); 2961 2962 return err; 2963} 2964 2965/* Decryptes the cipher message contained in C, which is of size C_N, 2966 with the secret key KEY_SECRET according to the Encryption Scheme 2967 SCHEME_ID. Handle is used for accessing the low-level 2968 cryptographic primitives. If OPTS is not NULL, it has to be an 2969 anonymous structure specific to the chosen scheme (gcry_ac_es_*_t). 2970 The decrypted message will be stored in M and M_N. */ 2971gcry_error_t 2972_gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle, 2973 gcry_ac_scheme_t scheme_id, 2974 unsigned int flags, void *opts, 2975 gcry_ac_key_t key, 2976 gcry_ac_io_t *io_cipher, 2977 gcry_ac_io_t *io_message) 2978{ 2979 gcry_ac_io_t io_em; 2980 gcry_error_t err; 2981 gcry_ac_data_t data_encrypted; 2982 unsigned char *em; 2983 size_t em_n; 2984 gcry_mpi_t mpi_encrypted; 2985 gcry_mpi_t mpi_decrypted; 2986 void *opts_em; 2987 ac_scheme_t *scheme; 2988 char *elements_enc; 2989 size_t elements_enc_n; 2990 unsigned char *c; 2991 size_t c_n; 2992 2993 (void)flags; 2994 2995 if (fips_mode ()) 2996 return gpg_error (GPG_ERR_NOT_SUPPORTED); 2997 2998 data_encrypted = NULL; 2999 mpi_encrypted = NULL; 3000 mpi_decrypted = NULL; 3001 elements_enc = NULL; 3002 opts_em = NULL; 3003 em = NULL; 3004 c = NULL; 3005 3006 scheme = ac_scheme_get (scheme_id); 3007 if (! scheme) 3008 { 3009 err = gcry_error (GPG_ERR_NO_ENCRYPTION_SCHEME); 3010 goto out; 3011 } 3012 3013 if (key->type != GCRY_AC_KEY_SECRET) 3014 { 3015 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 3016 goto out; 3017 } 3018 3019 err = _gcry_ac_io_read_all (io_cipher, &c, &c_n); 3020 if (err) 3021 goto out; 3022 3023 mpi_encrypted = gcry_mpi_snew (0); 3024 gcry_ac_os_to_mpi (mpi_encrypted, c, c_n); 3025 3026 err = _gcry_pk_get_elements (handle->algorithm, &elements_enc, NULL); 3027 if (err) 3028 goto out; 3029 3030 elements_enc_n = strlen (elements_enc); 3031 if (elements_enc_n != 1) 3032 { 3033 /* FIXME? */ 3034 err = gcry_error (GPG_ERR_CONFLICT); 3035 goto out; 3036 } 3037 3038 err = _gcry_ac_data_new (&data_encrypted); 3039 if (err) 3040 goto out; 3041 3042 err = _gcry_ac_data_set (data_encrypted, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC, 3043 elements_enc, mpi_encrypted); 3044 if (err) 3045 goto out; 3046 3047 err = _gcry_ac_data_decrypt (handle, 0, key, &mpi_decrypted, data_encrypted); 3048 if (err) 3049 goto out; 3050 3051 err = _gcry_ac_mpi_to_os_alloc (mpi_decrypted, &em, &em_n); 3052 if (err) 3053 goto out; 3054 3055 err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em); 3056 if (err) 3057 goto out; 3058 3059 _gcry_ac_io_init (&io_em, GCRY_AC_IO_READABLE, 3060 GCRY_AC_IO_STRING, em, em_n); 3061 3062 err = _gcry_ac_data_decode (scheme->scheme_encoding, 0, opts_em, 3063 &io_em, io_message); 3064 if (err) 3065 goto out; 3066 3067 out: 3068 3069 _gcry_ac_data_destroy (data_encrypted); 3070 gcry_mpi_release (mpi_encrypted); 3071 gcry_mpi_release (mpi_decrypted); 3072 free (elements_enc); 3073 gcry_free (opts_em); 3074 gcry_free (em); 3075 gcry_free (c); 3076 3077 return err; 3078} 3079 3080 3081/* Signs the message contained in M, which is of size M_N, with the 3082 secret key KEY according to the Signature Scheme SCHEME_ID. Handle 3083 is used for accessing the low-level cryptographic primitives. If 3084 OPTS is not NULL, it has to be an anonymous structure specific to 3085 the chosen scheme (gcry_ac_ssa_*_t). The signed message will be 3086 stored in S and S_N. */ 3087gcry_error_t 3088_gcry_ac_data_sign_scheme (gcry_ac_handle_t handle, 3089 gcry_ac_scheme_t scheme_id, 3090 unsigned int flags, void *opts, 3091 gcry_ac_key_t key, 3092 gcry_ac_io_t *io_message, 3093 gcry_ac_io_t *io_signature) 3094{ 3095 gcry_ac_io_t io_em; 3096 gcry_error_t err; 3097 gcry_ac_data_t data_signed; 3098 unsigned char *em; 3099 size_t em_n; 3100 gcry_mpi_t mpi; 3101 void *opts_em; 3102 unsigned char *buffer; 3103 size_t buffer_n; 3104 gcry_mpi_t mpi_signed; 3105 ac_scheme_t *scheme; 3106 3107 (void)flags; 3108 3109 if (fips_mode ()) 3110 return gpg_error (GPG_ERR_NOT_SUPPORTED); 3111 3112 data_signed = NULL; 3113 mpi_signed = NULL; 3114 opts_em = NULL; 3115 buffer = NULL; 3116 mpi = NULL; 3117 em = NULL; 3118 3119 if (key->type != GCRY_AC_KEY_SECRET) 3120 { 3121 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 3122 goto out; 3123 } 3124 3125 scheme = ac_scheme_get (scheme_id); 3126 if (! scheme) 3127 { 3128 /* FIXME: adjust api of scheme_get in respect to err codes. */ 3129 err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME); 3130 goto out; 3131 } 3132 3133 err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em); 3134 if (err) 3135 goto out; 3136 3137 _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE, 3138 GCRY_AC_IO_STRING, &em, &em_n); 3139 3140 err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em, 3141 io_message, &io_em); 3142 if (err) 3143 goto out; 3144 3145 mpi = gcry_mpi_new (0); 3146 _gcry_ac_os_to_mpi (mpi, em, em_n); 3147 3148 err = _gcry_ac_data_sign (handle, key, mpi, &data_signed); 3149 if (err) 3150 goto out; 3151 3152 err = ac_data_set_to_mpi (data_signed, &mpi_signed); 3153 if (err) 3154 goto out; 3155 3156 err = _gcry_ac_mpi_to_os_alloc (mpi_signed, &buffer, &buffer_n); 3157 if (err) 3158 goto out; 3159 3160 err = _gcry_ac_io_write (io_signature, buffer, buffer_n); 3161 3162 out: 3163 3164 _gcry_ac_data_destroy (data_signed); 3165 gcry_mpi_release (mpi_signed); 3166 gcry_mpi_release (mpi); 3167 gcry_free (opts_em); 3168 gcry_free (buffer); 3169 gcry_free (em); 3170 3171 return err; 3172} 3173 3174/* Verifies that the signature contained in S, which is of length S_N, 3175 is indeed the result of signing the message contained in M, which 3176 is of size M_N, with the secret key belonging to the public key 3177 KEY_PUBLIC. If OPTS is not NULL, it has to be an anonymous 3178 structure (gcry_ac_ssa_*_t) specific to the Signature Scheme, whose 3179 ID is contained in SCHEME_ID. */ 3180gcry_error_t 3181_gcry_ac_data_verify_scheme (gcry_ac_handle_t handle, 3182 gcry_ac_scheme_t scheme_id, 3183 unsigned int flags, void *opts, 3184 gcry_ac_key_t key, 3185 gcry_ac_io_t *io_message, 3186 gcry_ac_io_t *io_signature) 3187{ 3188 gcry_ac_io_t io_em; 3189 gcry_error_t err; 3190 gcry_ac_data_t data_signed; 3191 unsigned char *em; 3192 size_t em_n; 3193 void *opts_em; 3194 gcry_mpi_t mpi_signature; 3195 gcry_mpi_t mpi_data; 3196 ac_scheme_t *scheme; 3197 char *elements_sig; 3198 size_t elements_sig_n; 3199 unsigned char *s; 3200 size_t s_n; 3201 3202 (void)flags; 3203 3204 if (fips_mode ()) 3205 return gpg_error (GPG_ERR_NOT_SUPPORTED); 3206 3207 mpi_signature = NULL; 3208 elements_sig = NULL; 3209 data_signed = NULL; 3210 mpi_data = NULL; 3211 opts_em = NULL; 3212 em = NULL; 3213 s = NULL; 3214 3215 if (key->type != GCRY_AC_KEY_PUBLIC) 3216 { 3217 err = gcry_error (GPG_ERR_WRONG_KEY_USAGE); 3218 goto out; 3219 } 3220 3221 scheme = ac_scheme_get (scheme_id); 3222 if (! scheme) 3223 { 3224 err = gcry_error (GPG_ERR_NO_SIGNATURE_SCHEME); 3225 goto out; 3226 } 3227 3228 err = ac_dencode_prepare (handle, key, opts, *scheme, &opts_em); 3229 if (err) 3230 goto out; 3231 3232 _gcry_ac_io_init (&io_em, GCRY_AC_IO_WRITABLE, 3233 GCRY_AC_IO_STRING, &em, &em_n); 3234 3235 err = _gcry_ac_data_encode (scheme->scheme_encoding, 0, opts_em, 3236 io_message, &io_em); 3237 if (err) 3238 goto out; 3239 3240 mpi_data = gcry_mpi_new (0); 3241 _gcry_ac_os_to_mpi (mpi_data, em, em_n); 3242 3243 err = _gcry_ac_io_read_all (io_signature, &s, &s_n); 3244 if (err) 3245 goto out; 3246 3247 mpi_signature = gcry_mpi_new (0); 3248 _gcry_ac_os_to_mpi (mpi_signature, s, s_n); 3249 3250 err = _gcry_pk_get_elements (handle->algorithm, NULL, &elements_sig); 3251 if (err) 3252 goto out; 3253 3254 elements_sig_n = strlen (elements_sig); 3255 if (elements_sig_n != 1) 3256 { 3257 /* FIXME? */ 3258 err = gcry_error (GPG_ERR_CONFLICT); 3259 goto out; 3260 } 3261 3262 err = _gcry_ac_data_new (&data_signed); 3263 if (err) 3264 goto out; 3265 3266 err = _gcry_ac_data_set (data_signed, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC, 3267 elements_sig, mpi_signature); 3268 if (err) 3269 goto out; 3270 3271 gcry_mpi_release (mpi_signature); 3272 mpi_signature = NULL; 3273 3274 err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed); 3275 3276 out: 3277 3278 _gcry_ac_data_destroy (data_signed); 3279 gcry_mpi_release (mpi_signature); 3280 gcry_mpi_release (mpi_data); 3281 free (elements_sig); 3282 gcry_free (opts_em); 3283 gcry_free (em); 3284 gcry_free (s); 3285 3286 return err; 3287} 3288 3289 3290/* 3291 * General functions. 3292 */ 3293 3294gcry_err_code_t 3295_gcry_ac_init (void) 3296{ 3297 if (fips_mode ()) 3298 return GPG_ERR_NOT_SUPPORTED; 3299 3300 return 0; 3301} 3302