diff options
Diffstat (limited to 'plugins/MirOTR/libgcrypt-1.4.6/tests')
28 files changed, 15308 insertions, 0 deletions
diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/ChangeLog b/plugins/MirOTR/libgcrypt-1.4.6/tests/ChangeLog new file mode 100644 index 0000000000..e906aacf7a --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/ChangeLog @@ -0,0 +1,770 @@ +2010-07-13 Werner Koch <wk@g10code.com> + + * aeswrap.c: New. Take from trunk. + +2010-07-09 Werner Koch <wk@g10code.com> + + * basic.c (check_digests): Add tests for TIGER1 and TIGER2 from + the NESSIE project. + +2010-06-10 Werner Koch <wk@g10code.com> + + * t-mpi-bit.c (mpi2bitstr_nlz): Handle case for LENGTH==0. + +2009-01-22 Werner Koch <wk@g10code.com> + + * cavs_tests.sh: Pass option -D to driver if required. + + * fipsdrv.c (run_dsa_sign): Use hash of the data. + (dsa_gen_with_seed): New. + (run_dsa_pqg_gen): Add args SEED and SEEDLEN and use them. + (main): Optically take a seed for dsa-pgq-gen. + (standalone_mode): New. + (main): Add option --standalone. + (print_dsa_domain_parameters): Implement standalone mode. + +2009-01-21 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_dsa_verify): Use gcry_mpi_scan again. + (run_rsa_derive): Also print N. + + * fipsdrv.c (run_dsa_verify): Use hash of the data. + + * pubkey.c (get_dsa_key_fips186_with_seed_new): New. + (check_run): Call it. + +2008-12-11 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_rsa_derive): New. + (main): Add mode rsa-derive. + +2008-12-10 Werner Koch <wk@g10code.com> + + * basic.c (main): Check for error after running self-test in + non-fips mode. + + * pubkey.c (get_dsa_key_with_domain_new): New. + (get_dsa_key_fips186_with_domain_new): New. + (check_run): Call them. + +2008-12-08 Werner Koch <wk@g10code.com> + + * fipsdrv.c [W32]: Include fcntl.h. + +2008-12-05 Werner Koch <wk@g10code.com> + + * pubkey.c (get_dsa_key_new): Add arg transient_key. + (check_run): Use it. + +2008-12-03 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_dsa_pqg_gen): Facor code out into .. + (print_dsa_domain_parameters, dsa_gen): .. these two new functions. + (print_sexp, read_sexp_from_file): New. + (run_dsa_sign): New. + (run_dsa_verify): New. + +2008-12-02 Werner Koch <wk@g10code.com> + + * fipsdrv.c: All standalone build. + + * mpitests.c (mpi_powm): New. + +2008-11-28 Werner Koch <wk@g10code.com> + + * fips186-dsa.c: New. + + * fipsdrv.c (print_mpi_line, print_data_line): New. + (run_dsa_pqg_gen): New. + (usage): Add mode dsa-pqg-gen. + +2008-11-25 Werner Koch <wk@g10code.com> + + * pubkey.c (get_dsa_key_new): New. + +2008-11-24 Werner Koch <wk@g10code.com> + + * tsexp.c (basic): Add test for format character S. + + * pubkey.c (check_x931_derived_key): New. + (get_keys_x931_new): New. + (check_run): Check X9.31 generated RSA key. + +2008-11-07 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_cipher_mct_loop, get_current_iv): New. + (read_textline, read_hexline, skip_to_empty_line): New. + (main): New option --mct-server. + * cavs_driver.pl: Update from upstream and adjust to new fipsdrv. + +2008-11-05 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_encrypt_decrypt): Disable weak key detection. + +2008-10-31 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_rsa_sign): Buffer needs to be larger for SHA512. + +2008-10-27 Werner Koch <wk@g10code.com> + + * fipsdrv.c (run_encrypt_decrypt): Make IV_BUFFER optional. + (main): Ditto. + * cavs_driver.pl: Remove the --no-fips flags. + (libgcrypt_encdec($$$$$)): Make IV optional. + (libgcrypt_state_cipher($$$$$)): Ditto. + +2008-10-24 Werner Koch <wk@g10code.com> + + * benchmark.c (md_bench): Do not test MD5 in fips mode. + * basic.c (check_digests, check_hmac): Ditto. + +2008-10-06 Werner Koch <wk@g10code.com> + + * cavs_driver.pl: New version from upstream. + (libgcrypt_rsa_verify($$$$)): Pass pkcs1. + (libgcrypt_rsa_sign($$$)): Pass pkcs1 and hash algo. + + * fipsdrv.c (run_rsa_sign): Hash data in pkcs1 mode. + (run_rsa_verify): Ditto. + (read_key_file): Rename to read_private_key_file. Factor public + key code out to.. + (read_public_key_file): .. new. + +2008-10-02 Werner Koch <wk@g10code.com> + + * fipsdrv.c (print_buffer): Add base64 printing code. + (base64_decode, read_key_file, parse_tag, read_sig_file): New. + (run_rsa_gen, run_rsa_sign): New. + (main): Add modes rsa-gen, rsa-sign and rsa-verify. + + +2008-09-29 Werner Koch <wk@g10code.com> + + * fipsdrv.c: Merge code from fipsrngdrv.c + * fipsrngdrv.c: Remove. + +2008-09-26 Werner Koch <wk@g10code.com> + + * Makefile.am: Distribute cavs_driver.pl. + * cavs_tests.sh: New. + * fipsdrv.c: New. + +2008-09-18 Werner Koch <wk@g10code.com> + + * benchmark.c (main): Do not disable secure memory in FIPS mode. + +2008-09-18 Werner Koch <wk@g10code.com> + + * basic.c (main): Do not disable secure memory in FIPS mode. + +2008-09-16 Werner Koch <wk@g10code.com> + + * fipsrngdrv.c (main): Bail out on write error. Implement verbose + option. + (main): Use flag to disable dup block checks. + +2008-09-15 Werner Koch <wk@g10code.com> + + * fipsrngdrv.c: New. + +2008-09-09 Werner Koch <wk@g10code.com> + + * basic.c (main): New option --selftest. + +2008-08-29 Werner Koch <wk@g10code.com> + + * keygrip.c: Update to also check ECDSA. + +2008-08-28 Werner Koch <wk@g10code.com> + + * rsa-16k.key: New sample key. + +2008-08-27 Werner Koch <wk@g10code.com> + + * pkbench.c (read_file): New. + (process_key_pair_file): Replace mmap by read_file. + (main): Add a --fips option. + * Makefile.am (EXTRA_DIST): Remove. + (EXTRA_PROGRAMS): Add pkbench. + + * basic.c (main): Extended FIPS self-test test. + +2008-08-26 Werner Koch <wk@g10code.com> + + * basic.c (get_keys_new): Use transient-key flag. + * benchmark.c (main): First check options then do the libgcrypt + initialization. + (rsa_bench): Use transient-key flag if not in fips mode. + +2008-08-20 Werner Koch <wk@g10code.com> + + * t-mpi-bit.c (test_lshift): New. + (mpi2bitstr_nlz, lshiftbitstring): New. + (main): Run test. + +2008-08-18 Werner Koch <wk@g10code.com> + + * basic.c (main): Add option --fips. + +2008-08-15 Werner Koch <wk@g10code.com> + + * register.c (main): Check for fips mode. + (check_run): Take care of fips mode. + + * basic.c (check_cbc_mac_cipher, check_ciphers, check_digests) + (check_hmac, check_pubkey): Do not test unavalaible algorithms in + fips mode. + (main): Check for fips mode. + +2008-04-22 Werner Koch <wk@g10code.com> + + * basic.c (check_one_cipher): Also check in-place encryption. + +2008-03-17 Werner Koch <wk@g10code.com> + + * benchmark.c (main): Add option --cipher-repetition. + (cipher_bench): Use it. + +2008-03-12 Werner Koch <wk@g10code.com> + + * benchmark.c (rsa_bench): Add arg NO_BLINDING. + (main): Add option --no-blinding. + +2007-12-05 Werner Koch <wk@g10code.com> + + * pubkey.c (sample_private_key_1_1,sample_private_key_1_2): New. + (get_keys_sample): Add arg SECRET_VARIANT. + (check_run): Check all variants. Also check gcry_pk_testkey. + (check_keys_crypt): Add DECRYPT_FAIL_CODE. + (check_keys): Ditto. + +2007-11-30 Werner Koch <wk@g10code.com> + + * benchmark.c (main): Add optione --verbose and reworked the + option parsing. + (random_bench): Dump random stats. + +2007-10-31 Werner Koch <wk@g10code.com> + + * benchmark.c (start_timer, stop_timer, elapsed_time) [W32]: Fixed. + +2007-06-20 Werner Koch <wk@g10code.com> + + * benchmark.c (rsa_bench): New. + (main): New command "rsa". + +2007-05-03 Werner Koch <wk@g10code.com> + + * Makefile.am (EXTRA_DIST): Do not build pkbench.c + +2007-05-02 David Shaw <dshaw@jabberwocky.com> + + * basic.c (check_ciphers): Add Camellia. + +2007-04-30 David Shaw <dshaw@jabberwocky.com> + + * basic.c (check_ciphers): #if out ciphers we don't have. Add + test for GCRY_CIPHER_RFC2268_40. + +2007-04-30 Werner Koch <wk@g10code.com> + + * version.c: New. + * Makefile.am (TESTS): Add version. + +2007-04-30 Marcus Brinkmann <marcus@g10code.de> + + * benchmark.c (ecc_bench): Release KEY_SPEC. + +2007-04-28 Marcus Brinkmann <marcus@g10code.de> + + * ac-data.c (check_run): Don't give redundant GCRY_AC_FLAG_DEALLOC + in addition to GCRY_AC_FLAG_COPY. Don't release LABEL1 or MPI0, + as those are donated to libgcrypt, but do release MPI0 and MPI2. + +2007-04-12 Marcus Brinkmann <marcus@g10code.de> + + * ac-schemes.c (scheme_spec): Revert last change. + + * ac-schemes.c (scheme_spec): Remove const qualifier from member M. + (es_check): Remove const qualifier from C and M2. + +2007-03-28 Werner Koch <wk@g10code.com> + + * pkbench.c (generate_key): Support named curves. + + * benchmark.c (dsa_bench): New args ITERATIONS and PRINT_HEADER. + (main): Call dsa and ecc benchs. + (show_sexp): New. + + * Makefile.am (TESTS): Move pkbench to EXTRA_PROGRAMS. + +2007-03-22 Werner Koch <wk@g10code.com> + + * benchmark.c (die): New. + (ecc_bench): New. + + * pkbench.c (main): Reworked to provide proper option handling. + +2007-03-13 Werner Koch <wk@g10code.com> + + * mpitests.c: Reformatted to GNU standards. + (main): Add options --verbose and --debug for future use. + +2007-03-13 Werner Dittmann <Werner.Dittmann@t-online.de> (wk) + + * mpitests.c: New. + +2007-02-23 Werner Koch <wk@g10code.com> + + * Makefile.am (TEST): Run benchmark as last. + + * ac-data.c (check_sexp_conversion): Print label only in verbose + mode. + + * pubkey.c (main): Run test just 2 times instead of 10. + (get_elg_key_new): New. + (check_run): Also run tests with Elgamal keys. + (check_keys): New arg NBITS_DATA. + (get_elg_key_new): Use only 400 for the 512 bit Elgamal test. + + * random.c: New. + +2007-02-22 Werner Koch <wk@g10code.com> + + * basic.c (check_pubkey_sign): Also try signing using an OID. + + * Makefile.am (TESTS) [W32]: Removed pkbench for now. + * pkbench.c (benchmark): Fixed for W32. + +2007-02-21 Werner Koch <wk@g10code.com> + + * hmac.c (check_one_mac): Make pointer args const. + * basic.c (check_one_md): Ditto. + (check_one_hmac): Ditto. + + * keygen.c (progress_cb): Filter out line feeds. + * basic.c (progress_handler): Ditto. + +2006-12-18 Werner Koch <wk@g10code.com> + + * Makefile.am (AM_CFLAGS, AM_CPPFLAGS): Splitted and merged with + Moritz' changes. + (INCLUDES): Removed. + + * keygen.c (progress_handler): New. + (main): Use it in verbose mode. + +2006-11-05 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (AM_CFLAGS): Added -I$(top_builddir)/src so that the + new gcrypt.h is used, not the one installed in the system. + +2006-10-17 Werner Koch <wk@g10code.com> + + * keygen.c (check_rsa_keys): Also create an 1536 bit DSA key. + +2006-08-03 Werner Koch <wk@g10code.com> + + * t-mpi-bit.c: New. + +2006-07-06 Werner Koch <wk@g10code.com> + + * benchmark.c (main): New option --use-random-daemon. New command + strongrandom. + (random_bench): New arg VERY_STRONG. + +2006-03-14 Werner Koch <wk@g10code.com> + + * benchmark.c (main): Allow for seed file argument to random bench. + + * basic.c (main): Use progress handler only in verbose mode. + (main): Speed up test key generation. + * ac-data.c (check_sexp_conversion, check_run): Take care of VERBOSE. + * ac.c (main): Ditto. + * pubkey.c (main): Ditto. + * pkbench.c (main): Ditto. + * keygen.c (main): Ditto. + (check_rsa_keys): Print key only in verbose mode. + +2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2006-02-18) + + * basic.c (check_one_hmac, check_hmac): New. + +2006-03-07 Werner Koch <wk@g10code.com> + + * benchmark.c (cipher_bench): Add OFB mode. + +2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07) + + * basic.c: Added test cases for OFB and CFB modes. Fixed some + compiler warnings for signedness. + +2005-11-12 Moritz Schulte <moritz@g10code.com> + + * ac-data.c: Added way more test cases. + +2005-09-15 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added keygrip. + * keygrip.c: New. + +2005-09-19 Werner Koch <wk@g10code.com> + + * benchmark.c (dsa_bench): New. + +2005-08-19 Werner Koch <wk@g10code.com> + + * hmac.c (main): Added all FIPS tests. + +2005-08-18 Werner Koch <wk@g10code.com> + + * hmac.c: New. + +2005-04-22 Moritz Schulte <moritz@g10code.com> + + * tsexp.c: Include <config.h> in case HAVE_CONFIG_H is defined; + thanks to Albert Chin. + * testapi.c: Likewise. + * register.c: Likewise. + * pubkey.c: Likewise. + * prime.c: Likewise. + * pkbench.c: Likewise. + * keygen.c: Likewise. + * benchmark.c: Likewise. + * basic.c: Likewise. + * ac-schemes.c: Likewise. + * ac-data.c: Likewise. + * ac.c: Likewise. + +2005-04-16 Moritz Schulte <moritz@g10code.com> + + * ac-data.c (check_run): Include new test. + +2005-04-11 Moritz Schulte <moritz@g10code.com> + + * basic.c (check_digests): Add tests for Whirlpool. + +2005-03-30 Moritz Schulte <moritz@g10code.com> + + * ac-schemes.c: New file. + * ac-data.c: New file. + * Makefile.am (TESTS): Added ac-schemes and ac-data. + +2004-09-15 Moritz Schulte <moritz@g10code.com> + + * pkbench.c: Include <time.h>. + +2004-08-24 Moritz Schulte <moritz@g10code.com> + + * pkbench.c (context_init): Improve generation of test data. + +2004-08-23 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added: pkbench. + * pkbench.c: New file. + +2004-02-25 Werner Koch <wk@gnupg.org> + + * Makefile.am (TEST): Add benchmark. + + * benchmark.c (md_bench, cipher_bench): Allow NULL arg to to run + tests for all algorithms. + (main): Run all tests by default. + +2004-02-03 Werner Koch <wk@gnupg.org> + + * tsexp.c (basic): New pass to check secure memory switching. + +2004-01-12 Moritz Schulte <mo@g10code.com> + + * ac.c (check_one): Adjust to new ac API. + +2003-11-22 Werner Koch <wk@gnupg.org> + + * pubkey.c (check_keys_crypt): Fixed my last patch. + +2003-11-11 Werner Koch <wk@gnupg.org> + + * tsexp.c (basic): Add pass structure and a test for the %b + format. + +2003-11-04 Werner Koch <wk@gnupg.org> + + * Makefile.am (noinst_PROGRAMS): Use this so that test programs + get always build. + + * keygen.c (check_nonce): New. + (main): Add a basic check for the nocen function. + +2003-10-31 Werner Koch <wk@gnupg.org> + + * basic.c (check_aes128_cbc_cts_cipher): Make it a prototype + + * ac.c (check_run): Comment unused variable. + +2003-10-10 Werner Koch <wk@gnupg.org> + + * prime.c (check_primes): Generate a generator and avoid printing + unless in verbose mode. + +2003-10-07 Werner Koch <wk@gnupg.org> + + * tsexp.c (check_sscan): New. + +2003-09-04 Werner Koch <wk@gnupg.org> + + * pubkey.c (check_keys_crypt): Fix for compatibility mode. + +2003-09-02 Moritz Schulte <mo@g10code.com> + + * Makefile.am (TESTS): Added: prime. + + * prime.c: New file. + +2003-08-27 Moritz Schulte <mo@g10code.com> + + * basic.c (check_ciphers): Added: Serpent. + Write braces around flags. + +2003-08-04 Moritz Schulte <moritz@g10code.com> + + * benchmark.c (do_powm): Adjust for new gcry_mpi_scan interface. + +2003-07-23 Moritz Schulte <moritz@g10code.com> + + * ac.c (key_copy): New function... + (check_one): ... use it. + +2003-07-22 Moritz Schulte <moritz@g10code.com> + + * basic.c (check_ciphers): Use gcry_cipher_map_name. + +2003-07-18 Moritz Schulte <moritz@g10code.com> + + * ac.c (check_run): Renamed to ... + (check_one): ... this, changed calling interface. + (check_run): New function. + + * register.c: Adjust gcry_cipher_spec_t structure. + +2003-07-14 Moritz Schulte <moritz@g10code.com> + + * register.c: Adjust cipher specification structure. + + * benchmark.c: New file. + * testapi.c: New file. + + * Makefile.am (EXTRA_PROGRAMS): Set to: benchmark testapi. + (check_PROGRAMS): Set to: $(TESTS). + +2003-07-12 Moritz Schulte <moritz@g10code.com> + + * ac.c, basic.c, keygen.c, register.c, sexp.c, tsexp.c: Used + gcry_err* wrappers for libgpg symbols. + + * basic.c (check_ciphers): Added: GCRY_CIPHER_TWOFISH128. + +2003-07-08 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (LIBS): Remove: -lpthread. + + * basic.c (check_one_cipher): Fix variable initialization. Thanks + to Simon Joseffson <jas@extundo.com>. + +2003-07-07 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added: register. + +2003-07-05 Moritz Schulte <moritz@g10code.com> + + * register.c (check_run): Adjusted for new gcry_cipher_register API. + +2003-07-02 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added: ac. + * ac.c: New file. + +2003-06-18 Werner Koch <wk@gnupg.org> + + * basic.c (check_cbc_mac_cipher): Adjusted for new API of get_blklen + and get_keylen. + (check_ctr_cipher): Ditto. + (check_one_cipher): Ditto. + (check_one_md): Adjusted for new API of gcry_md_copy. + +2003-06-18 Moritz Schulte <moritz@g10code.com> + + * register.c: Replace old type GcryModule with newer one: + gcry_module_t. + Adjusted for new API. + + * Makefile.am (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@. + +2003-06-15 Moritz Schulte <moritz@g10code.com> + + * basic.c (get_keys_new): New function. + (do_check_one_pubkey): New function ... + (check_one_pubkey): ... use it. + (progress_handler): New function. + (main): Use gcry_set_progress_handler. + +2003-06-14 Moritz Schulte <moritz@g10code.com> + + * basic.c: Replaced calls to gcry_strerror with calls to + gpg_strerror. + (check_one_md): Adjust for new gcry_md_copy API. + + * tsexp.c: Likewise. + * keygen.c: Likewise. + +2003-06-12 Moritz Schulte <moritz@g10code.com> + + * basic.c: Changed here and there, reorganized pubkey checks, + added DSA and ELG keys. + +2003-06-09 Moritz Schulte <moritz@g10code.com> + + * basic.c, keygen.c, pubkey.c, register.c, tsexp.c: Changed to use + new API. + +2003-06-01 Moritz Schulte <moritz@g10code.com> + + * tsexp.c (canon_len): Adjust for new gcry_sexp_canon_len API. + +2003-05-26 Moritz Schulte <moritz@g10code.com> + + * basic.c (verify_one_signature): Adjust for libgpg-error. + (check_pubkey_sign): Likewise. + (check_pubkey): Likewise. + * basic.c (check_pubkey_sign): Likewise. + * tsexp.c (canon_len): Likewise. + (back_and_forth_one): Likewise. + +2003-04-27 Moritz Schulte <moritz@g10code.com> + + * pubkey.c: Changed the sample private key to contain the + identifier `openpgp-rsa' instead of `rsa'. + + * basic.c (check_digests): Enabled/fixed some tests for TIGER. + +2003-04-17 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Removed `register' for now. + +2003-04-17 Moritz Schulte <moritz@g10code.com> + + * basic.c (check_digests): Include checks for SHA512 and SHA384. + +2003-04-16 Moritz Schulte <moritz@g10code.com> + + * basic.c (check_one_md): Also test md_copy. + +2003-04-07 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added register. + + * register.c: New file. + +2003-03-30 Simon Josefsson <jas@extundo.com> + + * basic.c (check_one_cipher): New. Test CTR. + (main): Call it. + (check_ciphers): Check CTR mode. + +2003-03-26 Moritz Schulte <moritz@g10code.com> + + * Makefile.am (TESTS): Added pubkey. + + * pubkey.c: New file. + +2003-03-22 Simon Josefsson <jas@extundo.com> + + * basic.c (check_cbc_mac_cipher): New. + (main): Use it. + +2003-03-19 Werner Koch <wk@gnupg.org> + + * keygen.c (check_rsa_keys): Don't expect an exponent when asking + for e=0. + (check_generated_rsa_key): Just print exponent if EXPECTED_E is 0. + +2003-03-02 Moritz Schulte <moritz@g10code.com> + + * basic.c (check_one_cipher): Use gcry_cipher_reset() instead of + gcry_cipher_close(), gcry_cipher_open and gcry_cipher_setkey(). + +2003-01-23 Werner Koch <wk@gnupg.org> + + * keygen.c: New. + +2003-01-20 Simon Josefsson <jas@extundo.com> + + * basic.c (check_digests): Add CRC. + (check_one_md): Print computed and expected values on error. + +2003-01-20 Werner Koch <wk@gnupg.org> + + * basic.c (check_one_md): Kludge to check a one million "a". + (check_digests): Add checks for SHA-256. + +2003-01-20 Werner Koch <wk@gnupg.org> + + * basic.c (check_pubkey): Check the keygrip for the sample key. + +2003-01-15 Werner Koch <wk@gnupg.org> + + * basic.c (verify_one_signature,check_pubkey_sign) + (check_pubkey): New. + (main): Check public key functions. Add a --debug option. + +2002-11-23 Werner Koch <wk@gnupg.org> + + * basic.c (check_digests): Add another test for MD4. By Simon + Josefsson. + +2002-11-10 Simon Josefsson <jas@extundo.com> + + * basic.c (check_aes128_cbc_cts_cipher): New function. + (check_one_cipher): Add flags parameter. + (check_ciphers): Support flags parameter. + (main): Check CTS. + +2002-11-10 Werner Koch <wk@gnupg.org> + + * basic.c (check_one_md): New. By Simon Josefsson. + (check_digests): New tests for MD4. By Simon. + +2002-08-26 Werner Koch <wk@gnupg.org> + + * basic.c (check_ciphers): Check simple DES. + +2002-05-16 Werner Koch <wk@gnupg.org> + + * tsexp.c (back_and_forth): Very minimal test of the new functions. + +2002-05-14 Werner Koch <wk@gnupg.org> + + Changed license of all files to the LGPL. + +2002-05-02 Werner Koch <wk@gnupg.org> + + * basic.c: Add option --verbose. + +2002-01-11 Werner Koch <wk@gnupg.org> + + * tsexp.c (canon_len): Fixed tests. + +2001-12-18 Werner Koch <wk@gnupg.org> + + * tsexp.c: New. + + + Copyright 2001, 2002, 2003, 2008 Free Software Foundation, Inc. + + This file is free software; as a special exception the author gives + unlimited permission to copy and/or distribute it, with or without + modifications, as long as this notice is preserved. + + This file is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY, to the extent permitted by law; without even the + implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.am b/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.am new file mode 100644 index 0000000000..f6a2d71d87 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.am @@ -0,0 +1,44 @@ +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is part of Libgcrypt. +# +# Libgcrypt is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Libgcrypt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +## Process this file with automake to produce Makefile.in + +TESTS = version t-mpi-bit prime register ac ac-schemes ac-data basic \ + mpitests tsexp keygen pubkey hmac keygrip fips186-dsa aeswrap + + +# random.c uses fork() thus a test for W32 does not make any sense. +if !HAVE_W32_SYSTEM +TESTS += random +endif + +# The last test to run. +TESTS += benchmark + + +# Need to include ../src in addition to top_srcdir because gcrypt.h is +# a built header. +AM_CPPFLAGS = -I../src -I$(top_srcdir)/src +AM_CFLAGS = $(GPG_ERROR_CFLAGS) + +LDADD = ../src/libgcrypt.la $(DL_LIBS) + +EXTRA_PROGRAMS = testapi pkbench +noinst_PROGRAMS = $(TESTS) fipsdrv + +EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.in b/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.in new file mode 100644 index 0000000000..91eb54d104 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/Makefile.in @@ -0,0 +1,767 @@ +# Makefile.in generated by automake 1.10.2 from Makefile.am. +# @configure_input@ + +# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, +# 2003, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. +# This Makefile.in is free software; the Free Software Foundation +# gives unlimited permission to copy and/or distribute it, +# with or without modifications, as long as this notice is preserved. + +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY, to the extent permitted by law; without +# even the implied warranty of MERCHANTABILITY or FITNESS FOR A +# PARTICULAR PURPOSE. + +@SET_MAKE@ + +# Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. +# +# This file is part of Libgcrypt. +# +# Libgcrypt is free software; you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License as +# published by the Free Software Foundation; either version 2.1 of +# the License, or (at your option) any later version. +# +# Libgcrypt is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public +# License along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +VPATH = @srcdir@ +pkgdatadir = $(datadir)/@PACKAGE@ +pkglibdir = $(libdir)/@PACKAGE@ +pkgincludedir = $(includedir)/@PACKAGE@ +am__cd = CDPATH="$${ZSH_VERSION+.}$(PATH_SEPARATOR)" && cd +install_sh_DATA = $(install_sh) -c -m 644 +install_sh_PROGRAM = $(install_sh) -c +install_sh_SCRIPT = $(install_sh) -c +INSTALL_HEADER = $(INSTALL_DATA) +transform = $(program_transform_name) +NORMAL_INSTALL = : +PRE_INSTALL = : +POST_INSTALL = : +NORMAL_UNINSTALL = : +PRE_UNINSTALL = : +POST_UNINSTALL = : +build_triplet = @build@ +host_triplet = @host@ +TESTS = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \ + register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \ + ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \ + tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \ + keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \ + $(am__EXEEXT_1) benchmark$(EXEEXT) + +# random.c uses fork() thus a test for W32 does not make any sense. +@HAVE_W32_SYSTEM_FALSE@am__append_1 = random +EXTRA_PROGRAMS = testapi$(EXEEXT) pkbench$(EXEEXT) +noinst_PROGRAMS = $(am__EXEEXT_2) fipsdrv$(EXEEXT) +subdir = tests +DIST_COMMON = README $(srcdir)/Makefile.am $(srcdir)/Makefile.in \ + ChangeLog +ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 +am__aclocal_m4_deps = $(top_srcdir)/m4/libtool.m4 \ + $(top_srcdir)/m4/noexecstack.m4 $(top_srcdir)/m4/onceonly.m4 \ + $(top_srcdir)/m4/socklen.m4 $(top_srcdir)/m4/sys_socket_h.m4 \ + $(top_srcdir)/acinclude.m4 $(top_srcdir)/configure.ac +am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ + $(ACLOCAL_M4) +mkinstalldirs = $(SHELL) $(top_srcdir)/mkinstalldirs +CONFIG_HEADER = $(top_builddir)/config.h +CONFIG_CLEAN_FILES = +@HAVE_W32_SYSTEM_FALSE@am__EXEEXT_1 = random$(EXEEXT) +am__EXEEXT_2 = version$(EXEEXT) t-mpi-bit$(EXEEXT) prime$(EXEEXT) \ + register$(EXEEXT) ac$(EXEEXT) ac-schemes$(EXEEXT) \ + ac-data$(EXEEXT) basic$(EXEEXT) mpitests$(EXEEXT) \ + tsexp$(EXEEXT) keygen$(EXEEXT) pubkey$(EXEEXT) hmac$(EXEEXT) \ + keygrip$(EXEEXT) fips186-dsa$(EXEEXT) aeswrap$(EXEEXT) \ + $(am__EXEEXT_1) benchmark$(EXEEXT) +PROGRAMS = $(noinst_PROGRAMS) +ac_SOURCES = ac.c +ac_OBJECTS = ac.$(OBJEXT) +ac_LDADD = $(LDADD) +am__DEPENDENCIES_1 = +ac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +ac_data_SOURCES = ac-data.c +ac_data_OBJECTS = ac-data.$(OBJEXT) +ac_data_LDADD = $(LDADD) +ac_data_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +ac_schemes_SOURCES = ac-schemes.c +ac_schemes_OBJECTS = ac-schemes.$(OBJEXT) +ac_schemes_LDADD = $(LDADD) +ac_schemes_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +aeswrap_SOURCES = aeswrap.c +aeswrap_OBJECTS = aeswrap.$(OBJEXT) +aeswrap_LDADD = $(LDADD) +aeswrap_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +basic_SOURCES = basic.c +basic_OBJECTS = basic.$(OBJEXT) +basic_LDADD = $(LDADD) +basic_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +benchmark_SOURCES = benchmark.c +benchmark_OBJECTS = benchmark.$(OBJEXT) +benchmark_LDADD = $(LDADD) +benchmark_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +fips186_dsa_SOURCES = fips186-dsa.c +fips186_dsa_OBJECTS = fips186-dsa.$(OBJEXT) +fips186_dsa_LDADD = $(LDADD) +fips186_dsa_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +fipsdrv_SOURCES = fipsdrv.c +fipsdrv_OBJECTS = fipsdrv.$(OBJEXT) +fipsdrv_LDADD = $(LDADD) +fipsdrv_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +hmac_SOURCES = hmac.c +hmac_OBJECTS = hmac.$(OBJEXT) +hmac_LDADD = $(LDADD) +hmac_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +keygen_SOURCES = keygen.c +keygen_OBJECTS = keygen.$(OBJEXT) +keygen_LDADD = $(LDADD) +keygen_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +keygrip_SOURCES = keygrip.c +keygrip_OBJECTS = keygrip.$(OBJEXT) +keygrip_LDADD = $(LDADD) +keygrip_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +mpitests_SOURCES = mpitests.c +mpitests_OBJECTS = mpitests.$(OBJEXT) +mpitests_LDADD = $(LDADD) +mpitests_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +pkbench_SOURCES = pkbench.c +pkbench_OBJECTS = pkbench.$(OBJEXT) +pkbench_LDADD = $(LDADD) +pkbench_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +prime_SOURCES = prime.c +prime_OBJECTS = prime.$(OBJEXT) +prime_LDADD = $(LDADD) +prime_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +pubkey_SOURCES = pubkey.c +pubkey_OBJECTS = pubkey.$(OBJEXT) +pubkey_LDADD = $(LDADD) +pubkey_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +random_SOURCES = random.c +random_OBJECTS = random.$(OBJEXT) +random_LDADD = $(LDADD) +random_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +register_SOURCES = register.c +register_OBJECTS = register.$(OBJEXT) +register_LDADD = $(LDADD) +register_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +t_mpi_bit_SOURCES = t-mpi-bit.c +t_mpi_bit_OBJECTS = t-mpi-bit.$(OBJEXT) +t_mpi_bit_LDADD = $(LDADD) +t_mpi_bit_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +testapi_SOURCES = testapi.c +testapi_OBJECTS = testapi.$(OBJEXT) +testapi_LDADD = $(LDADD) +testapi_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +tsexp_SOURCES = tsexp.c +tsexp_OBJECTS = tsexp.$(OBJEXT) +tsexp_LDADD = $(LDADD) +tsexp_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +version_SOURCES = version.c +version_OBJECTS = version.$(OBJEXT) +version_LDADD = $(LDADD) +version_DEPENDENCIES = ../src/libgcrypt.la $(am__DEPENDENCIES_1) +DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) +depcomp = $(SHELL) $(top_srcdir)/depcomp +am__depfiles_maybe = depfiles +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +CCLD = $(CC) +LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) \ + --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) \ + $(LDFLAGS) -o $@ +SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c benchmark.c \ + fips186-dsa.c fipsdrv.c hmac.c keygen.c keygrip.c mpitests.c \ + pkbench.c prime.c pubkey.c random.c register.c t-mpi-bit.c \ + testapi.c tsexp.c version.c +DIST_SOURCES = ac.c ac-data.c ac-schemes.c aeswrap.c basic.c \ + benchmark.c fips186-dsa.c fipsdrv.c hmac.c keygen.c keygrip.c \ + mpitests.c pkbench.c prime.c pubkey.c random.c register.c \ + t-mpi-bit.c testapi.c tsexp.c version.c +ETAGS = etags +CTAGS = ctags +DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST) +ACLOCAL = @ACLOCAL@ +AMTAR = @AMTAR@ +AR = @AR@ +AS = @AS@ +AUTOCONF = @AUTOCONF@ +AUTOHEADER = @AUTOHEADER@ +AUTOMAKE = @AUTOMAKE@ +AWK = @AWK@ +BUILD_FILEVERSION = @BUILD_FILEVERSION@ +BUILD_REVISION = @BUILD_REVISION@ +BUILD_TIMESTAMP = @BUILD_TIMESTAMP@ +CC = @CC@ +CCAS = @CCAS@ +CCASDEPMODE = @CCASDEPMODE@ +CCASFLAGS = @CCASFLAGS@ +CCDEPMODE = @CCDEPMODE@ +CFLAGS = @CFLAGS@ +CPP = @CPP@ +CPPFLAGS = @CPPFLAGS@ +CXX = @CXX@ +CXXCPP = @CXXCPP@ +CXXDEPMODE = @CXXDEPMODE@ +CXXFLAGS = @CXXFLAGS@ +CYGPATH_W = @CYGPATH_W@ +DEFS = @DEFS@ +DEPDIR = @DEPDIR@ +DLLTOOL = @DLLTOOL@ +DL_LIBS = @DL_LIBS@ +ECHO = @ECHO@ +ECHO_C = @ECHO_C@ +ECHO_N = @ECHO_N@ +ECHO_T = @ECHO_T@ +EGREP = @EGREP@ +EXEEXT = @EXEEXT@ +F77 = @F77@ +FALLBACK_SOCKLEN_T = @FALLBACK_SOCKLEN_T@ +FFLAGS = @FFLAGS@ +GCRYPT_CIPHERS = @GCRYPT_CIPHERS@ +GCRYPT_DIGESTS = @GCRYPT_DIGESTS@ +GCRYPT_PUBKEY_CIPHERS = @GCRYPT_PUBKEY_CIPHERS@ +GCRYPT_RANDOM = @GCRYPT_RANDOM@ +GPG_ERROR_CFLAGS = @GPG_ERROR_CFLAGS@ +GPG_ERROR_CONFIG = @GPG_ERROR_CONFIG@ +GPG_ERROR_LIBS = @GPG_ERROR_LIBS@ +GREP = @GREP@ +INSTALL = @INSTALL@ +INSTALL_DATA = @INSTALL_DATA@ +INSTALL_PROGRAM = @INSTALL_PROGRAM@ +INSTALL_SCRIPT = @INSTALL_SCRIPT@ +INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ +LDFLAGS = @LDFLAGS@ +LIBGCRYPT_CIPHERS = @LIBGCRYPT_CIPHERS@ +LIBGCRYPT_CONFIG_API_VERSION = @LIBGCRYPT_CONFIG_API_VERSION@ +LIBGCRYPT_CONFIG_CFLAGS = @LIBGCRYPT_CONFIG_CFLAGS@ +LIBGCRYPT_CONFIG_LIBS = @LIBGCRYPT_CONFIG_LIBS@ +LIBGCRYPT_DIGESTS = @LIBGCRYPT_DIGESTS@ +LIBGCRYPT_LT_AGE = @LIBGCRYPT_LT_AGE@ +LIBGCRYPT_LT_CURRENT = @LIBGCRYPT_LT_CURRENT@ +LIBGCRYPT_LT_REVISION = @LIBGCRYPT_LT_REVISION@ +LIBGCRYPT_PUBKEY_CIPHERS = @LIBGCRYPT_PUBKEY_CIPHERS@ +LIBGCRYPT_THREAD_MODULES = @LIBGCRYPT_THREAD_MODULES@ +LIBOBJS = @LIBOBJS@ +LIBS = @LIBS@ +LIBTOOL = @LIBTOOL@ +LN_S = @LN_S@ +LTLIBOBJS = @LTLIBOBJS@ +MAINT = @MAINT@ +MAKEINFO = @MAKEINFO@ +MKDIR_P = @MKDIR_P@ +MPI_SFLAGS = @MPI_SFLAGS@ +NOEXECSTACK_FLAGS = @NOEXECSTACK_FLAGS@ +OBJDUMP = @OBJDUMP@ +OBJEXT = @OBJEXT@ +PACKAGE = @PACKAGE@ +PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ +PACKAGE_NAME = @PACKAGE_NAME@ +PACKAGE_STRING = @PACKAGE_STRING@ +PACKAGE_TARNAME = @PACKAGE_TARNAME@ +PACKAGE_URL = @PACKAGE_URL@ +PACKAGE_VERSION = @PACKAGE_VERSION@ +PATH_SEPARATOR = @PATH_SEPARATOR@ +PTH_CFLAGS = @PTH_CFLAGS@ +PTH_CONFIG = @PTH_CONFIG@ +PTH_LIBS = @PTH_LIBS@ +RANLIB = @RANLIB@ +RC = @RC@ +SET_MAKE = @SET_MAKE@ +SHELL = @SHELL@ +STRIP = @STRIP@ +SYS_SOCKET_H = @SYS_SOCKET_H@ +VERSION = @VERSION@ +abs_builddir = @abs_builddir@ +abs_srcdir = @abs_srcdir@ +abs_top_builddir = @abs_top_builddir@ +abs_top_srcdir = @abs_top_srcdir@ +ac_ct_CC = @ac_ct_CC@ +ac_ct_CXX = @ac_ct_CXX@ +ac_ct_F77 = @ac_ct_F77@ +am__include = @am__include@ +am__leading_dot = @am__leading_dot@ +am__quote = @am__quote@ +am__tar = @am__tar@ +am__untar = @am__untar@ +bindir = @bindir@ +build = @build@ +build_alias = @build_alias@ +build_cpu = @build_cpu@ +build_os = @build_os@ +build_vendor = @build_vendor@ +builddir = @builddir@ +datadir = @datadir@ +datarootdir = @datarootdir@ +docdir = @docdir@ +dvidir = @dvidir@ +exec_prefix = @exec_prefix@ +host = @host@ +host_alias = @host_alias@ +host_cpu = @host_cpu@ +host_os = @host_os@ +host_vendor = @host_vendor@ +htmldir = @htmldir@ +includedir = @includedir@ +infodir = @infodir@ +install_sh = @install_sh@ +libdir = @libdir@ +libexecdir = @libexecdir@ +localedir = @localedir@ +localstatedir = @localstatedir@ +mandir = @mandir@ +mkdir_p = @mkdir_p@ +oldincludedir = @oldincludedir@ +pdfdir = @pdfdir@ +prefix = @prefix@ +program_transform_name = @program_transform_name@ +psdir = @psdir@ +sbindir = @sbindir@ +sharedstatedir = @sharedstatedir@ +srcdir = @srcdir@ +sysconfdir = @sysconfdir@ +target_alias = @target_alias@ +top_build_prefix = @top_build_prefix@ +top_builddir = @top_builddir@ +top_srcdir = @top_srcdir@ + +# Need to include ../src in addition to top_srcdir because gcrypt.h is +# a built header. +AM_CPPFLAGS = -I../src -I$(top_srcdir)/src +AM_CFLAGS = $(GPG_ERROR_CFLAGS) +LDADD = ../src/libgcrypt.la $(DL_LIBS) +EXTRA_DIST = README rsa-16k.key cavs_tests.sh cavs_driver.pl +all: all-am + +.SUFFIXES: +.SUFFIXES: .c .lo .o .obj +$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) + @for dep in $?; do \ + case '$(am__configure_deps)' in \ + *$$dep*) \ + ( cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh ) \ + && { if test -f $@; then exit 0; else break; fi; }; \ + exit 1;; \ + esac; \ + done; \ + echo ' cd $(top_srcdir) && $(AUTOMAKE) --gnu tests/Makefile'; \ + cd $(top_srcdir) && \ + $(AUTOMAKE) --gnu tests/Makefile +.PRECIOUS: Makefile +Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status + @case '$?' in \ + *config.status*) \ + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ + *) \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + esac; + +$(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh +$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps) + cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh + +clean-noinstPROGRAMS: + @list='$(noinst_PROGRAMS)'; for p in $$list; do \ + f=`echo $$p|sed 's/$(EXEEXT)$$//'`; \ + echo " rm -f $$p $$f"; \ + rm -f $$p $$f ; \ + done +ac$(EXEEXT): $(ac_OBJECTS) $(ac_DEPENDENCIES) + @rm -f ac$(EXEEXT) + $(LINK) $(ac_OBJECTS) $(ac_LDADD) $(LIBS) +ac-data$(EXEEXT): $(ac_data_OBJECTS) $(ac_data_DEPENDENCIES) + @rm -f ac-data$(EXEEXT) + $(LINK) $(ac_data_OBJECTS) $(ac_data_LDADD) $(LIBS) +ac-schemes$(EXEEXT): $(ac_schemes_OBJECTS) $(ac_schemes_DEPENDENCIES) + @rm -f ac-schemes$(EXEEXT) + $(LINK) $(ac_schemes_OBJECTS) $(ac_schemes_LDADD) $(LIBS) +aeswrap$(EXEEXT): $(aeswrap_OBJECTS) $(aeswrap_DEPENDENCIES) + @rm -f aeswrap$(EXEEXT) + $(LINK) $(aeswrap_OBJECTS) $(aeswrap_LDADD) $(LIBS) +basic$(EXEEXT): $(basic_OBJECTS) $(basic_DEPENDENCIES) + @rm -f basic$(EXEEXT) + $(LINK) $(basic_OBJECTS) $(basic_LDADD) $(LIBS) +benchmark$(EXEEXT): $(benchmark_OBJECTS) $(benchmark_DEPENDENCIES) + @rm -f benchmark$(EXEEXT) + $(LINK) $(benchmark_OBJECTS) $(benchmark_LDADD) $(LIBS) +fips186-dsa$(EXEEXT): $(fips186_dsa_OBJECTS) $(fips186_dsa_DEPENDENCIES) + @rm -f fips186-dsa$(EXEEXT) + $(LINK) $(fips186_dsa_OBJECTS) $(fips186_dsa_LDADD) $(LIBS) +fipsdrv$(EXEEXT): $(fipsdrv_OBJECTS) $(fipsdrv_DEPENDENCIES) + @rm -f fipsdrv$(EXEEXT) + $(LINK) $(fipsdrv_OBJECTS) $(fipsdrv_LDADD) $(LIBS) +hmac$(EXEEXT): $(hmac_OBJECTS) $(hmac_DEPENDENCIES) + @rm -f hmac$(EXEEXT) + $(LINK) $(hmac_OBJECTS) $(hmac_LDADD) $(LIBS) +keygen$(EXEEXT): $(keygen_OBJECTS) $(keygen_DEPENDENCIES) + @rm -f keygen$(EXEEXT) + $(LINK) $(keygen_OBJECTS) $(keygen_LDADD) $(LIBS) +keygrip$(EXEEXT): $(keygrip_OBJECTS) $(keygrip_DEPENDENCIES) + @rm -f keygrip$(EXEEXT) + $(LINK) $(keygrip_OBJECTS) $(keygrip_LDADD) $(LIBS) +mpitests$(EXEEXT): $(mpitests_OBJECTS) $(mpitests_DEPENDENCIES) + @rm -f mpitests$(EXEEXT) + $(LINK) $(mpitests_OBJECTS) $(mpitests_LDADD) $(LIBS) +pkbench$(EXEEXT): $(pkbench_OBJECTS) $(pkbench_DEPENDENCIES) + @rm -f pkbench$(EXEEXT) + $(LINK) $(pkbench_OBJECTS) $(pkbench_LDADD) $(LIBS) +prime$(EXEEXT): $(prime_OBJECTS) $(prime_DEPENDENCIES) + @rm -f prime$(EXEEXT) + $(LINK) $(prime_OBJECTS) $(prime_LDADD) $(LIBS) +pubkey$(EXEEXT): $(pubkey_OBJECTS) $(pubkey_DEPENDENCIES) + @rm -f pubkey$(EXEEXT) + $(LINK) $(pubkey_OBJECTS) $(pubkey_LDADD) $(LIBS) +random$(EXEEXT): $(random_OBJECTS) $(random_DEPENDENCIES) + @rm -f random$(EXEEXT) + $(LINK) $(random_OBJECTS) $(random_LDADD) $(LIBS) +register$(EXEEXT): $(register_OBJECTS) $(register_DEPENDENCIES) + @rm -f register$(EXEEXT) + $(LINK) $(register_OBJECTS) $(register_LDADD) $(LIBS) +t-mpi-bit$(EXEEXT): $(t_mpi_bit_OBJECTS) $(t_mpi_bit_DEPENDENCIES) + @rm -f t-mpi-bit$(EXEEXT) + $(LINK) $(t_mpi_bit_OBJECTS) $(t_mpi_bit_LDADD) $(LIBS) +testapi$(EXEEXT): $(testapi_OBJECTS) $(testapi_DEPENDENCIES) + @rm -f testapi$(EXEEXT) + $(LINK) $(testapi_OBJECTS) $(testapi_LDADD) $(LIBS) +tsexp$(EXEEXT): $(tsexp_OBJECTS) $(tsexp_DEPENDENCIES) + @rm -f tsexp$(EXEEXT) + $(LINK) $(tsexp_OBJECTS) $(tsexp_LDADD) $(LIBS) +version$(EXEEXT): $(version_OBJECTS) $(version_DEPENDENCIES) + @rm -f version$(EXEEXT) + $(LINK) $(version_OBJECTS) $(version_LDADD) $(LIBS) + +mostlyclean-compile: + -rm -f *.$(OBJEXT) + +distclean-compile: + -rm -f *.tab.c + +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-data.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac-schemes.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/aeswrap.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/basic.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/benchmark.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fips186-dsa.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fipsdrv.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hmac.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygen.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/keygrip.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mpitests.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pkbench.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/prime.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pubkey.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/random.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/register.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/t-mpi-bit.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/testapi.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsexp.Po@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/version.Po@am__quote@ + +.c.o: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c $< + +.c.obj: +@am__fastdepCC_TRUE@ $(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(COMPILE) -c `$(CYGPATH_W) '$<'` + +.c.lo: +@am__fastdepCC_TRUE@ $(LTCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCC_TRUE@ mv -f $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LTCOMPILE) -c -o $@ $< + +mostlyclean-libtool: + -rm -f *.lo + +clean-libtool: + -rm -rf .libs _libs + +ID: $(HEADERS) $(SOURCES) $(LISP) $(TAGS_FILES) + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + mkid -fID $$unique +tags: TAGS + +TAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + here=`pwd`; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + if test -z "$(ETAGS_ARGS)$$tags$$unique"; then :; else \ + test -n "$$unique" || unique=$$empty_fix; \ + $(ETAGS) $(ETAGSFLAGS) $(AM_ETAGSFLAGS) $(ETAGS_ARGS) \ + $$tags $$unique; \ + fi +ctags: CTAGS +CTAGS: $(HEADERS) $(SOURCES) $(TAGS_DEPENDENCIES) \ + $(TAGS_FILES) $(LISP) + tags=; \ + list='$(SOURCES) $(HEADERS) $(LISP) $(TAGS_FILES)'; \ + unique=`for i in $$list; do \ + if test -f "$$i"; then echo $$i; else echo $(srcdir)/$$i; fi; \ + done | \ + $(AWK) '{ files[$$0] = 1; nonempty = 1; } \ + END { if (nonempty) { for (i in files) print i; }; }'`; \ + test -z "$(CTAGS_ARGS)$$tags$$unique" \ + || $(CTAGS) $(CTAGSFLAGS) $(AM_CTAGSFLAGS) $(CTAGS_ARGS) \ + $$tags $$unique + +GTAGS: + here=`$(am__cd) $(top_builddir) && pwd` \ + && cd $(top_srcdir) \ + && gtags -i $(GTAGS_ARGS) $$here + +distclean-tags: + -rm -f TAGS ID GTAGS GRTAGS GSYMS GPATH tags + +check-TESTS: $(TESTS) + @failed=0; all=0; xfail=0; xpass=0; skip=0; \ + srcdir=$(srcdir); export srcdir; \ + list=' $(TESTS) '; \ + if test -n "$$list"; then \ + for tst in $$list; do \ + if test -f ./$$tst; then dir=./; \ + elif test -f $$tst; then dir=; \ + else dir="$(srcdir)/"; fi; \ + if $(TESTS_ENVIRONMENT) $${dir}$$tst; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xpass=`expr $$xpass + 1`; \ + failed=`expr $$failed + 1`; \ + echo "XPASS: $$tst"; \ + ;; \ + *) \ + echo "PASS: $$tst"; \ + ;; \ + esac; \ + elif test $$? -ne 77; then \ + all=`expr $$all + 1`; \ + case " $(XFAIL_TESTS) " in \ + *[\ \ ]$$tst[\ \ ]*) \ + xfail=`expr $$xfail + 1`; \ + echo "XFAIL: $$tst"; \ + ;; \ + *) \ + failed=`expr $$failed + 1`; \ + echo "FAIL: $$tst"; \ + ;; \ + esac; \ + else \ + skip=`expr $$skip + 1`; \ + echo "SKIP: $$tst"; \ + fi; \ + done; \ + if test "$$all" -eq 1; then \ + tests="test"; \ + All=""; \ + else \ + tests="tests"; \ + All="All "; \ + fi; \ + if test "$$failed" -eq 0; then \ + if test "$$xfail" -eq 0; then \ + banner="$$All$$all $$tests passed"; \ + else \ + if test "$$xfail" -eq 1; then failures=failure; else failures=failures; fi; \ + banner="$$All$$all $$tests behaved as expected ($$xfail expected $$failures)"; \ + fi; \ + else \ + if test "$$xpass" -eq 0; then \ + banner="$$failed of $$all $$tests failed"; \ + else \ + if test "$$xpass" -eq 1; then passes=pass; else passes=passes; fi; \ + banner="$$failed of $$all $$tests did not behave as expected ($$xpass unexpected $$passes)"; \ + fi; \ + fi; \ + dashes="$$banner"; \ + skipped=""; \ + if test "$$skip" -ne 0; then \ + if test "$$skip" -eq 1; then \ + skipped="($$skip test was not run)"; \ + else \ + skipped="($$skip tests were not run)"; \ + fi; \ + test `echo "$$skipped" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$skipped"; \ + fi; \ + report=""; \ + if test "$$failed" -ne 0 && test -n "$(PACKAGE_BUGREPORT)"; then \ + report="Please report to $(PACKAGE_BUGREPORT)"; \ + test `echo "$$report" | wc -c` -le `echo "$$banner" | wc -c` || \ + dashes="$$report"; \ + fi; \ + dashes=`echo "$$dashes" | sed s/./=/g`; \ + echo "$$dashes"; \ + echo "$$banner"; \ + test -z "$$skipped" || echo "$$skipped"; \ + test -z "$$report" || echo "$$report"; \ + echo "$$dashes"; \ + test "$$failed" -eq 0; \ + else :; fi + +distdir: $(DISTFILES) + @srcdirstrip=`echo "$(srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + topsrcdirstrip=`echo "$(top_srcdir)" | sed 's/[].[^$$\\*]/\\\\&/g'`; \ + list='$(DISTFILES)'; \ + dist_files=`for file in $$list; do echo $$file; done | \ + sed -e "s|^$$srcdirstrip/||;t" \ + -e "s|^$$topsrcdirstrip/|$(top_builddir)/|;t"`; \ + case $$dist_files in \ + */*) $(MKDIR_P) `echo "$$dist_files" | \ + sed '/\//!d;s|^|$(distdir)/|;s,/[^/]*$$,,' | \ + sort -u` ;; \ + esac; \ + for file in $$dist_files; do \ + if test -f $$file || test -d $$file; then d=.; else d=$(srcdir); fi; \ + if test -d $$d/$$file; then \ + dir=`echo "/$$file" | sed -e 's,/[^/]*$$,,'`; \ + if test -d $(srcdir)/$$file && test $$d != $(srcdir); then \ + cp -pR $(srcdir)/$$file $(distdir)$$dir || exit 1; \ + fi; \ + cp -pR $$d/$$file $(distdir)$$dir || exit 1; \ + else \ + test -f $(distdir)/$$file \ + || cp -p $$d/$$file $(distdir)/$$file \ + || exit 1; \ + fi; \ + done +check-am: all-am + $(MAKE) $(AM_MAKEFLAGS) check-TESTS +check: check-am +all-am: Makefile $(PROGRAMS) +installdirs: +install: install-am +install-exec: install-exec-am +install-data: install-data-am +uninstall: uninstall-am + +install-am: all-am + @$(MAKE) $(AM_MAKEFLAGS) install-exec-am install-data-am + +installcheck: installcheck-am +install-strip: + $(MAKE) $(AM_MAKEFLAGS) INSTALL_PROGRAM="$(INSTALL_STRIP_PROGRAM)" \ + install_sh_PROGRAM="$(INSTALL_STRIP_PROGRAM)" INSTALL_STRIP_FLAG=-s \ + `test -z '$(STRIP)' || \ + echo "INSTALL_PROGRAM_ENV=STRIPPROG='$(STRIP)'"` install +mostlyclean-generic: + +clean-generic: + +distclean-generic: + -test -z "$(CONFIG_CLEAN_FILES)" || rm -f $(CONFIG_CLEAN_FILES) + +maintainer-clean-generic: + @echo "This command is intended for maintainers to use" + @echo "it deletes files that may require special tools to rebuild." +clean: clean-am + +clean-am: clean-generic clean-libtool clean-noinstPROGRAMS \ + mostlyclean-am + +distclean: distclean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +distclean-am: clean-am distclean-compile distclean-generic \ + distclean-tags + +dvi: dvi-am + +dvi-am: + +html: html-am + +info: info-am + +info-am: + +install-data-am: + +install-dvi: install-dvi-am + +install-exec-am: + +install-html: install-html-am + +install-info: install-info-am + +install-man: + +install-pdf: install-pdf-am + +install-ps: install-ps-am + +installcheck-am: + +maintainer-clean: maintainer-clean-am + -rm -rf ./$(DEPDIR) + -rm -f Makefile +maintainer-clean-am: distclean-am maintainer-clean-generic + +mostlyclean: mostlyclean-am + +mostlyclean-am: mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool + +pdf: pdf-am + +pdf-am: + +ps: ps-am + +ps-am: + +uninstall-am: + +.MAKE: install-am install-strip + +.PHONY: CTAGS GTAGS all all-am check check-TESTS check-am clean \ + clean-generic clean-libtool clean-noinstPROGRAMS ctags \ + distclean distclean-compile distclean-generic \ + distclean-libtool distclean-tags distdir dvi dvi-am html \ + html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags uninstall uninstall-am + +# Tell versions [3.59,3.63) of GNU make to not export all variables. +# Otherwise a system limit (for SysV at least) may be exceeded. +.NOEXPORT: diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/README b/plugins/MirOTR/libgcrypt-1.4.6/tests/README new file mode 100644 index 0000000000..5326890259 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/README @@ -0,0 +1,9 @@ +Some notes about the tests. + +rsa-16k.key - A 16384 bit RSA key (public and privat), created 2008-08-28. + It took 91 minutes to create it on a 1500Mhz Pentium M. + pkpench showed these results: + encrypt: 80 ms + decrypt: 14370 ms + sign: 14110 ms + verify: 30 ms diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-data.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-data.c new file mode 100644 index 0000000000..e97b4f49ec --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-data.c @@ -0,0 +1,208 @@ +/* ac-data.c - Public key encryption/decryption tests + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdlib.h> +#include <stdio.h> +#include <assert.h> + +#define assert_err(err) \ + do \ + if (err) \ + { \ + fprintf (stderr, "Error occured at line %i: %s\n", \ + __LINE__, gcry_strerror (err)); \ + exit (1); \ + } \ + while (0) + +#include "../src/gcrypt.h" + +static int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +static void +check_sexp_conversion (gcry_ac_data_t data, const char **identifiers) +{ + gcry_ac_data_t data2; + gcry_error_t err; + gcry_sexp_t sexp; + unsigned int i; + const char *label1, *label2; + gcry_mpi_t mpi1, mpi2; + size_t length1, length2; + + err = gcry_ac_data_to_sexp (data, &sexp, identifiers); + assert_err (err); + if (verbose) + gcry_sexp_dump (sexp); + err = gcry_ac_data_from_sexp (&data2, sexp, identifiers); + assert_err (err); + + length1 = gcry_ac_data_length (data); + length2 = gcry_ac_data_length (data2); + assert (length1 == length2); + + for (i = 0; i < length1; i++) + { + err = gcry_ac_data_get_index (data, 0, i, &label1, &mpi1); + assert_err (err); + err = gcry_ac_data_get_index (data2, 0, i, &label2, &mpi2); + assert_err (err); + if (verbose) + { + fprintf (stderr, "Label1=`%s'\n", label1); + fprintf (stderr, "Label2=`%s'\n", label2); + } + assert (! strcmp (label1, label2)); + assert (! gcry_mpi_cmp (mpi1, mpi2)); + } + + gcry_ac_data_destroy (data2); + gcry_sexp_release (sexp); +} + +void +check_run (void) +{ + const char *identifiers[] = { "foo", + "bar", + "baz", + "hello", + "somemoretexthere", + "blahblahblah", + NULL }; + const char *identifiers_null[] = { NULL }; + gcry_ac_data_t data; + gcry_error_t err; + const char *label0; + const char *label1; + gcry_mpi_t mpi0; + gcry_mpi_t mpi1; + gcry_mpi_t mpi2; + + /* Initialize values. */ + + label0 = "thisisreallylonglabelbutsincethereisnolimitationonthelengthoflabelsitshouldworkjustfine"; + mpi0 = gcry_mpi_new (0); + assert (mpi0); + gcry_mpi_set_ui (mpi0, 123456); + + err = gcry_ac_data_new (&data); + assert_err (err); + + check_sexp_conversion (data, identifiers); + check_sexp_conversion (data, identifiers_null); + check_sexp_conversion (data, NULL); + + err = gcry_ac_data_set (data, 0, label0, mpi0); + assert_err (err); + err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1); + assert_err (err); + assert (label0 == label1); + assert (mpi0 == mpi1); + check_sexp_conversion (data, identifiers); + check_sexp_conversion (data, identifiers_null); + check_sexp_conversion (data, NULL); + + if (verbose) + printf ("data-set-test-0 succeeded\n"); + + gcry_ac_data_clear (data); + + err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, label0, mpi0); + assert_err (err); + + err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0); + assert_err (err); + err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "foo", mpi0); + assert_err (err); + err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "bar", mpi0); + assert_err (err); + err = gcry_ac_data_set (data, GCRY_AC_FLAG_COPY, "blah1", mpi0); + assert_err (err); + check_sexp_conversion (data, identifiers); + check_sexp_conversion (data, identifiers_null); + check_sexp_conversion (data, NULL); + + err = gcry_ac_data_get_name (data, 0, label0, &mpi1); + assert_err (err); + assert (mpi0 != mpi1); + err = gcry_ac_data_get_name (data, GCRY_AC_FLAG_COPY, label0, &mpi2); + assert_err (err); + assert (mpi0 != mpi1); + assert (mpi1 != mpi2); + err = gcry_ac_data_get_index (data, 0, 0, &label1, &mpi1); + assert_err (err); + gcry_mpi_release (mpi0); + gcry_mpi_release (mpi2); + + if (verbose) + printf ("data-set-test-1 succeeded\n"); + + gcry_ac_data_clear (data); + assert (! gcry_ac_data_length (data)); + check_sexp_conversion (data, identifiers); + check_sexp_conversion (data, identifiers_null); + check_sexp_conversion (data, NULL); + + if (verbose) + printf ("data-set-test-2 succeeded\n"); + + gcry_ac_data_destroy (data); + + +} + +int +main (int argc, char **argv) +{ + int debug = 0; + int i = 1; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + + for (; i > 0; i--) + check_run (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-schemes.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-schemes.c new file mode 100644 index 0000000000..dcef0bf760 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac-schemes.c @@ -0,0 +1,347 @@ +/* ac-schemes.c - Tests for ES/SSA + Copyright (C) 2003, 2005 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <errno.h> + +#include "../src/gcrypt.h" + +static unsigned int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +typedef struct scheme_spec +{ + unsigned int idx; + gcry_ac_scheme_t scheme; + unsigned int flags; + const char *m; + size_t m_n; +} scheme_spec_t; + +#define SCHEME_SPEC_FLAG_GET_OPTS (1 << 0) + +#define FILL(idx, scheme, flags, m) \ + { idx, GCRY_AC_##scheme, flags, m, sizeof (m) } + +scheme_spec_t es_specs[] = + { + FILL (0, ES_PKCS_V1_5, 0, "foobar"), + FILL (1, ES_PKCS_V1_5, 0, "") + }; + +scheme_spec_t ssa_specs[] = + { + FILL (0, SSA_PKCS_V1_5, SCHEME_SPEC_FLAG_GET_OPTS, "foobar") + }; + +#undef FILL + +gcry_err_code_t +scheme_get_opts (scheme_spec_t specs, void **opts) +{ + gcry_err_code_t err = GPG_ERR_NO_ERROR; + void *opts_new = NULL; + + switch (specs.scheme) + { + case GCRY_AC_SSA_PKCS_V1_5: + { + gcry_ac_ssa_pkcs_v1_5_t *opts_pkcs_v1_5 = NULL; + + opts_new = gcry_malloc (sizeof (gcry_ac_ssa_pkcs_v1_5_t)); + if (! opts_new) + err = gpg_err_code_from_errno (ENOMEM); + else + { + opts_pkcs_v1_5 = (gcry_ac_ssa_pkcs_v1_5_t *) opts_new; + + switch (specs.idx) + { + case 0: + opts_pkcs_v1_5->md = GCRY_MD_SHA1; + break; + case 1: + opts_pkcs_v1_5->md = GCRY_MD_MD5; + break; + } + } + } + case GCRY_AC_ES_PKCS_V1_5: + break; + } + + if (! err) + *opts = opts_new; + + return err; +} + +gcry_error_t +es_check (gcry_ac_handle_t handle, scheme_spec_t spec, + gcry_ac_key_t key_public, gcry_ac_key_t key_secret) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + char *c = NULL; + char *m2 = NULL; + size_t c_n = 0; + size_t m2_n = 0; + void *opts = NULL; + gcry_ac_io_t io_m; + gcry_ac_io_t io_c; + gcry_ac_io_t io_m2; + + if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS) + err = scheme_get_opts (spec, &opts); + if (! err) + { + c = NULL; + m2 = NULL; + + gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, + GCRY_AC_IO_STRING, spec.m, spec.m_n); + gcry_ac_io_init (&io_c, GCRY_AC_IO_WRITABLE, + GCRY_AC_IO_STRING, &c, &c_n); + + err = gcry_ac_data_encrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, opts, key_public, + &io_m, &io_c); + if (! err) + { + gcry_ac_io_init (&io_c, GCRY_AC_IO_READABLE, + GCRY_AC_IO_STRING, c, c_n); + gcry_ac_io_init (&io_m2, GCRY_AC_IO_WRITABLE, + GCRY_AC_IO_STRING, &m2, &m2_n); + + err = gcry_ac_data_decrypt_scheme (handle, GCRY_AC_ES_PKCS_V1_5, 0, + opts, key_secret, &io_c, &io_m2); + } + if (! err) + assert ((spec.m_n == m2_n) && (! strncmp (spec.m, m2, spec.m_n))); + + if (c) + gcry_free (c); + if (m2) + gcry_free (m2); + } + + if (opts) + gcry_free (opts); + + return err; +} + +gcry_error_t +ssa_check (gcry_ac_handle_t handle, scheme_spec_t spec, + gcry_ac_key_t key_public, gcry_ac_key_t key_secret) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + unsigned char *s = NULL; + size_t s_n = 0; + void *opts = NULL; + gcry_ac_io_t io_m; + gcry_ac_io_t io_s; + + if (spec.flags & SCHEME_SPEC_FLAG_GET_OPTS) + err = scheme_get_opts (spec, &opts); + if (! err) + { + gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, + GCRY_AC_IO_STRING, spec.m, spec.m_n); + gcry_ac_io_init (&io_s, GCRY_AC_IO_WRITABLE, + GCRY_AC_IO_STRING, &s, &s_n); + + err = gcry_ac_data_sign_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_secret, + &io_m, &io_s); + if (! err) + { + gcry_ac_io_init (&io_m, GCRY_AC_IO_READABLE, + GCRY_AC_IO_STRING, spec.m, spec.m_n); + gcry_ac_io_init (&io_s, GCRY_AC_IO_READABLE, + GCRY_AC_IO_STRING, s, s_n); + err = gcry_ac_data_verify_scheme (handle, GCRY_AC_SSA_PKCS_V1_5, 0, opts, key_public, + &io_m, &io_s); + } + assert (! err); + + if (s) + gcry_free (s); + } + + if (opts) + gcry_free (opts); + + return err; +} + +void +es_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + unsigned int i = 0; + + for (i = 0; (i < (sizeof (es_specs) / sizeof (*es_specs))) && (! err); i++) + err = es_check (handle, es_specs[i], key_public, key_secret); + + assert (! err); +} + +void +ssa_checks (gcry_ac_handle_t handle, gcry_ac_key_t key_public, gcry_ac_key_t key_secret) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + unsigned int i = 0; + + for (i = 0; (i < (sizeof (ssa_specs) / sizeof (*ssa_specs))) && (! err); i++) + err = ssa_check (handle, ssa_specs[i], key_public, key_secret); + + assert (! err); +} + +#define KEY_TYPE_PUBLIC (1 << 0) +#define KEY_TYPE_SECRET (1 << 1) + +typedef struct key_spec +{ + const char *name; + unsigned int flags; + const char *mpi_string; +} key_spec_t; + +key_spec_t key_specs[] = + { + { "n", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET, + "e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251" }, + { "e", KEY_TYPE_PUBLIC | KEY_TYPE_SECRET, + "010001" }, + { "d", KEY_TYPE_SECRET, + "046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" + "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" + "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" + "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781" }, + { "p", KEY_TYPE_SECRET, + "00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" + "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1" }, + { "q", KEY_TYPE_SECRET, + "00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" + "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361" }, + { "u", KEY_TYPE_SECRET, + "304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" + "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b" }, + { NULL }, + }; + +gcry_error_t +key_init (gcry_ac_key_type_t type, gcry_ac_key_t *key) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_ac_data_t key_data = NULL; + gcry_ac_key_t key_new = NULL; + gcry_mpi_t mpi = NULL; + unsigned int i = 0; + + err = gcry_ac_data_new (&key_data); + for (i = 0; key_specs[i].name && (! err); i++) + { + if (((type == GCRY_AC_KEY_PUBLIC) && (key_specs[i].flags & KEY_TYPE_PUBLIC)) + || ((type == GCRY_AC_KEY_SECRET) && (key_specs[i].flags & KEY_TYPE_SECRET))) + { + err = gcry_mpi_scan (&mpi, GCRYMPI_FMT_HEX, key_specs[i].mpi_string, 0, NULL); + if (! err) + { + gcry_ac_data_set (key_data, GCRY_AC_FLAG_COPY | GCRY_AC_FLAG_DEALLOC, + key_specs[i].name, mpi); + gcry_mpi_release (mpi); + } + } + } + if (! err) + err = gcry_ac_key_init (&key_new, NULL, type, key_data); + + if (key_data) + gcry_ac_data_destroy (key_data); + + if (! err) + *key = key_new; + + return err; +} + +static void +check_run (void) +{ + gcry_ac_handle_t handle = NULL; + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_ac_key_t key_public = NULL, key_secret = NULL; + + err = key_init (GCRY_AC_KEY_PUBLIC, &key_public); + if (! err) + err = key_init (GCRY_AC_KEY_SECRET, &key_secret); + + if (! err) + err = gcry_ac_open (&handle, GCRY_AC_RSA, 0); + if (! err) + { + es_checks (handle, key_public, key_secret); + ssa_checks (handle, key_public, key_secret); + } + + assert (! err); +} + +int +main (int argc, char **argv) +{ + unsigned int debug = 0; + + if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) + verbose = 1; + else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) + verbose = debug = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (! gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + + check_run (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/ac.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac.c new file mode 100644 index 0000000000..d734360a95 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/ac.c @@ -0,0 +1,162 @@ +/* pubkey.c - Public key encryption/decryption tests + * Copyright (C) 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../src/gcrypt.h" + +static int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +void +key_copy (gcry_ac_handle_t handle, + gcry_ac_key_type_t type, + gcry_ac_key_t *key_cp, gcry_ac_key_t key) +{ + gcry_error_t err = 0; + + err = gcry_ac_key_init (key_cp, handle, type, + gcry_ac_key_data_get (key)); + + assert (! err); +} + +void +check_one (gcry_mpi_t x) +{ + gcry_ac_handle_t handle; + gcry_ac_key_pair_t key_pair; + gcry_ac_key_t key_sec, key_sec_cp, key_pub, key_pub_cp; + gcry_error_t err = 0; + gcry_mpi_t x2; + gcry_ac_data_t data, data2; + gcry_ac_key_spec_rsa_t rsa_spec; + + rsa_spec.e = gcry_mpi_new (0); + gcry_mpi_set_ui (rsa_spec.e, 1); + + err = gcry_ac_open (&handle, GCRY_AC_RSA, 0); + assert (! err); + + err = gcry_ac_key_pair_generate (handle, 1024, &rsa_spec, &key_pair, NULL); + assert (! err); + + key_sec = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_SECRET); + key_copy (handle, GCRY_AC_KEY_SECRET, &key_sec_cp, key_sec); + + key_pub = gcry_ac_key_pair_extract (key_pair, GCRY_AC_KEY_PUBLIC); + key_copy (handle, GCRY_AC_KEY_PUBLIC, &key_pub_cp, key_pub); + + err = gcry_ac_data_encrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_pub_cp, x, &data); + assert (! err); + + err = gcry_ac_data_decrypt (handle, GCRY_AC_FLAG_NO_BLINDING, key_sec_cp, &x2, data); + assert (! err); + + assert (! gcry_mpi_cmp (x, x2)); + + gcry_ac_data_destroy (data); + + err = gcry_ac_data_sign (handle, key_sec, x, &data); + assert (! err); + err = gcry_ac_data_copy (&data2, data); + assert (! err); + gcry_ac_data_destroy (data); + err = gcry_ac_data_copy (&data, data2); + assert (! err); + gcry_ac_data_destroy (data2); + + err = gcry_ac_data_verify (handle, key_pub, x, data); + assert (! err); + + gcry_ac_data_destroy (data); + + err = gcry_ac_data_sign (handle, key_sec, x, &data); + assert (! err); + { + const char *label; + gcry_mpi_t y; + + err = gcry_ac_data_get_index (data, 0, 0, &label, &y); + assert (! err); + gcry_mpi_add_ui (y, y, 1); + + err = gcry_ac_data_verify (handle, key_pub, x, data); + assert (gcry_err_code (err) == GPG_ERR_BAD_SIGNATURE); + } + + gcry_ac_close (handle); +} + +void +check_run (void) +{ + /*const char *s = "All Hail Discordia."; -- not used */ + unsigned int a = 0x4223; + gcry_mpi_t x; + + x = gcry_mpi_new (0); + gcry_mpi_set_ui (x, a); + check_one (x); + gcry_mpi_release (x); +} + +int +main (int argc, char **argv) +{ + int debug = 0; + int i = 1; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + + for (; i > 0; i--) + check_run (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/aeswrap.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/aeswrap.c new file mode 100644 index 0000000000..39ef1e72a0 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/aeswrap.c @@ -0,0 +1,259 @@ +/* aeswrap.c - AESWRAP mode regression tests + * Copyright (C) 2009 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +static int verbose; +static int error_count; + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + + +static void +check (int algo, + const void *kek, size_t keklen, + const void *data, size_t datalen, + const void *expected, size_t expectedlen) +{ + gcry_error_t err; + gcry_cipher_hd_t hd; + unsigned char outbuf[32+8]; + size_t outbuflen; + + err = gcry_cipher_open (&hd, algo, GCRY_CIPHER_MODE_AESWRAP, 0); + if (err) + { + fail ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); + return; + } + + err = gcry_cipher_setkey (hd, kek, keklen); + if (err) + { + fail ("gcry_cipher_setkey failed: %s\n", gpg_strerror (err)); + return; + } + + outbuflen = datalen + 8; + if (outbuflen > sizeof outbuf) + err = gpg_error (GPG_ERR_INTERNAL); + else + err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, datalen); + if (err) + { + fail ("gcry_cipher_encrypt failed: %s\n", gpg_strerror (err)); + return; + } + + if (outbuflen != expectedlen || memcmp (outbuf, expected, expectedlen)) + { + const unsigned char *s; + int i; + + fail ("mismatch at encryption!\n"); + fprintf (stderr, "computed: "); + for (i = 0; i < outbuflen; i++) + fprintf (stderr, "%02x ", outbuf[i]); + fprintf (stderr, "\nexpected: "); + for (s = expected, i = 0; i < expectedlen; s++, i++) + fprintf (stderr, "%02x ", *s); + putc ('\n', stderr); + } + + + outbuflen = expectedlen - 8; + if (outbuflen > sizeof outbuf) + err = gpg_error (GPG_ERR_INTERNAL); + else + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + if (err) + { + fail ("gcry_cipher_decrypt failed: %s\n", gpg_strerror (err)); + return; + } + + if (outbuflen != datalen || memcmp (outbuf, data, datalen)) + { + const unsigned char *s; + int i; + + fail ("mismatch at decryption!\n"); + fprintf (stderr, "computed: "); + for (i = 0; i < outbuflen; i++) + fprintf (stderr, "%02x ", outbuf[i]); + fprintf (stderr, "\nexpected: "); + for (s = data, i = 0; i < datalen; s++, i++) + fprintf (stderr, "%02x ", *s); + putc ('\n', stderr); + } + + /* Now the last step again with a key reset. */ + gcry_cipher_reset (hd); + + outbuflen = expectedlen - 8; + if (outbuflen > sizeof outbuf) + err = gpg_error (GPG_ERR_INTERNAL); + else + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + if (err) + { + fail ("gcry_cipher_decrypt(2) failed: %s\n", gpg_strerror (err)); + return; + } + + if (outbuflen != datalen || memcmp (outbuf, data, datalen)) + fail ("mismatch at decryption(2)!\n"); + + /* And once ore without a key reset. */ + outbuflen = expectedlen - 8; + if (outbuflen > sizeof outbuf) + err = gpg_error (GPG_ERR_INTERNAL); + else + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, expected, expectedlen); + if (err) + { + fail ("gcry_cipher_decrypt(3) failed: %s\n", gpg_strerror (err)); + return; + } + + if (outbuflen != datalen || memcmp (outbuf, data, datalen)) + fail ("mismatch at decryption(3)!\n"); + + gcry_cipher_close (hd); +} + + +static void +check_all (void) +{ + if (verbose) + fprintf (stderr, "4.1 Wrap 128 bits of Key Data with a 128-bit KEK\n"); + check + (GCRY_CIPHER_AES128, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 16, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, + "\x1F\xA6\x8B\x0A\x81\x12\xB4\x47\xAE\xF3\x4B\xD8\xFB\x5A\x7B\x82" + "\x9D\x3E\x86\x23\x71\xD2\xCF\xE5", 24); + + if (verbose) + fprintf (stderr, "4.2 Wrap 128 bits of Key Data with a 192-bit KEK\n"); + check + (GCRY_CIPHER_AES192, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, + "\x96\x77\x8B\x25\xAE\x6C\xA4\x35\xF9\x2B\x5B\x97\xC0\x50\xAE\xD2" + "\x46\x8A\xB8\xA1\x7A\xD8\x4E\x5D", 24); + + if (verbose) + fprintf (stderr, "4.3 Wrap 128 bits of Key Data with a 256-bit KEK\n"); + check + (GCRY_CIPHER_AES256, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF", 16, + "\x64\xE8\xC3\xF9\xCE\x0F\x5B\xA2\x63\xE9\x77\x79\x05\x81\x8A\x2A" + "\x93\xC8\x19\x1E\x7D\x6E\x8A\xE7", 24); + + if (verbose) + fprintf (stderr, "4.4 Wrap 192 bits of Key Data with a 192-bit KEK\n"); + check + (GCRY_CIPHER_AES192, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17", 24, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + "\x00\x01\x02\x03\x04\x05\x06\x07", 24, + "\x03\x1D\x33\x26\x4E\x15\xD3\x32\x68\xF2\x4E\xC2\x60\x74\x3E\xDC" + "\xE1\xC6\xC7\xDD\xEE\x72\x5A\x93\x6B\xA8\x14\x91\x5C\x67\x62\xD2", 32); + + if (verbose) + fprintf (stderr, "4.5 Wrap 192 bits of Key Data with a 256-bit KEK\n"); + check + (GCRY_CIPHER_AES256, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + "\x00\x01\x02\x03\x04\x05\x06\x07", 24, + "\xA8\xF9\xBC\x16\x12\xC6\x8B\x3F\xF6\xE6\xF4\xFB\xE3\x0E\x71\xE4" + "\x76\x9C\x8B\x80\xA3\x2C\xB8\x95\x8C\xD5\xD1\x7D\x6B\x25\x4D\xA1", 32); + + if (verbose) + fprintf (stderr, "4.6 Wrap 256 bits of Key Data with a 256-bit KEK\n"); + check + (GCRY_CIPHER_AES, + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F", 32, + "\x00\x11\x22\x33\x44\x55\x66\x77\x88\x99\xAA\xBB\xCC\xDD\xEE\xFF" + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F", 32, + "\x28\xC9\xF4\x04\xC4\xB8\x10\xF4\xCB\xCC\xB3\x5C\xFB\x87\xF8\x26" + "\x3F\x57\x86\xE2\xD8\x0E\xD3\x26\xCB\xC7\xF0\xE7\x1A\x99\xF4\x3B" + "\xFB\x98\x8B\x9B\x7A\x02\xDD\x21", 40); +} + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + check_all (); + + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/basic.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/basic.c new file mode 100644 index 0000000000..d8cdea6ceb --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/basic.c @@ -0,0 +1,2250 @@ +/* basic.c - basic regression tests + * Copyright (C) 2001, 2002, 2003, 2005, 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +typedef struct test_spec_pubkey_key +{ + const char *secret; + const char *public; + const char *grip; +} +test_spec_pubkey_key_t; + +typedef struct test_spec_pubkey +{ + int id; + int flags; + test_spec_pubkey_key_t key; +} +test_spec_pubkey_t; + +#define FLAG_CRYPT (1 << 0) +#define FLAG_SIGN (1 << 1) +#define FLAG_GRIP (1 << 2) + +static int verbose; +static int error_count; +static int in_fips_mode; + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +#define MAX_DATA_LEN 100 + +void +progress_handler (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + (void)what; + (void)current; + (void)total; + + if (printchar == '\n') + fputs ( "<LF>", stdout); + else + putchar (printchar); + fflush (stdout); +} + +static void +check_cbc_mac_cipher (void) +{ + struct tv + { + int algo; + char key[MAX_DATA_LEN]; + unsigned char plaintext[MAX_DATA_LEN]; + size_t plaintextlen; + char mac[MAX_DATA_LEN]; + } + tv[] = + { + { GCRY_CIPHER_AES, + "chicken teriyaki", + "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", + 0, "\x23\x8f\x6d\xc7\x53\x6a\x62\x97\x11\xc4\xa5\x16\x43\xea\xb0\xb6" }, + { GCRY_CIPHER_3DES, + "abcdefghABCDEFGH01234567", + "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", + 0, "\x5c\x11\xf0\x01\x47\xbd\x3d\x3a" }, + { GCRY_CIPHER_DES, + "abcdefgh", + "This is a sample plaintext for CBC MAC of sixtyfour bytes.......", + 0, "\xfa\x4b\xdf\x9d\xfa\xab\x01\x70" } + }; + gcry_cipher_hd_t hd; + unsigned char out[MAX_DATA_LEN]; + int i, blklen, keylen; + gcry_error_t err = 0; + + if (verbose) + fprintf (stderr, "Starting CBC MAC checks.\n"); + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + if (gcry_cipher_test_algo (tv[i].algo) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + tv[i].algo); + continue; + } + + err = gcry_cipher_open (&hd, + tv[i].algo, + GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_MAC); + if (!hd) + { + fail ("cbc-mac algo %d, grcy_open_cipher failed: %s\n", + tv[i].algo, gpg_strerror (err)); + return; + } + + blklen = gcry_cipher_get_algo_blklen(tv[i].algo); + if (!blklen) + { + fail ("cbc-mac algo %d, gcry_cipher_get_algo_blklen failed\n", + tv[i].algo); + gcry_cipher_close (hd); + return; + } + + keylen = gcry_cipher_get_algo_keylen (tv[i].algo); + if (!keylen) + { + fail ("cbc-mac algo %d, gcry_cipher_get_algo_keylen failed\n", + tv[i].algo); + return; + } + + err = gcry_cipher_setkey (hd, tv[i].key, keylen); + if (err) + { + fail ("cbc-mac algo %d, gcry_cipher_setkey failed: %s\n", + tv[i].algo, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + err = gcry_cipher_setiv (hd, NULL, 0); + if (err) + { + fail ("cbc-mac algo %d, gcry_cipher_setiv failed: %s\n", + tv[i].algo, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (verbose) + fprintf (stderr, " checking CBC MAC for %s [%i]\n", + gcry_cipher_algo_name (tv[i].algo), + tv[i].algo); + err = gcry_cipher_encrypt (hd, + out, blklen, + tv[i].plaintext, + tv[i].plaintextlen ? + tv[i].plaintextlen : + strlen ((char*)tv[i].plaintext)); + if (err) + { + fail ("cbc-mac algo %d, gcry_cipher_encrypt failed: %s\n", + tv[i].algo, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + +#if 0 + { + int j; + for (j = 0; j < gcry_cipher_get_algo_blklen (tv[i].algo); j++) + printf ("\\x%02x", out[j] & 0xFF); + printf ("\n"); + } +#endif + + if (memcmp (tv[i].mac, out, blklen)) + fail ("cbc-mac algo %d, encrypt mismatch entry %d\n", tv[i].algo, i); + + gcry_cipher_close (hd); + } + if (verbose) + fprintf (stderr, "Completed CBC MAC checks.\n"); +} + +static void +check_aes128_cbc_cts_cipher (void) +{ + char key[128 / 8] = "chicken teriyaki"; + unsigned char plaintext[] = + "I would like the General Gau's Chicken, please, and wonton soup."; + struct tv + { + unsigned char out[MAX_DATA_LEN]; + int inlen; + } tv[] = + { + { "\xc6\x35\x35\x68\xf2\xbf\x8c\xb4\xd8\xa5\x80\x36\x2d\xa7\xff\x7f" + "\x97", + 17 }, + { "\xfc\x00\x78\x3e\x0e\xfd\xb2\xc1\xd4\x45\xd4\xc8\xef\xf7\xed\x22" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5", + 31 }, + { "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84", + 32 }, + { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\xb3\xff\xfd\x94\x0c\x16\xa1\x8c\x1b\x55\x49\xd2\xf8\x38\x02\x9e" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5", + 47 }, + { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8", + 48 }, + { "\x97\x68\x72\x68\xd6\xec\xcc\xc0\xc0\x7b\x25\xe2\x5e\xcf\xe5\x84" + "\x39\x31\x25\x23\xa7\x86\x62\xd5\xbe\x7f\xcb\xcc\x98\xeb\xf5\xa8" + "\x48\x07\xef\xe8\x36\xee\x89\xa5\x26\x73\x0d\xbc\x2f\x7b\xc8\x40" + "\x9d\xad\x8b\xbb\x96\xc4\xcd\xc0\x3b\xc1\x03\xe1\xa1\x94\xbb\xd8", + 64 }, + }; + gcry_cipher_hd_t hd; + unsigned char out[MAX_DATA_LEN]; + int i; + gcry_error_t err = 0; + + if (verbose) + fprintf (stderr, "Starting AES128 CBC CTS checks.\n"); + err = gcry_cipher_open (&hd, + GCRY_CIPHER_AES, + GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); + if (err) + { + fail ("aes-cbc-cts, grcy_open_cipher failed: %s\n", gpg_strerror (err)); + return; + } + + err = gcry_cipher_setkey (hd, key, 128 / 8); + if (err) + { + fail ("aes-cbc-cts, gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + err = gcry_cipher_setiv (hd, NULL, 0); + if (err) + { + fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (verbose) + fprintf (stderr, " checking encryption for length %i\n", tv[i].inlen); + err = gcry_cipher_encrypt (hd, out, MAX_DATA_LEN, + plaintext, tv[i].inlen); + if (err) + { + fail ("aes-cbc-cts, gcry_cipher_encrypt failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (memcmp (tv[i].out, out, tv[i].inlen)) + fail ("aes-cbc-cts, encrypt mismatch entry %d\n", i); + + err = gcry_cipher_setiv (hd, NULL, 0); + if (err) + { + fail ("aes-cbc-cts, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + if (verbose) + fprintf (stderr, " checking decryption for length %i\n", tv[i].inlen); + err = gcry_cipher_decrypt (hd, out, tv[i].inlen, NULL, 0); + if (err) + { + fail ("aes-cbc-cts, gcry_cipher_decrypt failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (memcmp (plaintext, out, tv[i].inlen)) + fail ("aes-cbc-cts, decrypt mismatch entry %d\n", i); + } + + gcry_cipher_close (hd); + if (verbose) + fprintf (stderr, "Completed AES128 CBC CTS checks.\n"); +} + +static void +check_ctr_cipher (void) +{ + struct tv + { + int algo; + char key[MAX_DATA_LEN]; + char ctr[MAX_DATA_LEN]; + struct data + { + unsigned char plaintext[MAX_DATA_LEN]; + int inlen; + char out[MAX_DATA_LEN]; + } + data[MAX_DATA_LEN]; + } tv[] = + { + /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ + { GCRY_CIPHER_AES, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\x87\x4d\x61\x91\xb6\x20\xe3\x26\x1b\xef\x68\x64\x99\x0d\xb6\xce" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x98\x06\xf6\x6b\x79\x70\xfd\xff\x86\x17\x18\x7b\xb9\xff\xfd\xff" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x5a\xe4\xdf\x3e\xdb\xd5\xd3\x5e\x5b\x4f\x09\x02\x0d\xb0\x3e\xab" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x1e\x03\x1d\xda\x2f\xbe\x03\xd1\x79\x21\x70\xa0\xf3\x00\x9c\xee" }, + } + }, + { GCRY_CIPHER_AES192, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" + "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\x1a\xbc\x93\x24\x17\x52\x1c\xa2\x4f\x2b\x04\x59\xfe\x7e\x6e\x0b" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x09\x03\x39\xec\x0a\xa6\xfa\xef\xd5\xcc\xc2\xc6\xf4\xce\x8e\x94" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x1e\x36\xb2\x6b\xd1\xeb\xc6\x70\xd1\xbd\x1d\x66\x56\x20\xab\xf7" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x4f\x78\xa7\xf6\xd2\x98\x09\x58\x5a\x97\xda\xec\x58\xc6\xb0\x50" }, + } + }, + { GCRY_CIPHER_AES256, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", + "\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\x60\x1e\xc3\x13\x77\x57\x89\xa5\xb7\xa7\xf5\x04\xbb\xf3\xd2\x28" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\xf4\x43\xe3\xca\x4d\x62\xb5\x9a\xca\x84\xe9\x90\xca\xca\xf5\xc5" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x2b\x09\x30\xda\xa2\x3d\xe9\x4c\xe8\x70\x17\xba\x2d\x84\x98\x8d" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\xdf\xc9\xc5\x8d\xb6\x7a\xad\xa6\x13\xc2\xdd\x08\x45\x79\x41\xa6" } + } + } + }; + gcry_cipher_hd_t hde, hdd; + unsigned char out[MAX_DATA_LEN]; + int i, j, keylen, blklen; + gcry_error_t err = 0; + + if (verbose) + fprintf (stderr, "Starting CTR cipher checks.\n"); + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); + if (!err) + err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CTR, 0); + if (err) + { + fail ("aes-ctr, grcy_open_cipher failed: %s\n", gpg_strerror (err)); + return; + } + + keylen = gcry_cipher_get_algo_keylen(tv[i].algo); + if (!keylen) + { + fail ("aes-ctr, gcry_cipher_get_algo_keylen failed\n"); + return; + } + + err = gcry_cipher_setkey (hde, tv[i].key, keylen); + if (!err) + err = gcry_cipher_setkey (hdd, tv[i].key, keylen); + if (err) + { + fail ("aes-ctr, gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + blklen = gcry_cipher_get_algo_blklen(tv[i].algo); + if (!blklen) + { + fail ("aes-ctr, gcry_cipher_get_algo_blklen failed\n"); + return; + } + + err = gcry_cipher_setctr (hde, tv[i].ctr, blklen); + if (!err) + err = gcry_cipher_setctr (hdd, tv[i].ctr, blklen); + if (err) + { + fail ("aes-ctr, gcry_cipher_setctr failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (verbose) + fprintf (stderr, " checking CTR mode for for %s [%i]\n", + gcry_cipher_algo_name (tv[i].algo), + tv[i].algo); + for (j = 0; tv[i].data[j].inlen; j++) + { + err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + tv[i].data[j].plaintext, + tv[i].data[j].inlen == -1 ? + strlen ((char*)tv[i].data[j].plaintext) : + tv[i].data[j].inlen); + if (err) + { + fail ("aes-ctr, gcry_cipher_encrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) + fail ("aes-ctr, encrypt mismatch entry %d:%d\n", i, j); + + err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); + if (err) + { + fail ("aes-ctr, gcry_cipher_decrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) + fail ("aes-ctr, decrypt mismatch entry %d:%d\n", i, j); + } + + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + } + if (verbose) + fprintf (stderr, "Completed CTR cipher checks.\n"); +} + +static void +check_cfb_cipher (void) +{ + struct tv + { + int algo; + char key[MAX_DATA_LEN]; + char iv[MAX_DATA_LEN]; + struct data + { + unsigned char plaintext[MAX_DATA_LEN]; + int inlen; + char out[MAX_DATA_LEN]; + } + data[MAX_DATA_LEN]; + } tv[] = + { + /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ + { GCRY_CIPHER_AES, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\xc8\xa6\x45\x37\xa0\xb3\xa9\x3f\xcd\xe3\xcd\xad\x9f\x1c\xe5\x8b"}, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x26\x75\x1f\x67\xa3\xcb\xb1\x40\xb1\x80\x8c\xf1\x87\xa4\xf4\xdf" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\xc0\x4b\x05\x35\x7c\x5d\x1c\x0e\xea\xc4\xc6\x6f\x9f\xf7\xf2\xe6" }, + } + }, + { GCRY_CIPHER_AES192, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" + "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x67\xce\x7f\x7f\x81\x17\x36\x21\x96\x1a\x2b\x70\x17\x1d\x3d\x7a" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x2e\x1e\x8a\x1d\xd5\x9b\x88\xb1\xc8\xe6\x0f\xed\x1e\xfa\xc4\xc9" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\xc0\x5f\x9f\x9c\xa9\x83\x4f\xa0\x42\xae\x8f\xba\x58\x4b\x09\xff" }, + } + }, + { GCRY_CIPHER_AES256, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x39\xff\xed\x14\x3b\x28\xb1\xc8\x32\x11\x3c\x63\x31\xe5\x40\x7b" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\xdf\x10\x13\x24\x15\xe5\x4b\x92\xa1\x3e\xd0\xa8\x26\x7a\xe2\xf9" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x75\xa3\x85\x74\x1a\xb9\xce\xf8\x20\x31\x62\x3d\x55\xb1\xe4\x71" } + } + } + }; + gcry_cipher_hd_t hde, hdd; + unsigned char out[MAX_DATA_LEN]; + int i, j, keylen, blklen; + gcry_error_t err = 0; + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0); + if (!err) + err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_CFB, 0); + if (err) + { + fail ("aes-cfb, grcy_open_cipher failed: %s\n", gpg_strerror (err)); + return; + } + + keylen = gcry_cipher_get_algo_keylen(tv[i].algo); + if (!keylen) + { + fail ("aes-cfb, gcry_cipher_get_algo_keylen failed\n"); + return; + } + + err = gcry_cipher_setkey (hde, tv[i].key, keylen); + if (!err) + err = gcry_cipher_setkey (hdd, tv[i].key, keylen); + if (err) + { + fail ("aes-cfb, gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + blklen = gcry_cipher_get_algo_blklen(tv[i].algo); + if (!blklen) + { + fail ("aes-cfb, gcry_cipher_get_algo_blklen failed\n"); + return; + } + + err = gcry_cipher_setiv (hde, tv[i].iv, blklen); + if (!err) + err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); + if (err) + { + fail ("aes-cfb, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + for (j = 0; tv[i].data[j].inlen; j++) + { + err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + tv[i].data[j].plaintext, + tv[i].data[j].inlen); + if (err) + { + fail ("aes-cfb, gcry_cipher_encrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) { + fail ("aes-cfb, encrypt mismatch entry %d:%d\n", i, j); + } + err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); + if (err) + { + fail ("aes-cfb, gcry_cipher_decrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) + fail ("aes-cfb, decrypt mismatch entry %d:%d\n", i, j); + } + + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + } +} + +static void +check_ofb_cipher (void) +{ + struct tv + { + int algo; + char key[MAX_DATA_LEN]; + char iv[MAX_DATA_LEN]; + struct data + { + unsigned char plaintext[MAX_DATA_LEN]; + int inlen; + char out[MAX_DATA_LEN]; + } + data[MAX_DATA_LEN]; + } tv[] = + { + /* http://csrc.nist.gov/publications/nistpubs/800-38a/sp800-38a.pdf */ + { GCRY_CIPHER_AES, + "\x2b\x7e\x15\x16\x28\xae\xd2\xa6\xab\xf7\x15\x88\x09\xcf\x4f\x3c", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\x3b\x3f\xd9\x2e\xb7\x2d\xad\x20\x33\x34\x49\xf8\xe8\x3c\xfb\x4a" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x77\x89\x50\x8d\x16\x91\x8f\x03\xf5\x3c\x52\xda\xc5\x4e\xd8\x25"}, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x97\x40\x05\x1e\x9c\x5f\xec\xf6\x43\x44\xf7\xa8\x22\x60\xed\xcc" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x30\x4c\x65\x28\xf6\x59\xc7\x78\x66\xa5\x10\xd9\xc1\xd6\xae\x5e" }, + } + }, + { GCRY_CIPHER_AES192, + "\x8e\x73\xb0\xf7\xda\x0e\x64\x52\xc8\x10\xf3\x2b" + "\x80\x90\x79\xe5\x62\xf8\xea\xd2\x52\x2c\x6b\x7b", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\xcd\xc8\x0d\x6f\xdd\xf1\x8c\xab\x34\xc2\x59\x09\xc9\x9a\x41\x74" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\xfc\xc2\x8b\x8d\x4c\x63\x83\x7c\x09\xe8\x17\x00\xc1\x10\x04\x01" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x8d\x9a\x9a\xea\xc0\xf6\x59\x6f\x55\x9c\x6d\x4d\xaf\x59\xa5\xf2" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x6d\x9f\x20\x08\x57\xca\x6c\x3e\x9c\xac\x52\x4b\xd9\xac\xc9\x2a" }, + } + }, + { GCRY_CIPHER_AES256, + "\x60\x3d\xeb\x10\x15\xca\x71\xbe\x2b\x73\xae\xf0\x85\x7d\x77\x81" + "\x1f\x35\x2c\x07\x3b\x61\x08\xd7\x2d\x98\x10\xa3\x09\x14\xdf\xf4", + "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f", + { { "\x6b\xc1\xbe\xe2\x2e\x40\x9f\x96\xe9\x3d\x7e\x11\x73\x93\x17\x2a", + 16, + "\xdc\x7e\x84\xbf\xda\x79\x16\x4b\x7e\xcd\x84\x86\x98\x5d\x38\x60" }, + { "\xae\x2d\x8a\x57\x1e\x03\xac\x9c\x9e\xb7\x6f\xac\x45\xaf\x8e\x51", + 16, + "\x4f\xeb\xdc\x67\x40\xd2\x0b\x3a\xc8\x8f\x6a\xd8\x2a\x4f\xb0\x8d" }, + { "\x30\xc8\x1c\x46\xa3\x5c\xe4\x11\xe5\xfb\xc1\x19\x1a\x0a\x52\xef", + 16, + "\x71\xab\x47\xa0\x86\xe8\x6e\xed\xf3\x9d\x1c\x5b\xba\x97\xc4\x08" }, + { "\xf6\x9f\x24\x45\xdf\x4f\x9b\x17\xad\x2b\x41\x7b\xe6\x6c\x37\x10", + 16, + "\x01\x26\x14\x1d\x67\xf3\x7b\xe8\x53\x8f\x5a\x8b\xe7\x40\xe4\x84" } + } + } + }; + gcry_cipher_hd_t hde, hdd; + unsigned char out[MAX_DATA_LEN]; + int i, j, keylen, blklen; + gcry_error_t err = 0; + + for (i = 0; i < sizeof (tv) / sizeof (tv[0]); i++) + { + err = gcry_cipher_open (&hde, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); + if (!err) + err = gcry_cipher_open (&hdd, tv[i].algo, GCRY_CIPHER_MODE_OFB, 0); + if (err) + { + fail ("aes-ofb, grcy_open_cipher failed: %s\n", gpg_strerror (err)); + return; + } + + keylen = gcry_cipher_get_algo_keylen(tv[i].algo); + if (!keylen) + { + fail ("aes-ofb, gcry_cipher_get_algo_keylen failed\n"); + return; + } + + err = gcry_cipher_setkey (hde, tv[i].key, keylen); + if (!err) + err = gcry_cipher_setkey (hdd, tv[i].key, keylen); + if (err) + { + fail ("aes-ofb, gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + blklen = gcry_cipher_get_algo_blklen(tv[i].algo); + if (!blklen) + { + fail ("aes-ofb, gcry_cipher_get_algo_blklen failed\n"); + return; + } + + err = gcry_cipher_setiv (hde, tv[i].iv, blklen); + if (!err) + err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); + if (err) + { + fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + for (j = 0; tv[i].data[j].inlen; j++) + { + err = gcry_cipher_encrypt (hde, out, MAX_DATA_LEN, + tv[i].data[j].plaintext, + tv[i].data[j].inlen); + if (err) + { + fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) + fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); + + err = gcry_cipher_decrypt (hdd, out, tv[i].data[j].inlen, NULL, 0); + if (err) + { + fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) + fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); + } + + err = gcry_cipher_reset(hde); + if (!err) + err = gcry_cipher_reset(hdd); + if (err) + { + fail ("aes-ofb, gcry_cipher_reset (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + /* gcry_cipher_reset clears the IV */ + err = gcry_cipher_setiv (hde, tv[i].iv, blklen); + if (!err) + err = gcry_cipher_setiv (hdd, tv[i].iv, blklen); + if (err) + { + fail ("aes-ofb, gcry_cipher_setiv failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + + /* this time we encrypt and decrypt one byte at a time */ + for (j = 0; tv[i].data[j].inlen; j++) + { + int byteNum; + for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) + { + err = gcry_cipher_encrypt (hde, out+byteNum, 1, + (tv[i].data[j].plaintext) + byteNum, + 1); + if (err) + { + fail ("aes-ofb, gcry_cipher_encrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].data[j].out, out, tv[i].data[j].inlen)) + fail ("aes-ofb, encrypt mismatch entry %d:%d\n", i, j); + + for (byteNum = 0; byteNum < tv[i].data[j].inlen; ++byteNum) + { + err = gcry_cipher_decrypt (hdd, out+byteNum, 1, NULL, 0); + if (err) + { + fail ("aes-ofb, gcry_cipher_decrypt (%d, %d) failed: %s\n", + i, j, gpg_strerror (err)); + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + return; + } + } + + if (memcmp (tv[i].data[j].plaintext, out, tv[i].data[j].inlen)) + fail ("aes-ofb, decrypt mismatch entry %d:%d\n", i, j); + } + + gcry_cipher_close (hde); + gcry_cipher_close (hdd); + } +} + +static void +check_one_cipher (int algo, int mode, int flags) +{ + gcry_cipher_hd_t hd; + char key[32]; + unsigned char plain[16], in[16], out[16]; + int keylen; + gcry_error_t err = 0; + + memcpy (key, "0123456789abcdef.,;/[]{}-=ABCDEF", 32); + memcpy (plain, "foobar42FOOBAR17", 16); + + keylen = gcry_cipher_get_algo_keylen (algo); + if (!keylen) + { + fail ("algo %d, mode %d, gcry_cipher_get_algo_keylen failed\n", + algo, mode); + return; + } + + if (keylen < 40 / 8 || keylen > 32) + { + fail ("algo %d, mode %d, keylength problem (%d)\n", algo, mode, keylen); + return; + } + + err = gcry_cipher_open (&hd, algo, mode, flags); + if (err) + { + fail ("algo %d, mode %d, grcy_open_cipher failed: %s\n", + algo, mode, gpg_strerror (err)); + return; + } + + err = gcry_cipher_setkey (hd, key, keylen); + if (err) + { + fail ("algo %d, mode %d, gcry_cipher_setkey failed: %s\n", + algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + err = gcry_cipher_encrypt (hd, out, 16, plain, 16); + if (err) + { + fail ("algo %d, mode %d, gcry_cipher_encrypt failed: %s\n", + algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + gcry_cipher_reset (hd); + + err = gcry_cipher_decrypt (hd, in, 16, out, 16); + if (err) + { + fail ("algo %d, mode %d, gcry_cipher_decrypt failed: %s\n", + algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (memcmp (plain, in, 16)) + fail ("algo %d, mode %d, encrypt-decrypt mismatch\n", algo, mode); + + /* Again, using in-place encryption. */ + gcry_cipher_reset (hd); + + memcpy (out, plain, 16); + err = gcry_cipher_encrypt (hd, out, 16, NULL, 0); + if (err) + { + fail ("algo %d, mode %d, in-place, gcry_cipher_encrypt failed: %s\n", + algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + gcry_cipher_reset (hd); + + err = gcry_cipher_decrypt (hd, out, 16, NULL, 0); + if (err) + { + fail ("algo %d, mode %d, in-place, gcry_cipher_decrypt failed: %s\n", + algo, mode, gpg_strerror (err)); + gcry_cipher_close (hd); + return; + } + + if (memcmp (plain, out, 16)) + fail ("algo %d, mode %d, in-place, encrypt-decrypt mismatch\n",algo, mode); + + + gcry_cipher_close (hd); + +} + + +static void +check_ciphers (void) +{ + static int algos[] = { +#if USE_BLOWFISH + GCRY_CIPHER_BLOWFISH, +#endif +#if USE_DES + GCRY_CIPHER_DES, + GCRY_CIPHER_3DES, +#endif +#if USE_CAST5 + GCRY_CIPHER_CAST5, +#endif +#if USE_AES + GCRY_CIPHER_AES, + GCRY_CIPHER_AES192, + GCRY_CIPHER_AES256, +#endif +#if USE_TWOFISH + GCRY_CIPHER_TWOFISH, + GCRY_CIPHER_TWOFISH128, +#endif +#if USE_SERPENT + GCRY_CIPHER_SERPENT128, + GCRY_CIPHER_SERPENT192, + GCRY_CIPHER_SERPENT256, +#endif +#if USE_RFC2268 + GCRY_CIPHER_RFC2268_40, +#endif +#if USE_SEED + GCRY_CIPHER_SEED, +#endif +#if USE_CAMELLIA + GCRY_CIPHER_CAMELLIA128, + GCRY_CIPHER_CAMELLIA192, + GCRY_CIPHER_CAMELLIA256, +#endif + 0 + }; + static int algos2[] = { +#if USE_ARCFOUR + GCRY_CIPHER_ARCFOUR, +#endif + 0 + }; + int i; + + if (verbose) + fprintf (stderr, "Starting Cipher checks.\n"); + for (i = 0; algos[i]; i++) + { + if (gcry_cipher_test_algo (algos[i]) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + algos[i]); + continue; + } + if (verbose) + fprintf (stderr, " checking %s [%i]\n", + gcry_cipher_algo_name (algos[i]), + gcry_cipher_map_name (gcry_cipher_algo_name (algos[i]))); + + check_one_cipher (algos[i], GCRY_CIPHER_MODE_ECB, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CFB, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_OFB, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, 0); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CBC, GCRY_CIPHER_CBC_CTS); + check_one_cipher (algos[i], GCRY_CIPHER_MODE_CTR, 0); + } + + for (i = 0; algos2[i]; i++) + { + if (gcry_cipher_test_algo (algos[i]) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + algos[i]); + continue; + } + if (verbose) + fprintf (stderr, " checking `%s'\n", + gcry_cipher_algo_name (algos2[i])); + + check_one_cipher (algos2[i], GCRY_CIPHER_MODE_STREAM, 0); + } + /* we have now run all cipher's selftests */ + + if (verbose) + fprintf (stderr, "Completed Cipher checks.\n"); + + /* TODO: add some extra encryption to test the higher level functions */ +} + + + +static void +check_one_md (int algo, const char *data, int len, const char *expect) +{ + gcry_md_hd_t hd, hd2; + unsigned char *p; + int mdlen; + int i; + gcry_error_t err = 0; + + err = gcry_md_open (&hd, algo, 0); + if (err) + { + fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err)); + return; + } + + mdlen = gcry_md_get_algo_dlen (algo); + if (mdlen < 1 || mdlen > 500) + { + fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen); + return; + } + + if (*data == '!' && !data[1]) + { /* hash one million times a "a" */ + char aaa[1000]; + + /* Write in odd size chunks so that we test the buffering. */ + memset (aaa, 'a', 1000); + for (i = 0; i < 1000; i++) + gcry_md_write (hd, aaa, 1000); + } + else + gcry_md_write (hd, data, len); + + err = gcry_md_copy (&hd2, hd); + if (err) + { + fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); + } + + gcry_md_close (hd); + + p = gcry_md_read (hd2, algo); + + if (memcmp (p, expect, mdlen)) + { + printf ("computed: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", p[i] & 0xFF); + printf ("\nexpected: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", expect[i] & 0xFF); + printf ("\n"); + + fail ("algo %d, digest mismatch\n", algo); + } + + gcry_md_close (hd2); +} + + +static void +check_digests (void) +{ + static struct algos + { + int md; + const char *data; + const char *expect; + } algos[] = + { + { GCRY_MD_MD4, "", + "\x31\xD6\xCF\xE0\xD1\x6A\xE9\x31\xB7\x3C\x59\xD7\xE0\xC0\x89\xC0" }, + { GCRY_MD_MD4, "a", + "\xbd\xe5\x2c\xb3\x1d\xe3\x3e\x46\x24\x5e\x05\xfb\xdb\xd6\xfb\x24" }, + { GCRY_MD_MD4, "message digest", + "\xd9\x13\x0a\x81\x64\x54\x9f\xe8\x18\x87\x48\x06\xe1\xc7\x01\x4b" }, + { GCRY_MD_MD5, "", + "\xD4\x1D\x8C\xD9\x8F\x00\xB2\x04\xE9\x80\x09\x98\xEC\xF8\x42\x7E" }, + { GCRY_MD_MD5, "a", + "\x0C\xC1\x75\xB9\xC0\xF1\xB6\xA8\x31\xC3\x99\xE2\x69\x77\x26\x61" }, + { GCRY_MD_MD5, "abc", + "\x90\x01\x50\x98\x3C\xD2\x4F\xB0\xD6\x96\x3F\x7D\x28\xE1\x7F\x72" }, + { GCRY_MD_MD5, "message digest", + "\xF9\x6B\x69\x7D\x7C\xB7\x93\x8D\x52\x5A\x2F\x31\xAA\xF1\x61\xD0" }, + { GCRY_MD_SHA1, "abc", + "\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E" + "\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D" }, + { GCRY_MD_SHA1, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE" + "\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1" }, + { GCRY_MD_SHA1, "!" /* kludge for "a"*1000000 */ , + "\x34\xAA\x97\x3C\xD4\xC4\xDA\xA4\xF6\x1E" + "\xEB\x2B\xDB\xAD\x27\x31\x65\x34\x01\x6F" }, + /* From RFC3874 */ + { GCRY_MD_SHA224, "abc", + "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55\xb3" + "\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7" }, + { GCRY_MD_SHA224, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01\x50" + "\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25" }, + { GCRY_MD_SHA224, "!", + "\x20\x79\x46\x55\x98\x0c\x91\xd8\xbb\xb4\xc1\xea\x97\x61\x8a\x4b" + "\xf0\x3f\x42\x58\x19\x48\xb2\xee\x4e\xe7\xad\x67" }, + { GCRY_MD_SHA256, "abc", + "\xba\x78\x16\xbf\x8f\x01\xcf\xea\x41\x41\x40\xde\x5d\xae\x22\x23" + "\xb0\x03\x61\xa3\x96\x17\x7a\x9c\xb4\x10\xff\x61\xf2\x00\x15\xad" }, + { GCRY_MD_SHA256, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x24\x8d\x6a\x61\xd2\x06\x38\xb8\xe5\xc0\x26\x93\x0c\x3e\x60\x39" + "\xa3\x3c\xe4\x59\x64\xff\x21\x67\xf6\xec\xed\xd4\x19\xdb\x06\xc1" }, + { GCRY_MD_SHA256, "!", + "\xcd\xc7\x6e\x5c\x99\x14\xfb\x92\x81\xa1\xc7\xe2\x84\xd7\x3e\x67" + "\xf1\x80\x9a\x48\xa4\x97\x20\x0e\x04\x6d\x39\xcc\xc7\x11\x2c\xd0" }, + { GCRY_MD_SHA384, "abc", + "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50\x07" + "\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff\x5b\xed" + "\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34\xc8\x25\xa7" }, + { GCRY_MD_SHA512, "abc", + "\xDD\xAF\x35\xA1\x93\x61\x7A\xBA\xCC\x41\x73\x49\xAE\x20\x41\x31" + "\x12\xE6\xFA\x4E\x89\xA9\x7E\xA2\x0A\x9E\xEE\xE6\x4B\x55\xD3\x9A" + "\x21\x92\x99\x2A\x27\x4F\xC1\xA8\x36\xBA\x3C\x23\xA3\xFE\xEB\xBD" + "\x45\x4D\x44\x23\x64\x3C\xE8\x0E\x2A\x9A\xC9\x4F\xA5\x4C\xA4\x9F" }, + { GCRY_MD_RMD160, "", + "\x9c\x11\x85\xa5\xc5\xe9\xfc\x54\x61\x28" + "\x08\x97\x7e\xe8\xf5\x48\xb2\x25\x8d\x31" }, + { GCRY_MD_RMD160, "a", + "\x0b\xdc\x9d\x2d\x25\x6b\x3e\xe9\xda\xae" + "\x34\x7b\xe6\xf4\xdc\x83\x5a\x46\x7f\xfe" }, + { GCRY_MD_RMD160, "abc", + "\x8e\xb2\x08\xf7\xe0\x5d\x98\x7a\x9b\x04" + "\x4a\x8e\x98\xc6\xb0\x87\xf1\x5a\x0b\xfc" }, + { GCRY_MD_RMD160, "message digest", + "\x5d\x06\x89\xef\x49\xd2\xfa\xe5\x72\xb8" + "\x81\xb1\x23\xa8\x5f\xfa\x21\x59\x5f\x36" }, + { GCRY_MD_CRC32, "", "\x00\x00\x00\x00" }, + { GCRY_MD_CRC32, "foo", "\x8c\x73\x65\x21" }, + { GCRY_MD_CRC32_RFC1510, "", "\x00\x00\x00\x00" }, + { GCRY_MD_CRC32_RFC1510, "foo", "\x73\x32\xbc\x33" }, + { GCRY_MD_CRC32_RFC1510, "test0123456789", "\xb8\x3e\x88\xd6" }, + { GCRY_MD_CRC32_RFC1510, "MASSACHVSETTS INSTITVTE OF TECHNOLOGY", + "\xe3\x41\x80\xf7" }, +#if 0 + { GCRY_MD_CRC32_RFC1510, "\x80\x00", "\x3b\x83\x98\x4b" }, + { GCRY_MD_CRC32_RFC1510, "\x00\x08", "\x0e\xdb\x88\x32" }, + { GCRY_MD_CRC32_RFC1510, "\x00\x80", "\xed\xb8\x83\x20" }, +#endif + { GCRY_MD_CRC32_RFC1510, "\x80", "\xed\xb8\x83\x20" }, +#if 0 + { GCRY_MD_CRC32_RFC1510, "\x80\x00\x00\x00", "\xed\x59\xb6\x3b" }, + { GCRY_MD_CRC32_RFC1510, "\x00\x00\x00\x01", "\x77\x07\x30\x96" }, +#endif + { GCRY_MD_CRC24_RFC2440, "", "\xb7\x04\xce" }, + { GCRY_MD_CRC24_RFC2440, "foo", "\x4f\xc2\x55" }, + { GCRY_MD_TIGER, "", + "\x24\xF0\x13\x0C\x63\xAC\x93\x32\x16\x16\x6E\x76" + "\xB1\xBB\x92\x5F\xF3\x73\xDE\x2D\x49\x58\x4E\x7A" }, + { GCRY_MD_TIGER, "abc", + "\xF2\x58\xC1\xE8\x84\x14\xAB\x2A\x52\x7A\xB5\x41" + "\xFF\xC5\xB8\xBF\x93\x5F\x7B\x95\x1C\x13\x29\x51" }, + { GCRY_MD_TIGER, "Tiger", + "\x9F\x00\xF5\x99\x07\x23\x00\xDD\x27\x6A\xBB\x38" + "\xC8\xEB\x6D\xEC\x37\x79\x0C\x11\x6F\x9D\x2B\xDF" }, + { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefg" + "hijklmnopqrstuvwxyz0123456789+-", + "\x87\xFB\x2A\x90\x83\x85\x1C\xF7\x47\x0D\x2C\xF8" + "\x10\xE6\xDF\x9E\xB5\x86\x44\x50\x34\xA5\xA3\x86" }, + { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZ=abcdef" + "ghijklmnopqrstuvwxyz+0123456789", + "\x46\x7D\xB8\x08\x63\xEB\xCE\x48\x8D\xF1\xCD\x12" + "\x61\x65\x5D\xE9\x57\x89\x65\x65\x97\x5F\x91\x97" }, + { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " + "by Ross Anderson and Eli Biham", + "\x0C\x41\x0A\x04\x29\x68\x86\x8A\x16\x71\xDA\x5A" + "\x3F\xD2\x9A\x72\x5E\xC1\xE4\x57\xD3\xCD\xB3\x03" }, + { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " + "by Ross Anderson and Eli Biham, proceedings of Fa" + "st Software Encryption 3, Cambridge.", + "\xEB\xF5\x91\xD5\xAF\xA6\x55\xCE\x7F\x22\x89\x4F" + "\xF8\x7F\x54\xAC\x89\xC8\x11\xB6\xB0\xDA\x31\x93" }, + { GCRY_MD_TIGER, "Tiger - A Fast New Hash Function, " + "by Ross Anderson and Eli Biham, proceedings of Fa" + "st Software Encryption 3, Cambridge, 1996.", + "\x3D\x9A\xEB\x03\xD1\xBD\x1A\x63\x57\xB2\x77\x4D" + "\xFD\x6D\x5B\x24\xDD\x68\x15\x1D\x50\x39\x74\xFC" }, + { GCRY_MD_TIGER, "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefgh" + "ijklmnopqrstuvwxyz0123456789+-ABCDEFGHIJKLMNOPQRS" + "TUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+-", + "\x00\xB8\x3E\xB4\xE5\x34\x40\xC5\x76\xAC\x6A\xAE" + "\xE0\xA7\x48\x58\x25\xFD\x15\xE7\x0A\x59\xFF\xE4" }, + + { GCRY_MD_TIGER1, "", + "\x32\x93\xAC\x63\x0C\x13\xF0\x24\x5F\x92\xBB\xB1" + "\x76\x6E\x16\x16\x7A\x4E\x58\x49\x2D\xDE\x73\xF3" }, + { GCRY_MD_TIGER1, "a", + "\x77\xBE\xFB\xEF\x2E\x7E\xF8\xAB\x2E\xC8\xF9\x3B" + "\xF5\x87\xA7\xFC\x61\x3E\x24\x7F\x5F\x24\x78\x09" }, + { GCRY_MD_TIGER1, "abc", + "\x2A\xAB\x14\x84\xE8\xC1\x58\xF2\xBF\xB8\xC5\xFF" + "\x41\xB5\x7A\x52\x51\x29\x13\x1C\x95\x7B\x5F\x93" }, + { GCRY_MD_TIGER1, "message digest", + "\xD9\x81\xF8\xCB\x78\x20\x1A\x95\x0D\xCF\x30\x48" + "\x75\x1E\x44\x1C\x51\x7F\xCA\x1A\xA5\x5A\x29\xF6" }, + { GCRY_MD_TIGER1, "abcdefghijklmnopqrstuvwxyz", + "\x17\x14\xA4\x72\xEE\xE5\x7D\x30\x04\x04\x12\xBF" + "\xCC\x55\x03\x2A\x0B\x11\x60\x2F\xF3\x7B\xEE\xE9" }, + { GCRY_MD_TIGER1, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x0F\x7B\xF9\xA1\x9B\x9C\x58\xF2\xB7\x61\x0D\xF7" + "\xE8\x4F\x0A\xC3\xA7\x1C\x63\x1E\x7B\x53\xF7\x8E" }, + { GCRY_MD_TIGER1, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" "0123456789", + "\x8D\xCE\xA6\x80\xA1\x75\x83\xEE\x50\x2B\xA3\x8A" + "\x3C\x36\x86\x51\x89\x0F\xFB\xCC\xDC\x49\xA8\xCC" }, + { GCRY_MD_TIGER1, + "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890", + "\x1C\x14\x79\x55\x29\xFD\x9F\x20\x7A\x95\x8F\x84" + "\xC5\x2F\x11\xE8\x87\xFA\x0C\xAB\xDF\xD9\x1B\xFD" }, + { GCRY_MD_TIGER1, "!", + "\x6D\xB0\xE2\x72\x9C\xBE\xAD\x93\xD7\x15\xC6\xA7" + "\xD3\x63\x02\xE9\xB3\xCE\xE0\xD2\xBC\x31\x4B\x41" }, + + { GCRY_MD_TIGER2, "", + "\x44\x41\xBE\x75\xF6\x01\x87\x73\xC2\x06\xC2\x27" + "\x45\x37\x4B\x92\x4A\xA8\x31\x3F\xEF\x91\x9F\x41" }, + { GCRY_MD_TIGER2, "a", + "\x67\xE6\xAE\x8E\x9E\x96\x89\x99\xF7\x0A\x23\xE7" + "\x2A\xEA\xA9\x25\x1C\xBC\x7C\x78\xA7\x91\x66\x36" }, + { GCRY_MD_TIGER2, "abc", + "\xF6\x8D\x7B\xC5\xAF\x4B\x43\xA0\x6E\x04\x8D\x78" + "\x29\x56\x0D\x4A\x94\x15\x65\x8B\xB0\xB1\xF3\xBF" }, + { GCRY_MD_TIGER2, "message digest", + "\xE2\x94\x19\xA1\xB5\xFA\x25\x9D\xE8\x00\x5E\x7D" + "\xE7\x50\x78\xEA\x81\xA5\x42\xEF\x25\x52\x46\x2D" }, + { GCRY_MD_TIGER2, "abcdefghijklmnopqrstuvwxyz", + "\xF5\xB6\xB6\xA7\x8C\x40\x5C\x85\x47\xE9\x1C\xD8" + "\x62\x4C\xB8\xBE\x83\xFC\x80\x4A\x47\x44\x88\xFD" }, + { GCRY_MD_TIGER2, + "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\xA6\x73\x7F\x39\x97\xE8\xFB\xB6\x3D\x20\xD2\xDF" + "\x88\xF8\x63\x76\xB5\xFE\x2D\x5C\xE3\x66\x46\xA9" }, + { GCRY_MD_TIGER2, + "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" "0123456789", + "\xEA\x9A\xB6\x22\x8C\xEE\x7B\x51\xB7\x75\x44\xFC" + "\xA6\x06\x6C\x8C\xBB\x5B\xBA\xE6\x31\x95\x05\xCD" }, + { GCRY_MD_TIGER2, + "1234567890" "1234567890" "1234567890" "1234567890" + "1234567890" "1234567890" "1234567890" "1234567890", + "\xD8\x52\x78\x11\x53\x29\xEB\xAA\x0E\xEC\x85\xEC" + "\xDC\x53\x96\xFD\xA8\xAA\x3A\x58\x20\x94\x2F\xFF" }, + { GCRY_MD_TIGER2, "!", + "\xE0\x68\x28\x1F\x06\x0F\x55\x16\x28\xCC\x57\x15" + "\xB9\xD0\x22\x67\x96\x91\x4D\x45\xF7\x71\x7C\xF4" }, + + + { GCRY_MD_WHIRLPOOL, "", + "\x19\xFA\x61\xD7\x55\x22\xA4\x66\x9B\x44\xE3\x9C\x1D\x2E\x17\x26" + "\xC5\x30\x23\x21\x30\xD4\x07\xF8\x9A\xFE\xE0\x96\x49\x97\xF7\xA7" + "\x3E\x83\xBE\x69\x8B\x28\x8F\xEB\xCF\x88\xE3\xE0\x3C\x4F\x07\x57" + "\xEA\x89\x64\xE5\x9B\x63\xD9\x37\x08\xB1\x38\xCC\x42\xA6\x6E\xB3" }, + { GCRY_MD_WHIRLPOOL, "a", + "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" + "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" + "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" + "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, + { GCRY_MD_WHIRLPOOL, "a", + "\x8A\xCA\x26\x02\x79\x2A\xEC\x6F\x11\xA6\x72\x06\x53\x1F\xB7\xD7" + "\xF0\xDF\xF5\x94\x13\x14\x5E\x69\x73\xC4\x50\x01\xD0\x08\x7B\x42" + "\xD1\x1B\xC6\x45\x41\x3A\xEF\xF6\x3A\x42\x39\x1A\x39\x14\x5A\x59" + "\x1A\x92\x20\x0D\x56\x01\x95\xE5\x3B\x47\x85\x84\xFD\xAE\x23\x1A" }, + { GCRY_MD_WHIRLPOOL, + "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789", + "\xDC\x37\xE0\x08\xCF\x9E\xE6\x9B\xF1\x1F\x00\xED\x9A\xBA\x26\x90" + "\x1D\xD7\xC2\x8C\xDE\xC0\x66\xCC\x6A\xF4\x2E\x40\xF8\x2F\x3A\x1E" + "\x08\xEB\xA2\x66\x29\x12\x9D\x8F\xB7\xCB\x57\x21\x1B\x92\x81\xA6" + "\x55\x17\xCC\x87\x9D\x7B\x96\x21\x42\xC6\x5F\x5A\x7A\xF0\x14\x67" }, + { GCRY_MD_WHIRLPOOL, + "!", + "\x0C\x99\x00\x5B\xEB\x57\xEF\xF5\x0A\x7C\xF0\x05\x56\x0D\xDF\x5D" + "\x29\x05\x7F\xD8\x6B\x20\xBF\xD6\x2D\xEC\xA0\xF1\xCC\xEA\x4A\xF5" + "\x1F\xC1\x54\x90\xED\xDC\x47\xAF\x32\xBB\x2B\x66\xC3\x4F\xF9\xAD" + "\x8C\x60\x08\xAD\x67\x7F\x77\x12\x69\x53\xB2\x26\xE4\xED\x8B\x01" }, + { 0 }, + }; + int i; + + if (verbose) + fprintf (stderr, "Starting hash checks.\n"); + + for (i = 0; algos[i].md; i++) + { + if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) + && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + algos[i].md); + continue; + } + if (verbose) + fprintf (stderr, " checking %s [%i] for length %zi\n", + gcry_md_algo_name (algos[i].md), + algos[i].md, + !strcmp (algos[i].data, "!")? + 1000000 : strlen(algos[i].data)); + + check_one_md (algos[i].md, algos[i].data, strlen (algos[i].data), + algos[i].expect); + } + + if (verbose) + fprintf (stderr, "Completed hash checks.\n"); +} + +static void +check_one_hmac (int algo, const char *data, int datalen, + const char *key, int keylen, const char *expect) +{ + gcry_md_hd_t hd, hd2; + unsigned char *p; + int mdlen; + int i; + gcry_error_t err = 0; + + err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); + if (err) + { + fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err)); + return; + } + + mdlen = gcry_md_get_algo_dlen (algo); + if (mdlen < 1 || mdlen > 500) + { + fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen); + return; + } + + gcry_md_setkey( hd, key, keylen ); + + gcry_md_write (hd, data, datalen); + + err = gcry_md_copy (&hd2, hd); + if (err) + { + fail ("algo %d, gcry_md_copy failed: %s\n", algo, gpg_strerror (err)); + } + + gcry_md_close (hd); + + p = gcry_md_read (hd2, algo); + if (!p) + fail("algo %d, hmac gcry_md_read failed\n", algo); + + if (memcmp (p, expect, mdlen)) + { + printf ("computed: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", p[i] & 0xFF); + printf ("\nexpected: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", expect[i] & 0xFF); + printf ("\n"); + + fail ("algo %d, digest mismatch\n", algo); + } + + gcry_md_close (hd2); +} + +static void +check_hmac (void) +{ + static struct algos + { + int md; + const char *data; + const char *key; + const char *expect; + } algos[] = + { + { GCRY_MD_MD5, "what do ya want for nothing?", "Jefe", + "\x75\x0c\x78\x3e\x6a\xb0\xb5\x03\xea\xa8\x6e\x31\x0a\x5d\xb7\x38" }, + { GCRY_MD_MD5, + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", + "\x92\x94\x72\x7a\x36\x38\xbb\x1c\x13\xf4\x8e\xf8\x15\x8b\xfc\x9d" }, + { GCRY_MD_MD5, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA", + "\x56\xbe\x34\x52\x1d\x14\x4c\x88\xdb\xb8\xc7\x33\xf0\xe8\xb3\xf6" }, + { GCRY_MD_MD5, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\x69\x7e\xaf\x0a\xca\x3a\x3a\xea\x3a\x75\x16\x47\x46\xff\xaa\x79" }, + { GCRY_MD_MD5, "Test With Truncation", + "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c", + "\x56\x46\x1e\xf2\x34\x2e\xdc\x00\xf9\xba\xb9\x95\x69\x0e\xfd\x4c" }, + { GCRY_MD_MD5, "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa", + "\x6b\x1a\xb7\xfe\x4b\xd7\xbf\x8f\x0b\x62\xe6\xce\x61\xb9\xd0\xcd" }, + { GCRY_MD_MD5, + "Test Using Larger Than Block-Size Key and Larger Than One Block-Size Data", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa", + "\x6f\x63\x0f\xad\x67\xcd\xa0\xee\x1f\xb1\xf5\x62\xdb\x3a\xa5\x3e", }, + { GCRY_MD_SHA256, "what do ya want for nothing?", "Jefe", + "\x5b\xdc\xc1\x46\xbf\x60\x75\x4e\x6a\x04\x24\x26\x08\x95\x75\xc7\x5a" + "\x00\x3f\x08\x9d\x27\x39\x83\x9d\xec\x58\xb9\x64\xec\x38\x43" }, + { GCRY_MD_SHA256, + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "\xb0\x34\x4c\x61\xd8\xdb\x38\x53\x5c\xa8\xaf\xce\xaf\x0b\xf1\x2b\x88" + "\x1d\xc2\x00\xc9\x83\x3d\xa7\x26\xe9\x37\x6c\x2e\x32\xcf\xf7" }, + { GCRY_MD_SHA256, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA", + "\x77\x3e\xa9\x1e\x36\x80\x0e\x46\x85\x4d\xb8\xeb\xd0\x91\x81\xa7" + "\x29\x59\x09\x8b\x3e\xf8\xc1\x22\xd9\x63\x55\x14\xce\xd5\x65\xfe" }, + { GCRY_MD_SHA256, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\x82\x55\x8a\x38\x9a\x44\x3c\x0e\xa4\xcc\x81\x98\x99\xf2\x08" + "\x3a\x85\xf0\xfa\xa3\xe5\x78\xf8\x07\x7a\x2e\x3f\xf4\x67\x29\x66\x5b" }, + { GCRY_MD_SHA256, + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x60\xe4\x31\x59\x1e\xe0\xb6\x7f\x0d\x8a\x26\xaa\xcb\xf5\xb7\x7f" + "\x8e\x0b\xc6\x21\x37\x28\xc5\x14\x05\x46\x04\x0f\x0e\xe3\x7f\x54" }, + { GCRY_MD_SHA256, + "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x9b\x09\xff\xa7\x1b\x94\x2f\xcb\x27\x63\x5f\xbc\xd5\xb0\xe9\x44" + "\xbf\xdc\x63\x64\x4f\x07\x13\x93\x8a\x7f\x51\x53\x5c\x3a\x35\xe2" }, + { GCRY_MD_SHA224, "what do ya want for nothing?", "Jefe", + "\xa3\x0e\x01\x09\x8b\xc6\xdb\xbf\x45\x69\x0f\x3a\x7e\x9e\x6d\x0f" + "\x8b\xbe\xa2\xa3\x9e\x61\x48\x00\x8f\xd0\x5e\x44" }, + { GCRY_MD_SHA224, + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "\x89\x6f\xb1\x12\x8a\xbb\xdf\x19\x68\x32\x10\x7c\xd4\x9d\xf3\x3f\x47" + "\xb4\xb1\x16\x99\x12\xba\x4f\x53\x68\x4b\x22" }, + { GCRY_MD_SHA224, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA", + "\x7f\xb3\xcb\x35\x88\xc6\xc1\xf6\xff\xa9\x69\x4d\x7d\x6a\xd2\x64" + "\x93\x65\xb0\xc1\xf6\x5d\x69\xd1\xec\x83\x33\xea" }, + { GCRY_MD_SHA224, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\x6c\x11\x50\x68\x74\x01\x3c\xac\x6a\x2a\xbc\x1b\xb3\x82\x62" + "\x7c\xec\x6a\x90\xd8\x6e\xfc\x01\x2d\xe7\xaf\xec\x5a" }, + { GCRY_MD_SHA224, + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x95\xe9\xa0\xdb\x96\x20\x95\xad\xae\xbe\x9b\x2d\x6f\x0d\xbc\xe2" + "\xd4\x99\xf1\x12\xf2\xd2\xb7\x27\x3f\xa6\x87\x0e" }, + { GCRY_MD_SHA224, + "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x3a\x85\x41\x66\xac\x5d\x9f\x02\x3f\x54\xd5\x17\xd0\xb3\x9d\xbd" + "\x94\x67\x70\xdb\x9c\x2b\x95\xc9\xf6\xf5\x65\xd1" }, + { GCRY_MD_SHA384, "what do ya want for nothing?", "Jefe", + "\xaf\x45\xd2\xe3\x76\x48\x40\x31\x61\x7f\x78\xd2\xb5\x8a\x6b\x1b" + "\x9c\x7e\xf4\x64\xf5\xa0\x1b\x47\xe4\x2e\xc3\x73\x63\x22\x44\x5e" + "\x8e\x22\x40\xca\x5e\x69\xe2\xc7\x8b\x32\x39\xec\xfa\xb2\x16\x49" }, + { GCRY_MD_SHA384, + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "\xaf\xd0\x39\x44\xd8\x48\x95\x62\x6b\x08\x25\xf4\xab\x46\x90\x7f\x15" + "\xf9\xda\xdb\xe4\x10\x1e\xc6\x82\xaa\x03\x4c\x7c\xeb\xc5\x9c\xfa\xea" + "\x9e\xa9\x07\x6e\xde\x7f\x4a\xf1\x52\xe8\xb2\xfa\x9c\xb6" }, + { GCRY_MD_SHA384, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA", + "\x88\x06\x26\x08\xd3\xe6\xad\x8a\x0a\xa2\xac\xe0\x14\xc8\xa8\x6f" + "\x0a\xa6\x35\xd9\x47\xac\x9f\xeb\xe8\x3e\xf4\xe5\x59\x66\x14\x4b" + "\x2a\x5a\xb3\x9d\xc1\x38\x14\xb9\x4e\x3a\xb6\xe1\x01\xa3\x4f\x27" }, + { GCRY_MD_SHA384, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\x3e\x8a\x69\xb7\x78\x3c\x25\x85\x19\x33\xab\x62\x90\xaf\x6c\xa7" + "\x7a\x99\x81\x48\x08\x50\x00\x9c\xc5\x57\x7c\x6e\x1f\x57\x3b\x4e" + "\x68\x01\xdd\x23\xc4\xa7\xd6\x79\xcc\xf8\xa3\x86\xc6\x74\xcf\xfb" }, + { GCRY_MD_SHA384, + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x4e\xce\x08\x44\x85\x81\x3e\x90\x88\xd2\xc6\x3a\x04\x1b\xc5\xb4" + "\x4f\x9e\xf1\x01\x2a\x2b\x58\x8f\x3c\xd1\x1f\x05\x03\x3a\xc4\xc6" + "\x0c\x2e\xf6\xab\x40\x30\xfe\x82\x96\x24\x8d\xf1\x63\xf4\x49\x52" }, + { GCRY_MD_SHA384, + "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x66\x17\x17\x8e\x94\x1f\x02\x0d\x35\x1e\x2f\x25\x4e\x8f\xd3\x2c" + "\x60\x24\x20\xfe\xb0\xb8\xfb\x9a\xdc\xce\xbb\x82\x46\x1e\x99\xc5" + "\xa6\x78\xcc\x31\xe7\x99\x17\x6d\x38\x60\xe6\x11\x0c\x46\x52\x3e" }, + { GCRY_MD_SHA512, "what do ya want for nothing?", "Jefe", + "\x16\x4b\x7a\x7b\xfc\xf8\x19\xe2\xe3\x95\xfb\xe7\x3b\x56\xe0\xa3" + "\x87\xbd\x64\x22\x2e\x83\x1f\xd6\x10\x27\x0c\xd7\xea\x25\x05\x54" + "\x97\x58\xbf\x75\xc0\x5a\x99\x4a\x6d\x03\x4f\x65\xf8\xf0\xe6\xfd" + "\xca\xea\xb1\xa3\x4d\x4a\x6b\x4b\x63\x6e\x07\x0a\x38\xbc\xe7\x37" }, + { GCRY_MD_SHA512, + "Hi There", + "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" + "\x0b\x0b\x0b", + "\x87\xaa\x7c\xde\xa5\xef\x61\x9d\x4f\xf0\xb4\x24\x1a\x1d\x6c\xb0" + "\x23\x79\xf4\xe2\xce\x4e\xc2\x78\x7a\xd0\xb3\x05\x45\xe1\x7c\xde" + "\xda\xa8\x33\xb7\xd6\xb8\xa7\x02\x03\x8b\x27\x4e\xae\xa3\xf4\xe4" + "\xbe\x9d\x91\x4e\xeb\x61\xf1\x70\x2e\x69\x6c\x20\x3a\x12\x68\x54" }, + { GCRY_MD_SHA512, + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" + "\xdd\xdd\xdd\xdd\xdd", + "\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA\xAA" + "\xAA\xAA\xAA\xAA", + "\xfa\x73\xb0\x08\x9d\x56\xa2\x84\xef\xb0\xf0\x75\x6c\x89\x0b\xe9" + "\xb1\xb5\xdb\xdd\x8e\xe8\x1a\x36\x55\xf8\x3e\x33\xb2\x27\x9d\x39" + "\xbf\x3e\x84\x82\x79\xa7\x22\xc8\x06\xb4\x85\xa4\x7e\x67\xc8\x07" + "\xb9\x46\xa3\x37\xbe\xe8\x94\x26\x74\x27\x88\x59\xe1\x32\x92\xfb" }, + { GCRY_MD_SHA512, + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd" + "\xcd\xcd\xcd\xcd\xcd", + "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f" + "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19", + "\xb0\xba\x46\x56\x37\x45\x8c\x69\x90\xe5\xa8\xc5\xf6\x1d\x4a\xf7" + "\xe5\x76\xd9\x7f\xf9\x4b\x87\x2d\xe7\x6f\x80\x50\x36\x1e\xe3\xdb" + "\xa9\x1c\xa5\xc1\x1a\xa2\x5e\xb4\xd6\x79\x27\x5c\xc5\x78\x80\x63" + "\xa5\xf1\x97\x41\x12\x0c\x4f\x2d\xe2\xad\xeb\xeb\x10\xa2\x98\xdd" }, + { GCRY_MD_SHA512, + "Test Using Larger Than Block-Size Key - Hash Key First", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\x80\xb2\x42\x63\xc7\xc1\xa3\xeb\xb7\x14\x93\xc1\xdd\x7b\xe8\xb4" + "\x9b\x46\xd1\xf4\x1b\x4a\xee\xc1\x12\x1b\x01\x37\x83\xf8\xf3\x52" + "\x6b\x56\xd0\x37\xe0\x5f\x25\x98\xbd\x0f\xd2\x21\x5d\x6a\x1e\x52" + "\x95\xe6\x4f\x73\xf6\x3f\x0a\xec\x8b\x91\x5a\x98\x5d\x78\x65\x98" }, + { GCRY_MD_SHA512, + "This is a test using a larger than block-size key and a larger than block-size data. The key needs to be hashed before being used by the HMAC algorithm.", + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" + "\xaa\xaa\xaa", + "\xe3\x7b\x6a\x77\x5d\xc8\x7d\xba\xa4\xdf\xa9\xf9\x6e\x5e\x3f\xfd" + "\xde\xbd\x71\xf8\x86\x72\x89\x86\x5d\xf5\xa3\x2d\x20\xcd\xc9\x44" + "\xb6\x02\x2c\xac\x3c\x49\x82\xb1\x0d\x5e\xeb\x55\xc3\xe4\xde\x15" + "\x13\x46\x76\xfb\x6d\xe0\x44\x60\x65\xc9\x74\x40\xfa\x8c\x6a\x58" }, + { 0 }, + }; + int i; + + if (verbose) + fprintf (stderr, "Starting hashed MAC checks.\n"); + + for (i = 0; algos[i].md; i++) + { + if ((gcry_md_test_algo (algos[i].md) || algos[i].md == GCRY_MD_MD5) + && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + algos[i].md); + continue; + } + if (verbose) + fprintf (stderr, + " checking %s [%i] for %zi byte key and %zi byte data\n", + gcry_md_algo_name (algos[i].md), + algos[i].md, + strlen(algos[i].key), strlen(algos[i].data)); + + check_one_hmac (algos[i].md, algos[i].data, strlen (algos[i].data), + algos[i].key, strlen(algos[i].key), + algos[i].expect); + } + + if (verbose) + fprintf (stderr, "Completed hashed MAC checks.\n"); + } + +/* Check that the signature SIG matches the hash HASH. PKEY is the + public key used for the verification. BADHASH is a hasvalue which + should; result in a bad signature status. */ +static void +verify_one_signature (gcry_sexp_t pkey, gcry_sexp_t hash, + gcry_sexp_t badhash, gcry_sexp_t sig) +{ + gcry_error_t rc; + + rc = gcry_pk_verify (sig, hash, pkey); + if (rc) + fail ("gcry_pk_verify failed: %s\n", gpg_strerror (rc)); + rc = gcry_pk_verify (sig, badhash, pkey); + if (gcry_err_code (rc) != GPG_ERR_BAD_SIGNATURE) + fail ("gcry_pk_verify failed to detect a bad signature: %s\n", + gpg_strerror (rc)); +} + + +/* Test the public key sign function using the private ket SKEY. PKEY + is used for verification. */ +static void +check_pubkey_sign (int n, gcry_sexp_t skey, gcry_sexp_t pkey) +{ + gcry_error_t rc; + gcry_sexp_t sig, badhash, hash; + int dataidx; + static const char baddata[] = + "(data\n (flags pkcs1)\n" + " (hash sha1 #11223344556677889900AABBCCDDEEFF10203041#))\n"; + static struct + { + const char *data; + int expected_rc; + } datas[] = + { + { "(data\n (flags pkcs1)\n" + " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", + 0 }, + /* This test is to see whether hash algorithms not hard wired in + pubkey.c are detected: */ + { "(data\n (flags pkcs1)\n" + " (hash oid.1.3.14.3.2.29 " + " #11223344556677889900AABBCCDDEEFF10203040#))\n", + 0 }, + { "(data\n (flags )\n" + " (hash sha1 #11223344556677889900AABBCCDDEEFF10203040#))\n", + GPG_ERR_CONFLICT }, + { "(data\n (flags pkcs1)\n" + " (hash foo #11223344556677889900AABBCCDDEEFF10203040#))\n", + GPG_ERR_DIGEST_ALGO }, + { "(data\n (flags )\n" " (value #11223344556677889900AA#))\n", + 0 }, + { "(data\n (flags )\n" " (value #0090223344556677889900AA#))\n", + 0 }, + { "(data\n (flags raw)\n" " (value #11223344556677889900AA#))\n", + 0 }, + { "(data\n (flags pkcs1)\n" + " (value #11223344556677889900AA#))\n", + GPG_ERR_CONFLICT }, + { "(data\n (flags raw foo)\n" + " (value #11223344556677889900AA#))\n", + GPG_ERR_INV_FLAG }, + { NULL } + }; + + (void)n; + + rc = gcry_sexp_sscan (&badhash, NULL, baddata, strlen (baddata)); + if (rc) + die ("converting data failed: %s\n", gpg_strerror (rc)); + + for (dataidx = 0; datas[dataidx].data; dataidx++) + { + if (verbose) + fprintf (stderr, " signature test %d\n", dataidx); + + rc = gcry_sexp_sscan (&hash, NULL, datas[dataidx].data, + strlen (datas[dataidx].data)); + if (rc) + die ("converting data failed: %s\n", gpg_strerror (rc)); + + rc = gcry_pk_sign (&sig, hash, skey); + if (gcry_err_code (rc) != datas[dataidx].expected_rc) + fail ("gcry_pk_sign failed: %s\n", gpg_strerror (rc)); + + if (!rc) + verify_one_signature (pkey, hash, badhash, sig); + + gcry_sexp_release (sig); + sig = NULL; + gcry_sexp_release (hash); + hash = NULL; + } + + gcry_sexp_release (badhash); +} + +static void +check_pubkey_grip (int n, const unsigned char *grip, + gcry_sexp_t skey, gcry_sexp_t pkey) +{ + unsigned char sgrip[20], pgrip[20]; + + if (!gcry_pk_get_keygrip (skey, sgrip)) + die ("get keygrip for private RSA key failed\n"); + if (!gcry_pk_get_keygrip (pkey, pgrip)) + die ("[%i] get keygrip for public RSA key failed\n", n); + if (memcmp (sgrip, pgrip, 20)) + fail ("[%i] keygrips don't match\n", n); + if (memcmp (sgrip, grip, 20)) + fail ("wrong keygrip for RSA key\n"); +} + +static void +do_check_one_pubkey (int n, gcry_sexp_t skey, gcry_sexp_t pkey, + const unsigned char *grip, int flags) +{ + if (flags & FLAG_SIGN) + check_pubkey_sign (n, skey, pkey); + if (grip && (flags & FLAG_GRIP)) + check_pubkey_grip (n, grip, skey, pkey); +} + +static void +check_one_pubkey (int n, test_spec_pubkey_t spec) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_sexp_t skey, pkey; + + err = gcry_sexp_sscan (&skey, NULL, spec.key.secret, + strlen (spec.key.secret)); + if (!err) + err = gcry_sexp_sscan (&pkey, NULL, spec.key.public, + strlen (spec.key.public)); + if (err) + die ("converting sample key failed: %s\n", gpg_strerror (err)); + + do_check_one_pubkey (n, skey, pkey, + (const unsigned char*)spec.key.grip, spec.flags); + + gcry_sexp_release (skey); + gcry_sexp_release (pkey); +} + +static void +get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + if (verbose) + fprintf (stderr, " generating RSA key:"); + rc = gcry_sexp_new (&key_spec, + in_fips_mode ? "(genkey (rsa (nbits 4:1024)))" + : "(genkey (rsa (nbits 4:1024)(transient-key)))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating RSA key: %s\n", gpg_strerror (rc)); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (! pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (! sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + +static void +check_one_pubkey_new (int n) +{ + gcry_sexp_t skey, pkey; + + get_keys_new (&pkey, &skey); + do_check_one_pubkey (n, skey, pkey, NULL, FLAG_SIGN | FLAG_CRYPT); +} + +/* Run all tests for the public key functions. */ +static void +check_pubkey (void) +{ + test_spec_pubkey_t pubkeys[] = + { + { + GCRY_PK_RSA, FLAG_CRYPT | FLAG_SIGN, + + { "(private-key\n" + " (rsa\n" + " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" + " (e #010001#)\n" + " (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" + " 7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" + " C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" + " C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" + " (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" + " fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" + " (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" + " 35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n" + " (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" + " ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))\n", + + "(public-key\n" + " (rsa\n" + " (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + " 2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + " ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + " 891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" + " (e #010001#)))\n", + + "\x32\x10\x0c\x27\x17\x3e\xf6\xe9\xc4\xe9" + "\xa2\x5d\x3d\x69\xf8\x6d\x37\xa4\xf9\x39"} + }, + { + GCRY_PK_DSA, FLAG_SIGN, + + { "(private-key\n" + " (DSA\n" + " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" + " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" + " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" + " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n" + " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" + " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" + " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" + " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" + " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n" + " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" + " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" + " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" + " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)\n" + " (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))\n", + + "(public-key\n" + " (DSA\n" + " (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB" + " 96273899DD8B2BB46CD6ECA263FAF04A28903503D59062A8865D2AE8ADFB5191" + " CF36FFB562D0E2F5809801A1F675DAE59698A9E01EFE8D7DCFCA084F4C6F5A44" + " 44D499A06FFAEA5E8EF5E01F2FD20A7B7EF3F6968AFBA1FB8D91F1559D52D8777B#)\n" + " (q #00EB7B5751D25EBBB7BD59D920315FD840E19AEBF9#)\n" + " (g #1574363387FDFD1DDF38F4FBE135BB20C7EE4772FB94C337AF86EA8E49666503" + " AE04B6BE81A2F8DD095311E0217ACA698A11E6C5D33CCDAE71498ED35D13991E" + " B02F09AB40BD8F4C5ED8C75DA779D0AE104BC34C960B002377068AB4B5A1F984" + " 3FBA91F537F1B7CAC4D8DD6D89B0D863AF7025D549F9C765D2FC07EE208F8D15#)\n" + " (y #64B11EF8871BE4AB572AA810D5D3CA11A6CDBC637A8014602C72960DB135BF46" + " A1816A724C34F87330FC9E187C5D66897A04535CC2AC9164A7150ABFA8179827" + " 6E45831AB811EEE848EBB24D9F5F2883B6E5DDC4C659DEF944DCFD80BF4D0A20" + " 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)))\n", + + "\xc6\x39\x83\x1a\x43\xe5\x05\x5d\xc6\xd8" + "\x4a\xa6\xf9\xeb\x23\xbf\xa9\x12\x2d\x5b" } + }, + { + GCRY_PK_ELG, FLAG_SIGN | FLAG_CRYPT, + + { "(private-key\n" + " (ELG\n" + " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" + " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" + " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" + " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n" + " (g #05#)\n" + " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" + " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" + " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" + " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)\n" + " (x #03C28900087B38DABF4A0AB98ACEA39BB674D6557096C01D72E31C16BDD32214#)))\n", + + "(public-key\n" + " (ELG\n" + " (p #00B93B93386375F06C2D38560F3B9C6D6D7B7506B20C1773F73F8DE56E6CD65D" + " F48DFAAA1E93F57A2789B168362A0F787320499F0B2461D3A4268757A7B27517" + " B7D203654A0CD484DEC6AF60C85FEB84AAC382EAF2047061FE5DAB81A20A0797" + " 6E87359889BAE3B3600ED718BE61D4FC993CC8098A703DD0DC942E965E8F18D2A7#)\n" + " (g #05#)\n" + " (y #72DAB3E83C9F7DD9A931FDECDC6522C0D36A6F0A0FEC955C5AC3C09175BBFF2B" + " E588DB593DC2E420201BEB3AC17536918417C497AC0F8657855380C1FCF11C5B" + " D20DB4BEE9BDF916648DE6D6E419FA446C513AAB81C30CB7B34D6007637BE675" + " 56CE6473E9F9EE9B9FADD275D001563336F2186F424DEC6199A0F758F6A00FF4#)))\n", + + "\xa7\x99\x61\xeb\x88\x83\xd2\xf4\x05\xc8" + "\x4f\xba\x06\xf8\x78\x09\xbc\x1e\x20\xe5" } + }, + }; + int i; + if (verbose) + fprintf (stderr, "Starting public key checks.\n"); + for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) + if (pubkeys[i].id) + { + if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + pubkeys[i].id); + continue; + } + check_one_pubkey (i, pubkeys[i]); + } + if (verbose) + fprintf (stderr, "Completed public key checks.\n"); + + if (verbose) + fprintf (stderr, "Starting additional public key checks.\n"); + for (i = 0; i < sizeof (pubkeys) / sizeof (*pubkeys); i++) + if (pubkeys[i].id) + { + if (gcry_pk_test_algo (pubkeys[i].id) && in_fips_mode) + { + if (verbose) + fprintf (stderr, " algorithm %d not available in fips mode\n", + pubkeys[i].id); + continue; + } + check_one_pubkey_new (i); + } + if (verbose) + fprintf (stderr, "Completed additional public key checks.\n"); + +} + +int +main (int argc, char **argv) +{ + gpg_error_t err; + int last_argc = -1; + int debug = 0; + int use_fips = 0; + int selftest_only = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--fips")) + { + use_fips = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--selftest")) + { + selftest_only = 1; + verbose += 2; + argc--; argv++; + } + } + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); + + if (use_fips) + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + if ( gcry_fips_mode_active () ) + in_fips_mode = 1; + + if (!in_fips_mode) + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + + if (verbose) + gcry_set_progress_handler (progress_handler, NULL); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + + if (!selftest_only) + { + check_ciphers (); + check_aes128_cbc_cts_cipher (); + check_cbc_mac_cipher (); + check_ctr_cipher (); + check_cfb_cipher (); + check_ofb_cipher (); + check_digests (); + check_hmac (); + check_pubkey (); + } + + + if (in_fips_mode && !selftest_only) + { + /* If we are in fips mode do some more tests. */ + gcry_md_hd_t md; + + /* First trigger a self-test. */ + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("not in operational state after self-test\n"); + + /* Get us into the error state. */ + err = gcry_md_open (&md, GCRY_MD_SHA1, 0); + if (err) + fail ("failed to open SHA-1 hash context: %s\n", gpg_strerror (err)); + else + { + err = gcry_md_enable (md, GCRY_MD_SHA256); + if (err) + fail ("failed to add SHA-256 hash context: %s\n", + gpg_strerror (err)); + else + { + /* gcry_md_get_algo is only defined for a context with + just one digest algorithm. With our setup it should + put the oibrary intoerror state. */ + fputs ("Note: Two lines with error messages follow " + "- this is expected\n", stderr); + gcry_md_get_algo (md); + gcry_md_close (md); + if (gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("expected error state but still in operational state\n"); + else + { + /* Now run a self-test and to get back into + operational state. */ + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_control (GCRYCTL_OPERATIONAL_P, 0)) + fail ("did not reach operational after error " + "and self-test\n"); + } + } + } + + } + else + { + /* If in standard mode, run selftests. */ + if (gcry_control (GCRYCTL_SELFTEST, 0)) + fail ("running self-test failed\n"); + } + + if (verbose) + fprintf (stderr, "\nAll tests completed. Errors: %i\n", error_count); + + if (in_fips_mode && !gcry_fips_mode_active ()) + fprintf (stderr, "FIPS mode is not anymore active\n"); + + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/benchmark.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/benchmark.c new file mode 100644 index 0000000000..8f8f04ce16 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/benchmark.c @@ -0,0 +1,1158 @@ +/* benchmark.c - for libgcrypt + * Copyright (C) 2002, 2004, 2005, 2006, 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <time.h> +#include <stdarg.h> +#ifdef _WIN32 +#include <windows.h> +#else +#include <sys/times.h> +#endif + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include <gcrypt.h> +#endif + + +#define PGM "benchmark" + +static int verbose; + +/* Do encryption tests with large buffers. */ +static int large_buffers; + +/* Number of cipher repetitions. */ +static int cipher_repetitions; + +/* Whether fips mode was active at startup. */ +static int in_fips_mode; + + +static const char sample_private_dsa_key_1024[] = +"(private-key\n" +" (dsa\n" +" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685" + "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A" + "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF" + "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n" +" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n" +" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622" + "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312" + "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3" + "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n" +" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4" + "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6" + "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155" + "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n" +" (x #4186F8A58C5DF46C5BCFC7006BEEBF05E93C0CA7#)\n" +"))\n"; + +static const char sample_public_dsa_key_1024[] = +"(public-key\n" +" (dsa\n" +" (p #00A126202D592214C5A8F6016E2C3F4256052ACB1CB17D88E64B1293FAF08F5E4685" + "03E6F68366B326A56284370EB2103E92D8346A163E44A08FDC422AC8E9E44268557A" + "853539A6AF39353A59CE5E78FD98B57D0F3E3A7EBC8A256AC9A775BA59689F3004BF" + "C3035730C4C0C51626C5D7F5852637EC589BB29DAB46C161572E4B#)\n" +" (q #00DEB5A296421887179ECA1762884DE2AF8185AFC5#)\n" +" (g #3958B34AE7747194ECBD312F8FEE8CBE3918E94DF9FD11E2912E56318F33BDC38622" + "B18DDFF393074BCA8BAACF50DF27AEE529F3E8AEECE55C398DAB3A5E04C2EA142312" + "FACA2FE7F0A88884F8DAC3979EE67598F9A383B2A2325F035C796F352A5C3CDF2CB3" + "85AD24EC52A6E55247E1BB37D260F79E617D2A4446415B6AD79A#)\n" +" (y #519E9FE9AB0545A6724E74603B7B04E48DC1437E0284A11EA605A7BA8AB1CF354FD4" + "ECC93880AC293391C69B558AD84E7AAFA88F11D028CF3A378F241D6B056A90C588F6" + "66F68D27262B4DA84657D15057D371BCEC1F6504032507D5B881E45FC93A1B973155" + "D91C57219D090C3ACD75E7C2B9F1176A208AC03D6C12AC28A271#)\n" +"))\n"; + + +static const char sample_private_dsa_key_2048[] = +"(private-key\n" +" (dsa\n" +" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365" + "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C" + "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150" + "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970" + "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405" + "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179" + "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4" + "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n" +" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n" +" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78" + "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3" + "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F" + "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508" + "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F" + "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44" + "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3" + "6EE4425A553AF8885FEA15A88135BE133520#)\n" +" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C" + "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB" + "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79" + "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F" + "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3" + "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923" + "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7" + "14A264330AECCB24DE2A1107847B23490897#)\n" +" (x #477BD14676E22563C5ABA68025CEBA2A48D485F5B2D4AD4C0EBBD6D0#)\n" +"))\n"; + + +static const char sample_public_dsa_key_2048[] = +"(public-key\n" +" (dsa\n" +" (p #00B54636673962B64F7DC23C71ACEF6E7331796F607560B194DFCC0CA370E858A365" + "A413152FB6EB8C664BD171AC316FE5B381CD084D07377571599880A068EF1382D85C" + "308B4E9DEAC12D66DE5C4A826EBEB5ED94A62E7301E18927E890589A2F230272A150" + "C118BC3DC2965AE0D05BE4F65C6137B2BA7EDABB192C3070D202C10AA3F534574970" + "71454DB8A73DDB6511A5BA98EF1450FD90DE5BAAFC9FD3AC22EBEA612DD075BB7405" + "D56866D125E33982C046808F7CEBA8E5C0B9F19A6FE451461660A1CBA9EF68891179" + "0256A573D3B8F35A5C7A0C6C31F2DB90E25A26845252AD9E485EF2D339E7B5890CD4" + "2F9C9F315ED409171EC35CA04CC06B275577B3#)\n" +" (q #00DA67989167FDAC4AE3DF9247A716859A30C0CF9C5A6DBA01EABA3481#)\n" +" (g #48E35DA584A089D05142AA63603FDB00D131B07A0781E2D5A8F9614D2B33D3E40A78" + "98A9E10CDBB612CF093F95A3E10D09566726F2C12823836B2D9CD974BB695665F3B3" + "5D219A9724B87F380BD5207EDA0AE38C79E8F18122C3F76E4CEB0ABED3250914987F" + "B30D4B9E19C04C28A5D4F45560AF586F6A1B41751EAD90AE7F044F4E2A4A50C1F508" + "4FC202463F478F678B9A19392F0D2961C5391C546EF365368BB46410C9C1CEE96E9F" + "0C953570C2ED06328B11C90E86E57CAA7FA5ABAA278E22A4C8C08E16EE59F484EC44" + "2CF55535BAA2C6BEA8833A555372BEFE1E665D3C7DAEF58061D5136331EF4EB61BC3" + "6EE4425A553AF8885FEA15A88135BE133520#)\n" +" (y #66E0D1A69D663466F8FEF2B7C0878DAC93C36A2FB2C05E0306A53B926021D4B92A1C" + "2FA6860061E88E78CBBBA49B0E12700F07DBF86F72CEB2927EDAC0C7E3969C3A47BB" + "4E0AE93D8BB3313E93CC7A72DFEEE442EFBC81B3B2AEC9D8DCBE21220FB760201D79" + "328C41C773866587A44B6954767D022A88072900E964089D9B17133603056C985C4F" + "8A0B648F297F8D2C3CB43E4371DC6002B5B12CCC085BDB2CFC5074A0587566187EE3" + "E11A2A459BD94726248BB8D6CC62938E11E284C2C183576FBB51749EB238C4360923" + "79C08CE1C8CD77EB57404CE9B4744395ACF721487450BADE3220576F2F816248B0A7" + "14A264330AECCB24DE2A1107847B23490897#)\n" +"))\n"; + + +static const char sample_private_dsa_key_3072[] = +"(private-key\n" +" (dsa\n" +" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938" + "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5" + "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83" + "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988" + "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46" + "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2" + "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902" + "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60" + "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E" + "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7" + "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33" + "8015353D3778B02B892AF7#)\n" +" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n" +" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4" + "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474" + "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98" + "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC" + "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C" + "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89" + "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB" + "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6" + "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0" + "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F" + "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC" + "4997AF9EB55C6660B01A#)\n" +" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE" + "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053" + "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492" + "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15" + "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71" + "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997" + "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026" + "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B" + "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD" + "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765" + "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561" + "2703D518D8D49FF0EBE6#)\n" +" (x #00A9FFFC88E67D6F7B810E291C050BAFEA7FC4A75E8D2F16CFED3416FD77607232#)\n" +"))\n"; + +static const char sample_public_dsa_key_3072[] = +"(public-key\n" +" (dsa\n" +" (p #00BA73E148AEA5E8B64878AF5BE712B8302B9671C5F3EEB7722A9D0D9868D048C938" + "877C91C335C7819292E69C7D34264F1578E32EC2DA8408DF75D0EB76E0D3030B84B5" + "62D8EF93AB53BAB6B8A5DE464F5CA87AEA43BDCF0FB0B7815AA3114CFC84FD916A83" + "B3D5FD78390189332232E9D037D215313FD002FF46C048B66703F87FAE092AAA0988" + "AC745336EBE672A01DEDBD52395783579B67CF3AE1D6F1602CCCB12154FA0E00AE46" + "0D9B289CF709194625BCB919B11038DEFC50ADBBA20C3F320078E4E9529B4F6848E2" + "AB5E6278DB961FE226F2EEBD201E071C48C5BEF98B4D9BEE42C1C7102D893EBF8902" + "D7A91266340AFD6CE1D09E52282FFF5B97EAFA3886A3FCF84FF76D1E06538D0D8E60" + "B3332145785E07D29A5965382DE3470D1D888447FA9C00A2373378FC3FA7B9F7D17E" + "95A6A5AE1397BE46D976EF2C96E89913AC4A09351CA661BF6F67E30407DA846946C7" + "62D9BAA6B77825097D3E7B886456BB32E3E74516BF3FD93D71B257AA8F723E01CE33" + "8015353D3778B02B892AF7#)\n" +" (q #00BFF3F3CC18FA018A5B8155A8695E1E4939660D5E4759322C39D50F3B93E5F68B#)\n" +" (g #6CCFD8219F5FCE8EF2BEF3262929787140847E38674B1EF8DB20255E212CB6330EC4" + "DFE8A26AB7ECC5760DEB9BBF59A2B2821D510F1868172222867558B8D204E889C474" + "7CA30FBF9D8CF41AE5D5BD845174641101593849FF333E6C93A6550931B2B9D56B98" + "9CAB01729D9D736FA6D24A74D2DDE1E9E648D141473E443DD6BBF0B3CAB64F9FE4FC" + "134B2EB57437789F75C744DF1FA67FA8A64603E5441BC7ECE29E00BDF262BDC81E8C" + "7330A18A412DE38E7546D342B89A0AF675A89E6BEF00540EB107A2FE74EA402B0D89" + "F5C02918DEEEAF8B8737AC866B09B50810AB8D8668834A1B9E1E53866E2B0A926FAB" + "120A0CDE5B3715FFFE6ACD1AB73588DCC1EC4CE9392FE57F8D1D35811200CB07A0E6" + "374E2C4B0AEB7E3D077B8545C0E438DCC0F1AE81E186930E99EBC5B91B77E92803E0" + "21602887851A4FFDB3A7896AC655A0901218C121C5CBB0931E7D5EAC243F37711B5F" + "D5A62B1B38A83F03D8F6703D8B98DF367FC8A76990335F62173A5391836F0F2413EC" + "4997AF9EB55C6660B01A#)\n" +" (y #2320B22434C5DB832B4EC267CC52E78DD5CCFA911E8F0804E7E7F32B186B2D4167AE" + "4AA6869822E76400492D6A193B0535322C72B0B7AA4A87E33044FDC84BE24C64A053" + "A37655EE9EABDCDC1FDF63F3F1C677CEB41595DF7DEFE9178D85A3D621B4E4775492" + "8C0A58D2458D06F9562E4DE2FE6129A64063A99E88E54485B97484A28188C4D33F15" + "DDC903B6CEA0135E3E3D27B4EA39319696305CE93D7BA7BE00367DBE3AAF43491E71" + "CBF254744A5567F5D70090D6139E0C990239627B3A1C5B20B6F9F6374B8D8D8A8997" + "437265BE1E3B4810D4B09254400DE287A0DFFBAEF339E48D422B1D41A37E642BC026" + "73314701C8FA9792845C129351A87A945A03E6C895860E51D6FB8B7340A94D1A8A7B" + "FA85AC83B4B14E73AB86CB96C236C8BFB0978B61B2367A7FE4F7891070F56C78D5DD" + "F5576BFE5BE4F333A4E2664E79528B3294907AADD63F4F2E7AA8147B928D8CD69765" + "3DB98C4297CB678046ED55C0DBE60BF7142C594603E4D705DC3D17270F9F086EC561" + "2703D518D8D49FF0EBE6#)\n" +"))\n"; + + +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) +#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\ + exit(2);} while(0) + + +/* Helper for the start and stop timer. */ +#ifdef _WIN32 +struct { + FILETIME creation_time, exit_time, kernel_time, user_time; +} started_at, stopped_at; +#else +static clock_t started_at, stopped_at; +#endif + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + putchar ('\n'); + fputs ( PGM ": ", stderr); + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +static void +show_sexp (const char *prefix, gcry_sexp_t a) +{ + char *buf; + size_t size; + + fputs (prefix, stderr); + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = malloc (size); + if (!buf) + die ("out of core\n"); + + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + fprintf (stderr, "%.*s", (int)size, buf); +} + + +static void +start_timer (void) +{ +#ifdef _WIN32 + GetProcessTimes (GetCurrentProcess (), + &started_at.creation_time, &started_at.exit_time, + &started_at.kernel_time, &started_at.user_time); + stopped_at = started_at; +#else + struct tms tmp; + + times (&tmp); + started_at = stopped_at = tmp.tms_utime; +#endif +} + +static void +stop_timer (void) +{ +#ifdef _WIN32 + GetProcessTimes (GetCurrentProcess (), + &stopped_at.creation_time, &stopped_at.exit_time, + &stopped_at.kernel_time, &stopped_at.user_time); +#else + struct tms tmp; + + times (&tmp); + stopped_at = tmp.tms_utime; +#endif +} + +static const char * +elapsed_time (void) +{ + static char buf[50]; +#if _WIN32 + unsigned long long t1, t2, t; + + t1 = (((unsigned long long)started_at.kernel_time.dwHighDateTime << 32) + + started_at.kernel_time.dwLowDateTime); + t1 += (((unsigned long long)started_at.user_time.dwHighDateTime << 32) + + started_at.user_time.dwLowDateTime); + t2 = (((unsigned long long)stopped_at.kernel_time.dwHighDateTime << 32) + + stopped_at.kernel_time.dwLowDateTime); + t2 += (((unsigned long long)stopped_at.user_time.dwHighDateTime << 32) + + stopped_at.user_time.dwLowDateTime); + t = (t2 - t1)/10000; + snprintf (buf, sizeof buf, "%5.0fms", (double)t ); +#else + snprintf (buf, sizeof buf, "%5.0fms", + (((double) (stopped_at - started_at))/CLOCKS_PER_SEC)*10000000); +#endif + return buf; +} + + +static void +random_bench (int very_strong) +{ + char buf[128]; + int i; + + printf ("%-10s", "random"); + + if (!very_strong) + { + start_timer (); + for (i=0; i < 100; i++) + gcry_randomize (buf, sizeof buf, GCRY_STRONG_RANDOM); + stop_timer (); + printf (" %s", elapsed_time ()); + } + + start_timer (); + for (i=0; i < 100; i++) + gcry_randomize (buf, 8, + very_strong? GCRY_VERY_STRONG_RANDOM:GCRY_STRONG_RANDOM); + stop_timer (); + printf (" %s", elapsed_time ()); + + putchar ('\n'); + if (verbose) + gcry_control (GCRYCTL_DUMP_RANDOM_STATS); +} + + + +static void +md_bench ( const char *algoname ) +{ + int algo; + gcry_md_hd_t hd; + int i; + char buf[1000]; + gcry_error_t err = GPG_ERR_NO_ERROR; + + if (!algoname) + { + for (i=1; i < 400; i++) + if (in_fips_mode && i == GCRY_MD_MD5) + ; /* Don't use MD5 in fips mode. */ + else if ( !gcry_md_test_algo (i) ) + md_bench (gcry_md_algo_name (i)); + return; + } + + algo = gcry_md_map_name (algoname); + if (!algo) + { + fprintf (stderr, PGM ": invalid hash algorithm `%s'\n", algoname); + exit (1); + } + + err = gcry_md_open (&hd, algo, 0); + if (err) + { + fprintf (stderr, PGM ": error opening hash algorithm `%s'\n", algoname); + exit (1); + } + + for (i=0; i < sizeof buf; i++) + buf[i] = i; + + printf ("%-12s", gcry_md_algo_name (algo)); + + start_timer (); + for (i=0; i < 1000; i++) + gcry_md_write (hd, buf, sizeof buf); + gcry_md_final (hd); + stop_timer (); + printf (" %s", elapsed_time ()); + + gcry_md_reset (hd); + start_timer (); + for (i=0; i < 10000; i++) + gcry_md_write (hd, buf, sizeof buf/10); + gcry_md_final (hd); + stop_timer (); + printf (" %s", elapsed_time ()); + + gcry_md_reset (hd); + start_timer (); + for (i=0; i < 1000000; i++) + gcry_md_write (hd, "", 1); + gcry_md_final (hd); + stop_timer (); + printf (" %s", elapsed_time ()); + + gcry_md_close (hd); + putchar ('\n'); +} + +static void +cipher_bench ( const char *algoname ) +{ + static int header_printed; + int algo; + gcry_cipher_hd_t hd; + int i; + int keylen, blklen; + char key[128]; + char *outbuf, *buf; + size_t allocated_buflen, buflen; + int repetitions; + static struct { int mode; const char *name; int blocked; } modes[] = { + { GCRY_CIPHER_MODE_ECB, "ECB", 1 }, + { GCRY_CIPHER_MODE_CBC, "CBC", 1 }, + { GCRY_CIPHER_MODE_CFB, "CFB", 0 }, + { GCRY_CIPHER_MODE_OFB, "OFB", 0 }, + { GCRY_CIPHER_MODE_CTR, "CTR", 0 }, + { GCRY_CIPHER_MODE_STREAM, "STREAM", 0 }, + {0} + }; + int modeidx; + gcry_error_t err = GPG_ERR_NO_ERROR; + + + if (!algoname) + { + for (i=1; i < 400; i++) + if ( !gcry_cipher_test_algo (i) ) + cipher_bench (gcry_cipher_algo_name (i)); + return; + } + + if (large_buffers) + { + allocated_buflen = 1024 * 100; + repetitions = 10; + } + else + { + allocated_buflen = 1024; + repetitions = 1000; + } + repetitions *= cipher_repetitions; + + buf = gcry_xmalloc (allocated_buflen); + outbuf = gcry_xmalloc (allocated_buflen); + + if (!header_printed) + { + if (cipher_repetitions != 1) + printf ("Running each test %d times.\n", cipher_repetitions); + printf ("%-12s", ""); + for (modeidx=0; modes[modeidx].mode; modeidx++) + printf (" %-15s", modes[modeidx].name ); + putchar ('\n'); + printf ("%-12s", ""); + for (modeidx=0; modes[modeidx].mode; modeidx++) + printf (" ---------------" ); + putchar ('\n'); + header_printed = 1; + } + + algo = gcry_cipher_map_name (algoname); + if (!algo) + { + fprintf (stderr, PGM ": invalid cipher algorithm `%s'\n", algoname); + exit (1); + } + + keylen = gcry_cipher_get_algo_keylen (algo); + if (!keylen) + { + fprintf (stderr, PGM ": failed to get key length for algorithm `%s'\n", + algoname); + exit (1); + } + if ( keylen > sizeof key ) + { + fprintf (stderr, PGM ": algo %d, keylength problem (%d)\n", + algo, keylen ); + exit (1); + } + for (i=0; i < keylen; i++) + key[i] = i + (clock () & 0xff); + + blklen = gcry_cipher_get_algo_blklen (algo); + if (!blklen) + { + fprintf (stderr, PGM ": failed to get block length for algorithm `%s'\n", + algoname); + exit (1); + } + + printf ("%-12s", gcry_cipher_algo_name (algo)); + fflush (stdout); + + for (modeidx=0; modes[modeidx].mode; modeidx++) + { + if ((blklen > 1 && modes[modeidx].mode == GCRY_CIPHER_MODE_STREAM) + | (blklen == 1 && modes[modeidx].mode != GCRY_CIPHER_MODE_STREAM)) + { + printf (" " ); + continue; + } + + for (i=0; i < sizeof buf; i++) + buf[i] = i; + + err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); + if (err) + { + fprintf (stderr, PGM ": error opening cipher `%s'\n", algoname); + exit (1); + } + + err = gcry_cipher_setkey (hd, key, keylen); + if (err) + { + fprintf (stderr, "gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + exit (1); + } + + buflen = allocated_buflen; + if (modes[modeidx].blocked) + buflen = (buflen / blklen) * blklen; + + start_timer (); + for (i=err=0; !err && i < repetitions; i++) + err = gcry_cipher_encrypt ( hd, outbuf, buflen, buf, buflen); + stop_timer (); + + printf (" %s", elapsed_time ()); + fflush (stdout); + gcry_cipher_close (hd); + if (err) + { + fprintf (stderr, "gcry_cipher_encrypt failed: %s\n", + gpg_strerror (err) ); + exit (1); + } + + err = gcry_cipher_open (&hd, algo, modes[modeidx].mode, 0); + if (err) + { + fprintf (stderr, PGM ": error opening cipher `%s'/n", algoname); + exit (1); + } + + err = gcry_cipher_setkey (hd, key, keylen); + if (err) + { + fprintf (stderr, "gcry_cipher_setkey failed: %s\n", + gpg_strerror (err)); + gcry_cipher_close (hd); + exit (1); + } + + start_timer (); + for (i=err=0; !err && i < repetitions; i++) + err = gcry_cipher_decrypt ( hd, outbuf, buflen, buf, buflen); + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + gcry_cipher_close (hd); + if (err) + { + fprintf (stderr, "gcry_cipher_decrypt failed: %s\n", + gpg_strerror (err) ); + exit (1); + } + } + + putchar ('\n'); + gcry_free (buf); + gcry_free (outbuf); +} + + + +static void +rsa_bench (int iterations, int print_header, int no_blinding) +{ + gpg_error_t err; + int p_sizes[] = { 1024, 2048, 3072, 4096 }; + int testno; + + if (print_header) + printf ("Algorithm generate %4d*sign %4d*verify\n" + "------------------------------------------------\n", + iterations, iterations ); + for (testno=0; testno < DIM (p_sizes); testno++) + { + gcry_sexp_t key_spec, key_pair, pub_key, sec_key; + gcry_mpi_t x; + gcry_sexp_t data; + gcry_sexp_t sig = NULL; + int count; + + printf ("RSA %3d bit ", p_sizes[testno]); + fflush (stdout); + + err = gcry_sexp_build (&key_spec, NULL, + gcry_fips_mode_active () + ? "(genkey (RSA (nbits %d)))" + : "(genkey (RSA (nbits %d)(transient-key)))", + p_sizes[testno]); + if (err) + die ("creating S-expression failed: %s\n", gcry_strerror (err)); + + start_timer (); + err = gcry_pk_genkey (&key_pair, key_spec); + if (err) + die ("creating %d bit RSA key failed: %s\n", + p_sizes[testno], gcry_strerror (err)); + + pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); + if (! pub_key) + die ("public part missing in key\n"); + sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); + if (! sec_key) + die ("private part missing in key\n"); + gcry_sexp_release (key_pair); + gcry_sexp_release (key_spec); + + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + x = gcry_mpi_new (p_sizes[testno]); + gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, + "(data (flags raw) (value %m))", x); + gcry_mpi_release (x); + if (err) + die ("converting data failed: %s\n", gcry_strerror (err)); + + start_timer (); + for (count=0; count < iterations; count++) + { + gcry_sexp_release (sig); + err = gcry_pk_sign (&sig, data, sec_key); + if (err) + die ("signing failed (%d): %s\n", count, gpg_strerror (err)); + } + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + start_timer (); + for (count=0; count < iterations; count++) + { + err = gcry_pk_verify (sig, data, pub_key); + if (err) + { + putchar ('\n'); + show_sexp ("seckey:\n", sec_key); + show_sexp ("data:\n", data); + show_sexp ("sig:\n", sig); + die ("verify failed (%d): %s\n", count, gpg_strerror (err)); + } + } + stop_timer (); + printf (" %s", elapsed_time ()); + + if (no_blinding) + { + fflush (stdout); + x = gcry_mpi_new (p_sizes[testno]); + gcry_mpi_randomize (x, p_sizes[testno]-8, GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, + "(data (flags no-blinding) (value %m))", x); + gcry_mpi_release (x); + if (err) + die ("converting data failed: %s\n", gcry_strerror (err)); + + start_timer (); + for (count=0; count < iterations; count++) + { + gcry_sexp_release (sig); + err = gcry_pk_sign (&sig, data, sec_key); + if (err) + die ("signing failed (%d): %s\n", count, gpg_strerror (err)); + } + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + } + + putchar ('\n'); + fflush (stdout); + + gcry_sexp_release (sig); + gcry_sexp_release (data); + gcry_sexp_release (sec_key); + gcry_sexp_release (pub_key); + } +} + + + +static void +dsa_bench (int iterations, int print_header) +{ + gpg_error_t err; + gcry_sexp_t pub_key[3], sec_key[3]; + int p_sizes[3] = { 1024, 2048, 3072 }; + int q_sizes[3] = { 160, 224, 256 }; + gcry_sexp_t data; + gcry_sexp_t sig; + int i, j; + + err = gcry_sexp_sscan (pub_key+0, NULL, sample_public_dsa_key_1024, + strlen (sample_public_dsa_key_1024)); + if (!err) + err = gcry_sexp_sscan (sec_key+0, NULL, sample_private_dsa_key_1024, + strlen (sample_private_dsa_key_1024)); + if (!err) + err = gcry_sexp_sscan (pub_key+1, NULL, sample_public_dsa_key_2048, + strlen (sample_public_dsa_key_2048)); + if (!err) + err = gcry_sexp_sscan (sec_key+1, NULL, sample_private_dsa_key_2048, + strlen (sample_private_dsa_key_2048)); + if (!err) + err = gcry_sexp_sscan (pub_key+2, NULL, sample_public_dsa_key_3072, + strlen (sample_public_dsa_key_3072)); + if (!err) + err = gcry_sexp_sscan (sec_key+2, NULL, sample_private_dsa_key_3072, + strlen (sample_private_dsa_key_3072)); + if (err) + { + fprintf (stderr, PGM ": converting sample keys failed: %s\n", + gcry_strerror (err)); + exit (1); + } + + if (print_header) + printf ("Algorithm generate %4d*sign %4d*verify\n" + "------------------------------------------------\n", + iterations, iterations ); + for (i=0; i < DIM (q_sizes); i++) + { + gcry_mpi_t x; + + x = gcry_mpi_new (q_sizes[i]); + gcry_mpi_randomize (x, q_sizes[i], GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); + gcry_mpi_release (x); + if (err) + { + fprintf (stderr, PGM ": converting data failed: %s\n", + gcry_strerror (err)); + exit (1); + } + + printf ("DSA %d/%d -", p_sizes[i], q_sizes[i]); + fflush (stdout); + + start_timer (); + for (j=0; j < iterations; j++) + { + err = gcry_pk_sign (&sig, data, sec_key[i]); + if (err) + { + putchar ('\n'); + fprintf (stderr, PGM ": signing failed: %s\n", + gpg_strerror (err)); + exit (1); + } + } + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + start_timer (); + for (j=0; j < iterations; j++) + { + err = gcry_pk_verify (sig, data, pub_key[i]); + if (err) + { + putchar ('\n'); + fprintf (stderr, PGM ": verify failed: %s\n", + gpg_strerror (err)); + exit (1); + } + } + stop_timer (); + printf (" %s\n", elapsed_time ()); + fflush (stdout); + + gcry_sexp_release (sig); + gcry_sexp_release (data); + } + + + for (i=0; i < DIM (q_sizes); i++) + { + gcry_sexp_release (sec_key[i]); + gcry_sexp_release (pub_key[i]); + } +} + + +static void +ecc_bench (int iterations, int print_header) +{ +#if USE_ECC + gpg_error_t err; + int p_sizes[] = { 192, 224, 256, 384, 521 }; + int testno; + + if (print_header) + printf ("Algorithm generate %4d*sign %4d*verify\n" + "------------------------------------------------\n", + iterations, iterations ); + for (testno=0; testno < DIM (p_sizes); testno++) + { + gcry_sexp_t key_spec, key_pair, pub_key, sec_key; + gcry_mpi_t x; + gcry_sexp_t data; + gcry_sexp_t sig = NULL; + int count; + + printf ("ECDSA %3d bit ", p_sizes[testno]); + fflush (stdout); + + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (ECDSA (nbits %d)))", p_sizes[testno]); + if (err) + die ("creating S-expression failed: %s\n", gcry_strerror (err)); + + start_timer (); + err = gcry_pk_genkey (&key_pair, key_spec); + if (err) + die ("creating %d bit ECC key failed: %s\n", + p_sizes[testno], gcry_strerror (err)); + + pub_key = gcry_sexp_find_token (key_pair, "public-key", 0); + if (! pub_key) + die ("public part missing in key\n"); + sec_key = gcry_sexp_find_token (key_pair, "private-key", 0); + if (! sec_key) + die ("private part missing in key\n"); + gcry_sexp_release (key_pair); + gcry_sexp_release (key_spec); + + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + x = gcry_mpi_new (p_sizes[testno]); + gcry_mpi_randomize (x, p_sizes[testno], GCRY_WEAK_RANDOM); + err = gcry_sexp_build (&data, NULL, "(data (flags raw) (value %m))", x); + gcry_mpi_release (x); + if (err) + die ("converting data failed: %s\n", gcry_strerror (err)); + + start_timer (); + for (count=0; count < iterations; count++) + { + gcry_sexp_release (sig); + err = gcry_pk_sign (&sig, data, sec_key); + if (err) + die ("signing failed: %s\n", gpg_strerror (err)); + } + stop_timer (); + printf (" %s", elapsed_time ()); + fflush (stdout); + + start_timer (); + for (count=0; count < iterations; count++) + { + err = gcry_pk_verify (sig, data, pub_key); + if (err) + { + putchar ('\n'); + show_sexp ("seckey:\n", sec_key); + show_sexp ("data:\n", data); + show_sexp ("sig:\n", sig); + die ("verify failed: %s\n", gpg_strerror (err)); + } + } + stop_timer (); + printf (" %s\n", elapsed_time ()); + fflush (stdout); + + gcry_sexp_release (sig); + gcry_sexp_release (data); + gcry_sexp_release (sec_key); + gcry_sexp_release (pub_key); + } +#endif /*USE_ECC*/ +} + + + +static void +do_powm ( const char *n_str, const char *e_str, const char *m_str) +{ + gcry_mpi_t e, n, msg, cip; + gcry_error_t err; + int i; + + err = gcry_mpi_scan (&n, GCRYMPI_FMT_HEX, n_str, 0, 0); + if (err) BUG (); + err = gcry_mpi_scan (&e, GCRYMPI_FMT_HEX, e_str, 0, 0); + if (err) BUG (); + err = gcry_mpi_scan (&msg, GCRYMPI_FMT_HEX, m_str, 0, 0); + if (err) BUG (); + + cip = gcry_mpi_new (0); + + start_timer (); + for (i=0; i < 1000; i++) + gcry_mpi_powm (cip, msg, e, n); + stop_timer (); + printf (" %s", elapsed_time ()); fflush (stdout); +/* { */ +/* char *buf; */ + +/* if (gcry_mpi_aprint (GCRYMPI_FMT_HEX, (void**)&buf, NULL, cip)) */ +/* BUG (); */ +/* printf ("result: %s\n", buf); */ +/* gcry_free (buf); */ +/* } */ + gcry_mpi_release (cip); + gcry_mpi_release (msg); + gcry_mpi_release (n); + gcry_mpi_release (e); +} + + +static void +mpi_bench (void) +{ + printf ("%-10s", "powm"); fflush (stdout); + + do_powm ( +"20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E4", + "29", +"B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8" + ); + do_powm ( + "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716", + "29", + "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847" + ); + do_powm ( + "20A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA4071620A94417D4D5EF2B2DA99165C7DC87DADB3979B72961AF90D09D59BA24CB9A10166FDCCC9C659F2B9626EC23F3FA425F564A072BA941B03FA81767CC289E41071F0246879A442658FBD18C1771571E7073EEEB2160BA0CBFB3404D627069A6CFBD53867AD2D9D40231648000787B5C84176B4336144644AE71A403CA40716", + "29", + "B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847B870187A323F1ECD5B8A0B4249507335A1C4CE8394F38FD76B08C78A42C58F6EA136ACF90DFE8603697B1694A3D81114D6117AC1811979C51C4DD013D52F8FC4EE4BB446B83E48ABED7DB81CBF5E81DE4759E8D68AC985846D999F96B0D8A80E5C69D272C766AB8A23B40D50A4FA889FBC2BD2624222D8EB297F4BAEF8593847" + ); + + putchar ('\n'); + + +} + + +int +main( int argc, char **argv ) +{ + int last_argc = -1; + int no_blinding = 0; + int use_random_daemon = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + fputs ("usage: benchmark " + "[md|cipher|random|mpi|rsa|dsa|ecc [algonames]]\n", + stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--use-random-daemon")) + { + use_random_daemon = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--no-blinding")) + { + no_blinding = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--large-buffers")) + { + large_buffers = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--cipher-repetition")) + { + argc--; argv++; + if (argc) + { + cipher_repetitions = atoi(*argv); + argc--; argv++; + } + } + else if (!strcmp (*argv, "--fips")) + { + argc--; argv++; + /* This command needs to be called before gcry_check_version. */ + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + } + } + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); + + if (!gcry_check_version (GCRYPT_VERSION)) + { + fprintf (stderr, PGM ": version mismatch\n"); + exit (1); + } + + if (gcry_fips_mode_active ()) + in_fips_mode = 1; + else + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + + if (use_random_daemon) + gcry_control (GCRYCTL_USE_RANDOM_DAEMON, 1); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + + if (cipher_repetitions < 1) + cipher_repetitions = 1; + + if ( !argc ) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + md_bench (NULL); + putchar ('\n'); + cipher_bench (NULL); + putchar ('\n'); + rsa_bench (100, 1, no_blinding); + dsa_bench (100, 0); + ecc_bench (100, 0); + putchar ('\n'); + mpi_bench (); + putchar ('\n'); + random_bench (0); + } + else if ( !strcmp (*argv, "random") || !strcmp (*argv, "strongrandom")) + { + if (argc == 1) + random_bench ((**argv == 's')); + else if (argc == 2) + { + gcry_control (GCRYCTL_SET_RANDOM_SEED_FILE, argv[1]); + random_bench ((**argv == 's')); + gcry_control (GCRYCTL_UPDATE_RANDOM_SEED_FILE); + } + else + fputs ("usage: benchmark [strong]random [seedfile]\n", stdout); + } + else if ( !strcmp (*argv, "md")) + { + if (argc == 1) + md_bench (NULL); + else + for (argc--, argv++; argc; argc--, argv++) + md_bench ( *argv ); + } + else if ( !strcmp (*argv, "cipher")) + { + if (argc == 1) + cipher_bench (NULL); + else + for (argc--, argv++; argc; argc--, argv++) + cipher_bench ( *argv ); + } + else if ( !strcmp (*argv, "mpi")) + { + mpi_bench (); + } + else if ( !strcmp (*argv, "rsa")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + rsa_bench (100, 1, no_blinding); + } + else if ( !strcmp (*argv, "dsa")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + dsa_bench (100, 1); + } + else if ( !strcmp (*argv, "ecc")) + { + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + ecc_bench (100, 1); + } + else + { + fprintf (stderr, PGM ": bad arguments\n"); + return 1; + } + + + if (in_fips_mode && !gcry_fips_mode_active ()) + fprintf (stderr, PGM ": FIPS mode is not anymore active\n"); + + return 0; +} + diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl b/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl new file mode 100644 index 0000000000..7111f0f47c --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_driver.pl @@ -0,0 +1,2243 @@ +#!/usr/bin/env perl +# +# $Id: cavs_driver.pl 1497 2009-01-22 14:01:29Z smueller $ +# +# CAVS test driver (based on the OpenSSL driver) +# Written by: Stephan Müller <sm@atsec.com> +# Copyright (c) atsec information security corporation +# +# Permission is hereby granted, free of charge, to any person obtaining a copy +# of this software and associated documentation files (the "Software"), to deal +# in the Software without restriction, including without limitation the rights +# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +# copies of the Software, and to permit persons to whom the Software is +# furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# NO WARRANTY +# +# BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +# FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +# OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +# PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +# OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +# TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +# PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +# REPAIR OR CORRECTION. +# +# IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +# WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +# REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +# INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +# OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +# TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +# YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +# PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGES. +# +# +# test execution instruction: +# 1. get the request files from the lab +# 2. call each request file from 1. with this program: +# $0 <FILE>.rep +# 3. send the resulting file <FILE>.rsp to the lab +# +# +# Test should be easily adoptable to other implementations +# See the first functions for this task +# +# Following tests are covered (others may also be covered +# but have not been tested) +# +# AES +# [CBC|CFB128|ECB|OFB]GFSbox[128|192|256] +# [CBC|CFB128|ECB|OFB]MCT[128|192|256] +# [CBC|CFB128|ECB|OFB]VarKey[128|192|256] +# [CBC|CFB128|ECB|OFB]KeySbox[128|192|256] +# [CBC|CFB128|ECB|OFB]MMT[128|192|256] +# [CBC|CFB128|ECB|OFB]VarTxt[128|192|256] +# +# RSA +# SigGen[15|RSA] +# SigVer15 +# (SigVerRSA is not applicable for OpenSSL as X9.31 padding +# is not done through openssl dgst) +# KeyGen RSA X9.31 +# +# SHA +# SHA[1|224|256|384|512]ShortMsg +# SHA[1|224|256|384|512]LongMsg +# SHA[1|224|256|384|512]Monte +# +# HMAC (SHA - caveat: we only support hash output equal to the block size of +# of the hash - we do not support truncation of the hash; to support +# that, we first need to decipher the HMAC.req file - see hmac_kat() ) +# HMAC +# +# TDES +# T[CBC|CFB??|ECB|OFB]Monte[1|2|3] +# T[CBC|CFB??|ECB|OFB]permop +# T[CBC|CFB??|ECB|OFB]MMT[1|2|3] +# T[CBC|CFB??|ECB|OFB]subtab +# T[CBC|CFB??|ECB|OFB]varkey +# T[CBC|CFB??|ECB|OFB]invperm +# T[CBC|CFB??|ECB|OFB]vartext +# +# ANSI X9.31 RNG +# ANSI931_AES128MCT +# ANSI931_AES128VST +# +# DSA +# PQGGen +# SigGen +# SigVer +# +# RC4 (atsec developed tests) +# RC4KeyBD +# RC4MCT +# RC4PltBD +# RC4REGT +# + +use strict; +use warnings; +use IPC::Open2; +use Getopt::Std; +use MIME::Base64; + +# Contains the command line options +my %opt; + +################################################################# +##### Central interface functions to the external ciphers ####### +################################################################# +# Only these interface routines should be changed in case of +# porting to a new cipher library +# +# For porting to a new library, create implementation of these functions +# and then add pointers to the respective implementation of each +# function to the given variables. + +# common encryption/decryption routine +# $1 key in hex form (please note for 3DES: even when ede3 for three +# independent ciphers is given with the cipher specification, we hand in +# either one key for k1 = k2 = k3, two keys which are concatinated for +# k1 = k3, k2 independent, or three keys which are concatinated for +# k1, k2, k3 independent) +# $2 iv in hex form +# $3 cipher - the cipher string is defined as specified in the openssl +# enc(1ssl) specification for the option "-ciphername" +# (e.g. aes-128-cbc or des-ede3-cbc) +# $4 encrypt=1/decrypt=0 +# $5 de/encrypted data in hex form +# return en/decrypted data in hex form +my $encdec; + +# +# Derive an RSA key from the given X9.31 parameters. +# $1: modulus size +# $2: E in hex form +# $3: Xp1 in hex form +# $4: Xp2 in hex form +# $5: Xp in hex form +# $6: Xq1 in hex form +# $7: Xq2 in hex form +# $8: Xq in hex form +# return: string with the calculated values in hex format, where each value +# is separated from the previous with a \n in the following order: +# P\n +# Q\n +# N\n +# D\n +my $rsa_derive; + +# Sign a message with RSA +# $1: data to be signed in hex form +# $2: Hash algo +# $3: Key file in PEM format with the private key +# return: digest in hex format +my $rsa_sign; + +# Verify a message with RSA +# $1: data to be verified in hex form +# $2: hash algo +# $3: file holding the public RSA key in PEM format +# $4: file holding the signature in binary form +# return: 1 == verified / 0 == not verified +my $rsa_verify; + +# generate a new private RSA key with the following properties: +# exponent is 65537 +# PEM format +# $1 key size in bit +# $2 keyfile name +# return: nothing, but file created +my $gen_rsakey; + +# Creating a hash +# $1: Plaintext in hex form +# $2: hash type in the form documented in openssl's dgst(1ssl) - e.g. +# sha1, sha224, sha256, sha384, sha512 +# return: hash in hex form +my $hash; + +# supplying the call to the external cipher implementation +# that is being used to keep STDIN and STDOUT open +# to maintain the state of the block chaining +# $1: cipher +# $2: 1=encryption, 0=decryption +# $3: buffersize needed for openssl +# $4: encryption key in binary form +# $5: IV in binary form +# return: command line to execute the application +my $state_cipher; +# the only difference of the DES version is that it implements the inner loop +# of the TDES tests +my $state_cipher_des; + +# supplying the call to the external cipher implementation +# that is being used to keep STDIN and STDOUT open +# to maintain the state of the RNG with its seed +# +# input holds seed values +# $1: cipher key in hex format +# $2: DT value in hex format +# $3: V value in hex format +# +# return: command line to execute the application +# +# the application is expected to deliver random values on STDOUT - the script +# reads 128 bits repeatedly where the state of the RNG must be retained +# between the reads. The output of the RNG on STDOUT is assumed to be binary. +my $state_rng; + +# Generate an HMAC based on SHAx +# $1: Key to be used for the HMAC in hex format +# $2: length of the hash to be calculated in bits +# $3: Message for which the HMAC shall be calculated in hex format +# $4: hash type (1 - SHA1, 224 - SHA224, and so on) +# return: calculated HMAC in hex format +my $hmac; + +# +# Generate the P, Q, G, Seed, counter, h (value used to generate g) values +# for DSA +# $1: modulus size +# return: string with the calculated values in hex format, where each value +# is separated from the previous with a \n in the following order: +# P\n +# Q\n +# G\n +# Seed\n +# counter\n +# h +my $dsa_pqggen; + +# +# Generate an DSA public key from the provided parameters: +# $1: Name of file to create +# $2: P in hex form +# $3: Q in hex form +# $4: G in hex form +# $5: Y in hex form +my $dsa_genpubkey; + +# Verify a message with DSA +# $1: data to be verified in hex form +# $2: file holding the public DSA key in PEM format +# $3: R value of the signature +# $4: S value of the signature +# return: 1 == verified / 0 == not verified +my $dsa_verify; + +# generate a new DSA key with the following properties: +# PEM format +# $1 keyfile name +# return: file created, hash with keys of P, Q, G in hex format +my $gen_dsakey; + +# Sign a message with DSA +# $1: data to be signed in hex form +# $2: Key file in PEM format with the private key +# return: hash of digest information in hex format with Y, R, S as keys +my $dsa_sign; + +################################################################ +##### OpenSSL interface functions +################################################################ +sub openssl_encdec($$$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $enc = (shift) ? "-e" : "-d"; + my $data=shift; + + # We only invoke the driver with the IV parameter, if we have + # an IV, otherwise, we skip it + $iv = "-iv $iv" if ($iv); + + $data=hex2bin($data); + my $program="openssl enc -$cipher -nopad -nosalt -K $key $enc $iv"; + $program = "rc4 -k $key" if $opt{'R'}; #for ARCFOUR, no IV must be given + $data=pipe_through_program($data,$program); + return bin2hex($data); +} + +sub openssl_rsa_sign($$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + + $data=hex2bin($data); + die "ARCFOUR not available for RSA" if $opt{'R'}; + $data=pipe_through_program($data, + "openssl dgst -$cipher -binary -sign $keyfile"); + return bin2hex($data); +} + +sub openssl_rsa_verify($$$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + my $sigfile = shift; + + $data = hex2bin($data); + die "ARCFOUR not available for RSA" if $opt{'R'}; + $data = pipe_through_program($data, + "openssl dgst -$cipher -binary -verify $keyfile -signature $sigfile"); + + # Parse through the OpenSSL output information + return ($data =~ /OK/); +} + +sub openssl_gen_rsakey($$) { + my $keylen = shift; + my $file = shift; + + die "ARCFOUR not available for RSA" if $opt{'R'}; + # generating of a key with exponent 0x10001 + my @args = ("openssl", "genrsa", "-F4", "-out", "$file", "$keylen"); + system(@args) == 0 + or die "system @args failed: $?"; + die "system @args failed: file $file not created" if (! -f $file); +} + +sub openssl_hash($$) { + my $pt = shift; + my $cipher = shift; + + die "ARCFOUR not available for hashes" if $opt{'R'}; + my $hash = hex2bin($pt); + #bin2hex not needed as the '-hex' already converts it + return pipe_through_program($hash, "openssl dgst -$cipher -hex"); +} + +sub openssl_state_cipher($$$$$) { + my $cipher = shift; + my $encdec = shift; + my $bufsize = shift; + my $key = shift; + my $iv = shift; + + my $enc = $encdec ? "-e": "-d"; + + # We only invoke the driver with the IV parameter, if we have + # an IV, otherwise, we skip it + $iv = "-iv ".bin2hex($iv) if ($iv); + + my $out = "openssl enc -'$cipher' $enc -nopad -nosalt -bufsize $bufsize -K ".bin2hex($key)." $iv"; + #for ARCFOUR, no IV must be given + $out = "rc4 -k " . bin2hex($key) if $opt{'R'}; + return $out; +} + +###### End of OpenSSL interface implementation ############ + +########################################################### +###### libgcrypt implementation +########################################################### +sub libgcrypt_encdec($$$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $enc = (shift) ? "encrypt" : "decrypt"; + my $data=shift; + + # We only invoke the driver with the IV parameter, if we have + # an IV, otherwise, we skip it + $iv = "--iv $iv" if ($iv); + + my $program="fipsdrv --key $key $iv --algo $cipher $enc"; + + return pipe_through_program($data,$program); + +} + +sub libgcrypt_rsa_derive($$$$$$$$) { + my $n = shift; + my $e = shift; + my $xp1 = shift; + my $xp2 = shift; + my $xp = shift; + my $xq1 = shift; + my $xq2 = shift; + my $xq = shift; + my $sexp; + my @tmp; + + $n = sprintf ("%u", $n); + $e = sprintf ("%u", hex($e)); + $sexp = "(genkey(rsa(nbits " . sprintf ("%u:%s", length($n), $n) . ")" + . "(rsa-use-e " . sprintf ("%u:%s", length($e), $e) . ")" + . "(derive-parms" + . "(Xp1 #$xp1#)" + . "(Xp2 #$xp2#)" + . "(Xp #$xp#)" + . "(Xq1 #$xq1#)" + . "(Xq2 #$xq2#)" + . "(Xq #$xq#))))\n"; + + return pipe_through_program($sexp, "fipsdrv rsa-derive"); +} + + +sub libgcrypt_rsa_sign($$$) { + my $data = shift; + my $hashalgo = shift; + my $keyfile = shift; + + die "ARCFOUR not available for RSA" if $opt{'R'}; + + return pipe_through_program($data, + "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile rsa-sign"); +} + +sub libgcrypt_rsa_verify($$$$) { + my $data = shift; + my $hashalgo = shift; + my $keyfile = shift; + my $sigfile = shift; + + die "ARCFOUR not available for RSA" if $opt{'R'}; + $data = pipe_through_program($data, + "fipsdrv --pkcs1 --algo $hashalgo --key $keyfile --signature $sigfile rsa-verify"); + + # Parse through the output information + return ($data =~ /GOOD signature/); +} + +sub libgcrypt_gen_rsakey($$) { + my $keylen = shift; + my $file = shift; + + die "ARCFOUR not available for RSA" if $opt{'R'}; + my @args = ("fipsdrv --keysize $keylen rsa-gen > $file"); + system(@args) == 0 + or die "system @args failed: $?"; + die "system @args failed: file $file not created" if (! -f $file); +} + +sub libgcrypt_hash($$) { + my $pt = shift; + my $hashalgo = shift; + + my $program = "fipsdrv --algo $hashalgo digest"; + die "ARCFOUR not available for hashes" if $opt{'R'}; + + return pipe_through_program($pt, $program); +} + +sub libgcrypt_state_cipher($$$$$) { + my $cipher = shift; + my $enc = (shift) ? "encrypt": "decrypt"; + my $bufsize = shift; + my $key = shift; + my $iv = shift; + + # We only invoke the driver with the IV parameter, if we have + # an IV, otherwise, we skip it + $iv = "--iv ".bin2hex($iv) if ($iv); + + my $program="fipsdrv --binary --key ".bin2hex($key)." $iv --algo '$cipher' --chunk '$bufsize' $enc"; + + return $program; +} + +sub libgcrypt_state_cipher_des($$$$$) { + my $cipher = shift; + my $enc = (shift) ? "encrypt": "decrypt"; + my $bufsize = shift; + my $key = shift; + my $iv = shift; + + # We only invoke the driver with the IV parameter, if we have + # an IV, otherwise, we skip it + $iv = "--iv ".bin2hex($iv) if ($iv); + + my $program="fipsdrv --algo '$cipher' --mct-server $enc"; + + return $program; +} + +sub libgcrypt_state_rng($$$) { + my $key = shift; + my $dt = shift; + my $v = shift; + + return "fipsdrv --binary --loop --key $key --iv $v --dt $dt random"; +} + +sub libgcrypt_hmac($$$$) { + my $key = shift; + my $maclen = shift; + my $msg = shift; + my $hashtype = shift; + + my $program = "fipsdrv --key $key --algo $hashtype hmac-sha"; + return pipe_through_program($msg, $program); +} + +sub libgcrypt_dsa_pqggen($) { + my $mod = shift; + + my $program = "fipsdrv --keysize $mod dsa-pqg-gen"; + return pipe_through_program("", $program); +} + +sub libgcrypt_gen_dsakey($) { + my $file = shift; + + my $program = "fipsdrv --keysize 1024 --key $file dsa-gen"; + my $tmp; + my %ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + $tmp = pipe_through_program("", $program); + die "dsa key gen failed: file $file not created" if (! -f $file); + + @ret{'P', 'Q', 'G', 'Seed', 'c', 'H'} = split(/\n/, $tmp); + return %ret; +} + +sub libgcrypt_dsa_genpubkey($$$$$) { + my $filename = shift; + my $p = shift; + my $q = shift; + my $g = shift; + my $y = shift; + + my $sexp; + + $sexp = "(public-key(dsa(p #$p#)(q #$q#)(g #$g#)(y #$y#)))"; + + open(FH, ">", $filename) or die; + print FH $sexp; + close FH; +} + +sub libgcrypt_dsa_sign($$) { + my $data = shift; + my $keyfile = shift; + my $tmp; + my %ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + $tmp = pipe_through_program($data, "fipsdrv --key $keyfile dsa-sign"); + @ret{'Y', 'R', 'S'} = split(/\n/, $tmp); + return %ret; +} + +sub libgcrypt_dsa_verify($$$$) { + my $data = shift; + my $keyfile = shift; + my $r = shift; + my $s = shift; + + my $ret; + + die "ARCFOUR not available for DSA" if $opt{'R'}; + + my $sigfile = "$keyfile.sig"; + open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; + print FH "(sig-val(dsa(r #$r#)(s #$s#)))"; + close FH; + + $ret = pipe_through_program($data, + "fipsdrv --key $keyfile --signature $sigfile dsa-verify"); + unlink ($sigfile); + # Parse through the output information + return ($ret =~ /GOOD signature/); +} + +######### End of libgcrypt implementation ################ + +################################################################ +###### Vendor1 interface functions +################################################################ + +sub vendor1_encdec($$$$$) { + my $key=shift; + my $iv=shift; + my $cipher=shift; + my $enc = (shift) ? "encrypt" : "decrypt"; + my $data=shift; + + $data=hex2bin($data); + my $program = "./aes $enc $key"; + $data=pipe_through_program($data,$program); + return bin2hex($data); +} + +sub vendor1_state_cipher($$$$$) { + my $cipher = shift; + my $encdec = shift; + my $bufsize = shift; + my $key = shift; + my $iv = shift; + + $key = bin2hex($key); + my $enc = $encdec ? "encrypt": "decrypt"; + my $out = "./aes $enc $key $bufsize"; + return $out; +} + +##### No other interface functions below this point ###### +########################################################## + +########################################################## +# General helper routines + +# Executing a program by feeding STDIN and retrieving +# STDOUT +# $1: data string to be piped to the app on STDIN +# rest: program and args +# returns: STDOUT of program as string +sub pipe_through_program($@) { + my $in = shift; + my @args = @_; + + my ($CO, $CI); + my $pid = open2($CO, $CI, @args); + + my $out = ""; + my $len = length($in); + my $first = 1; + while (1) { + my $rin = ""; + my $win = ""; + # Output of prog is FD that we read + vec($rin,fileno($CO),1) = 1; + # Input of prog is FD that we write + # check for $first is needed because we can have NULL input + # that is to be written to the app + if ( $len > 0 || $first) { + (vec($win,fileno($CI),1) = 1); + $first=0; + } + # Let us wait for 100ms + my $nfound = select(my $rout=$rin, my $wout=$win, undef, 0.1); + if ( $wout ) { + my $written = syswrite($CI, $in, $len); + die "broken pipe" if !defined $written; + $len -= $written; + substr($in, 0, $written) = ""; + if ($len <= 0) { + close $CI or die "broken pipe: $!"; + } + } + if ( $rout ) { + my $tmp_out = ""; + my $bytes_read = sysread($CO, $tmp_out, 4096); + $out .= $tmp_out; + last if ($bytes_read == 0); + } + } + close $CO or die "broken pipe: $!"; + waitpid $pid, 0; + + return $out; +} + +# +# convert ASCII hex to binary input +# $1 ASCII hex +# return binary representation +sub hex2bin($) { + my $in = shift; + my $len = length($in); + $len = 0 if ($in eq "00"); + return pack("H$len", "$in"); +} + +# +# convert binary input to ASCII hex +# $1 binary value +# return ASCII hex representation +sub bin2hex($) { + my $in = shift; + my $len = length($in)*2; + return unpack("H$len", "$in"); +} + +# $1: binary byte (character) +# returns: binary byte with odd parity using low bit as parity bit +sub odd_par($) { + my $in = ord(shift); + my $odd_count=0; + for(my $i=1; $i<8; $i++) { + $odd_count++ if ($in & (1<<$i)); + } + + my $out = $in; + if ($odd_count & 1) { # check if parity is already odd + $out &= ~1; # clear the low bit + } else { + $out |= 1; # set the low bit + } + + return chr($out); +} + +# DES keys uses only the 7 high bits of a byte, the 8th low bit +# is the parity bit +# as the new key is calculated from oldkey XOR cipher in the MCT test, +# the parity is not really checked and needs to be set to match +# expectation (OpenSSL does not really care, but the FIPS +# test result is expected that the key has the appropriate parity) +# $1: arbitrary binary string +# returns: string with odd parity set in low bit of each byte +sub fix_key_parity($) { + my $in = shift; + my $out = ""; + for (my $i = 0; $i < length($in); $i++) { + $out .= odd_par(substr($in, $i, 1)); + } + + return $out; +} + +#################################################### +# DER/PEM utility functions +# Cf. http://www.columbia.edu/~ariel/ssleay/layman.html + +# Convert unsigned integer to base256 bigint bytes +# $1 integer +# returns base256 octet string +sub int_base256_unsigned($) { + my $n = shift; + + my $out = chr($n & 255); + while ($n>>=8) { + $out = chr($n & 255) . $out; + } + + return $out; +} + +# Convert signed integer to base256 bigint bytes +# $1 integer +# returns base256 octet string +sub int_base256_signed($) { + my $n = shift; + my $negative = ($n < 0); + + if ($negative) { + $n = -$n-1; + } + + my $out = int_base256_unsigned($n); + + if (ord(substr($out, 0, 1)) & 128) { + # it's supposed to be positive but has sign bit set, + # add a leading zero + $out = chr(0) . $out; + } + + if ($negative) { + my $neg = chr(255) x length($out); + $out ^= $neg; + } + + return $out; +} + +# Length header for specified DER object length +# $1 length as integer +# return octet encoding for length +sub der_len($) { + my $len = shift; + + if ($len <= 127) { + return chr($len); + } else { + my $blen = int_base256_unsigned($len); + + return chr(128 | length($blen)) . $blen; + } +} + +# Prepend length header to object +# $1 object as octet sequence +# return length header for object followed by object as octets +sub der_len_obj($) { + my $x = shift; + + return der_len(length($x)) . $x; +} + +# DER sequence +# $* objects +# returns DER sequence consisting of the objects passed as arguments +sub der_seq { + my $seq = join("", @_); + return chr(0x30) . der_len_obj($seq); +} + +# DER bitstring +# $1 input octets (must be full octets, fractional octets not supported) +# returns input encapsulated as bitstring +sub der_bitstring($) { + my $x = shift; + + $x = chr(0) . $x; + + return chr(0x03) . der_len_obj($x); +} + +# base-128-encoded integer, used for object numbers. +# $1 integer +# returns octet sequence +sub der_base128($) { + my $n = shift; + + my $out = chr($n & 127); + + while ($n>>=7) { + $out = chr(128 | ($n & 127)) . $out; + } + + return $out; +} + +# Generating the PEM certificate string +# (base-64-encoded DER string) +# $1 DER string +# returns octet sequence +sub pem_cert($) { + my $n = shift; + + my $out = "-----BEGIN PUBLIC KEY-----\n"; + $out .= encode_base64($n); + $out .= "-----END PUBLIC KEY-----\n"; + + return $out; +} + +# DER object identifier +# $* sequence of id numbers +# returns octets +sub der_objectid { + my $v1 = shift; + my $v2 = shift; + + my $out = chr(40*$v1 + $v2) . join("", map { der_base128($_) } @_); + + return chr(0x06) . der_len_obj($out); +} + +# DER signed integer +# $1 number as octet string (base 256 representation, high byte first) +# returns number in DER integer encoding +sub der_bigint($) { + my $x = shift; + + return chr(0x02) . der_len_obj($x); +} + +# DER positive integer with leading zeroes stripped +# $1 number as octet string (base 256 representation, high byte first) +# returns number in DER integer encoding +sub der_pos_bigint($) { + my $x = shift; + + # strip leading zero digits + $x =~ s/^[\0]+//; + + # need to prepend a zero if high bit set, since it would otherwise be + # interpreted as a negative number. Also needed for number 0. + if (!length($x) || ord(substr($x, 0, 1)) >= 128) { + $x = chr(0) . $x; + } + + return der_bigint($x); +} + +# $1 number as signed integer +# returns number as signed DER integer encoding +sub der_int($) { + my $n = shift; + + return der_bigint(int_base256_signed($n)); +} + +# the NULL object constant +sub der_null() { + return chr(0x05) . chr(0x00); +} + +# Unit test helper +# $1 calculated result +# $2 expected result +# no return value, dies if results differ, showing caller's line number +sub der_test($$) { + my $actual = bin2hex(shift); + my $expected = shift; + + my @caller = caller; + $actual eq $expected or die "Error:line $caller[2]:assertion failed: " + ."$actual != $expected\n"; +} + +# Unit testing for the DER encoding functions +# Examples from http://www.columbia.edu/~ariel/ssleay/layman.html +# No input, no output. Dies if unit tests fail. +sub der_unit_test { + ## uncomment these if you want to test the test framework + #print STDERR "Unit test running\n"; + #der_test chr(0), "42"; + + der_test der_null, "0500"; + + # length bytes + der_test der_len(1), "01"; + der_test der_len(127), "7f"; + der_test der_len(128), "8180"; + der_test der_len(256), "820100"; + der_test der_len(65536), "83010000"; + + # bigint + der_test der_bigint(chr(0)), "020100"; + der_test der_bigint(chr(128)), "020180"; # -128 + der_test der_pos_bigint(chr(128)), "02020080"; # +128 + der_test der_pos_bigint(chr(0).chr(0).chr(1)), "020101"; + der_test der_pos_bigint(chr(0)), "020100"; + + # integers (tests base256 conversion) + der_test der_int( 0), "020100"; + der_test der_int( 127), "02017f"; + der_test der_int( 128), "02020080"; + der_test der_int( 256), "02020100"; + der_test der_int( -1), "0201ff"; + der_test der_int( -128), "020180"; + der_test der_int( -129), "0202ff7f"; + der_test der_int(-65536), "0203ff0000"; + der_test der_int(-65537), "0203feffff"; + + # object encoding, "RSA Security" + der_test der_base128(840), "8648"; + der_test der_objectid(1, 2, 840, 113549), "06062a864886f70d"; + + # Combinations + der_test der_bitstring("ABCD"), "03050041424344"; + der_test der_bitstring(der_null), "0303000500"; + der_test der_seq(der_int(0), der_null), "30050201000500"; + + # The big picture + der_test der_seq(der_seq(der_objectid(1, 2, 840, 113549), der_null), + der_bitstring(der_seq(der_pos_bigint(chr(5)), + der_pos_bigint(chr(3))))), + "3017300a06062a864886f70d05000309003006020105020103"; +} + +#################################################### +# OpenSSL missing functionality workarounds + +## Format of an RSA public key: +# 0:d=0 hl=3 l= 159 cons: SEQUENCE +# 3:d=1 hl=2 l= 13 cons: SEQUENCE +# 5:d=2 hl=2 l= 9 prim: OBJECT :rsaEncryption +# 16:d=2 hl=2 l= 0 prim: NULL +# 18:d=1 hl=3 l= 141 prim: BIT STRING +# [ sequence: INTEGER (n), INTEGER (e) ] + +# generate RSA pub key in PEM format +# $1: filename where PEM key is to be stored +# $2: n of the RSA key in hex +# $3: e of the RSA key in hex +# return: nothing, but file created +sub gen_pubrsakey($$$) { + my $filename=shift; + my $n = shift; + my $e = shift; + + # make sure the DER encoder works ;-) + der_unit_test(); + + # generate DER encoding of the public key + + my $rsaEncryption = der_objectid(1, 2, 840, 113549, 1, 1, 1); + + my $der = der_seq(der_seq($rsaEncryption, der_null), + der_bitstring(der_seq(der_pos_bigint(hex2bin($n)), + der_pos_bigint(hex2bin($e))))); + + open(FH, ">", $filename) or die; + print FH pem_cert($der); + close FH; + +} + +# generate RSA pub key in PEM format +# +# This implementation uses "openssl asn1parse -genconf" which was added +# in openssl 0.9.8. It is not available in older openssl versions. +# +# $1: filename where PEM key is to be stored +# $2: n of the RSA key in hex +# $3: e of the RSA key in hex +# return: nothing, but file created +sub gen_pubrsakey_using_openssl($$$) { + my $filename=shift; + my $n = shift; + my $e = shift; + + my $asn1 = "asn1=SEQUENCE:pubkeyinfo + +[pubkeyinfo] +algorithm=SEQUENCE:rsa_alg +pubkey=BITWRAP,SEQUENCE:rsapubkey + +[rsa_alg] +algorithm=OID:rsaEncryption +parameter=NULL + +[rsapubkey] +n=INTEGER:0x$n + +e=INTEGER:0x$e"; + + open(FH, ">$filename.cnf") or die "Cannot create file $filename.cnf: $?"; + print FH $asn1; + close FH; + my @args = ("openssl", "asn1parse", "-genconf", "$filename.cnf", "-noout", "-out", "$filename.der"); + system(@args) == 0 or die "system @args failed: $?"; + @args = ("openssl", "rsa", "-inform", "DER", "-in", "$filename.der", + "-outform", "PEM", "-pubin", "-pubout", "-out", "$filename"); + system(@args) == 0 or die "system @args failed: $?"; + die "RSA PEM formatted key file $filename was not created" + if (! -f $filename); + + unlink("$filename.cnf"); + unlink("$filename.der"); +} + +############################################ +# Test cases + +# This is the Known Answer Test +# $1: the string that we have to put in front of the key +# when printing the key +# $2: crypto key1 in hex form +# $3: crypto key2 in hex form (TDES, undef otherwise) +# $4: crypto key3 in hex form (TDES, undef otherwise) +# $5: IV in hex form +# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form +# $7: cipher +# $8: encrypt=1/decrypt=0 +# return: string formatted as expected by CAVS +sub kat($$$$$$$$) { + my $keytype = shift; + my $key1 = shift; + my $key2 = shift; + my $key3 = shift; + my $iv = shift; + my $pt = shift; + my $cipher = shift; + my $enc = shift; + + my $out = ""; + + $out .= "$keytype = $key1\n"; + + # this is the concardination of the keys for 3DES + if (defined($key2)) { + $out .= "KEY2 = $key2\n"; + $key1 = $key1 . $key2; + } + if (defined($key3)) { + $out .= "KEY3 = $key3\n"; + $key1= $key1 . $key3; + } + + $out .= "IV = $iv\n" if (defined($iv) && $iv ne ""); + if ($enc) { + $out .= "PLAINTEXT = $pt\n"; + $out .= "CIPHERTEXT = " . &$encdec($key1, $iv, $cipher, 1, $pt) . "\n"; + } else { + $out .= "CIPHERTEXT = $pt\n"; + $out .= "PLAINTEXT = " . &$encdec($key1, $iv, $cipher, 0, $pt) . "\n"; + } + + return $out; +} + +# This is the Known Answer Test for Hashes +# $1: Plaintext in hex form +# $2: hash +# $3: hash length (undef if not applicable) +# return: string formatted as expected by CAVS +sub hash_kat($$$) { + my $pt = shift; + my $cipher = shift; + my $len = shift; + + my $out = ""; + $out .= "Len = $len\n" if (defined($len)); + $out .= "Msg = $pt\n"; + + $pt = "" if(!$len); + $out .= "MD = " . &$hash($pt, $cipher) . "\n"; + return $out; +} + +# Known Answer Test for HMAC hash +# $1: key length in bytes +# $2: MAC length in bytes +# $3: key for HMAC in hex form +# $4: message to be hashed +# return: string formatted as expected by CAVS +sub hmac_kat($$$$) { + my $klen = shift; + my $tlen = shift; + my $key = shift; + my $msg = shift; + + # XXX this is a hack - we need to decipher the HMAC REQ files in a more + # sane way + # + # This is a conversion table from the expected hash output size + # to the assumed hash type - we only define here the block size of + # the underlying hashes and do not allow any truncation + my %hashtype = ( + 20 => 1, + 28 => 224, + 32 => 256, + 48 => 384, + 64 => 512 + ); + + die "Hash output size $tlen is not supported!" + if(!defined($hashtype{$tlen})); + + my $out = ""; + $out .= "Klen = $klen\n"; + $out .= "Tlen = $tlen\n"; + $out .= "Key = $key\n"; + $out .= "Msg = $msg\n"; + $out .= "Mac = " . &$hmac($key, $tlen, $msg, $hashtype{$tlen}) . "\n"; + + return $out; +} + + +# Cipher Monte Carlo Testing +# $1: the string that we have to put in front of the key +# when printing the key +# $2: crypto key1 in hex form +# $3: crypto key2 in hex form (TDES, undef otherwise) +# $4: crypto key3 in hex form (TDES, undef otherwise) +# $5: IV in hex form +# $6: Plaintext (enc=1) or Ciphertext (enc=0) in hex form +# $7: cipher +# $8: encrypt=1/decrypt=0 +# return: string formatted as expected by CAVS +sub crypto_mct($$$$$$$$) { + my $keytype = shift; + my $key1 = hex2bin(shift); + my $key2 = shift; + my $key3 = shift; + my $iv = hex2bin(shift); + my $source_data = hex2bin(shift); + my $cipher = shift; + my $enc = shift; + + my $out = ""; + + $key2 = hex2bin($key2) if (defined($key2)); + $key3 = hex2bin($key3) if (defined($key3)); + my $bufsize = length($source_data); + + # for AES: outer loop 0-99, inner 0-999 based on FIPS compliance tests + # for RC4: outer loop 0-99, inner 0-999 based on atsec compliance tests + # for DES: outer loop 0-399, inner 0-9999 based on FIPS compliance tests + my $ciph = substr($cipher,0,3); + my $oloop=100; + my $iloop=1000; + if ($ciph =~ /des/) {$oloop=400;$iloop=10000;} + + for (my $i=0; $i<$oloop; ++$i) { + $out .= "COUNT = $i\n"; + if (defined($key2)) { + $out .= "$keytype = ". bin2hex($key1). "\n"; + $out .= "KEY2 = ". bin2hex($key2). "\n"; + $key1 = $key1 . $key2; + } else { + $out .= "$keytype = ". bin2hex($key1). "\n"; + } + if(defined($key3)) { + $out .= "KEY3 = ". bin2hex($key3). "\n"; + $key1 = $key1 . $key3; + } + my $keylen = length($key1); + + $out .= "IV = ". bin2hex($iv) . "\n" + if (defined($iv) && $iv ne ""); + + if ($enc) { + $out .= "PLAINTEXT = ". bin2hex($source_data). "\n"; + } else { + $out .= "CIPHERTEXT = ". bin2hex($source_data). "\n"; + } + my ($CO, $CI); + my $cipher_imp = &$state_cipher($cipher, $enc, $bufsize, $key1, $iv); + $cipher_imp = &$state_cipher_des($cipher, $enc, $bufsize, $key1, $iv) if($cipher =~ /des/); + my $pid = open2($CO, $CI, $cipher_imp); + + my $calc_data = $iv; # CT[j] + my $old_calc_data; # CT[j-1] + my $old_old_calc_data; # CT[j-2] + my $next_source; + + # TDES inner loop implements logic within driver + if ($cipher =~ /des/) { + # Need to provide a dummy IV in case of ECB mode. + my $iv_arg = (defined($iv) && $iv ne "") + ? bin2hex($iv) + : "00"x(length($source_data)); + print $CI "1\n" + .$iloop."\n" + .bin2hex($key1)."\n" + .$iv_arg."\n" + .bin2hex($source_data)."\n\n" or die; + chomp(my $line = <$CO>); + $calc_data = hex2bin($line); + chomp($line = <$CO>); + $old_calc_data = hex2bin($line); + chomp($line = <$CO>); + $old_old_calc_data = hex2bin($line); + chomp($line = <$CO>); + $iv = hex2bin($line) if (defined($iv) && $iv ne ""); + chomp($line = <$CO>); + $next_source = hex2bin($line); + # Skip over empty line. + $line = <$CO>; + } else { + for (my $j = 0; $j < $iloop; ++$j) { + $old_old_calc_data = $old_calc_data; + $old_calc_data = $calc_data; + + #print STDERR "source_data=", bin2hex($source_data), "\n"; + syswrite $CI, $source_data or die $!; + my $len = sysread $CO, $calc_data, $bufsize; + + #print STDERR "len=$len, bufsize=$bufsize\n"; + die if $len ne $bufsize; + #print STDERR "calc_data=", bin2hex($calc_data), "\n"; + + if ( (!$enc && $ciph =~ /des/) || + $ciph =~ /rc4/ || + $cipher =~ /ecb/ ) { + #TDES in decryption mode, RC4 and ECB mode + #have a special rule + $source_data = $calc_data; + } else { + $source_data = $old_calc_data; + } + } + } + close $CO; + close $CI; + waitpid $pid, 0; + + if ($enc) { + $out .= "CIPHERTEXT = ". bin2hex($calc_data). "\n\n"; + } else { + $out .= "PLAINTEXT = ". bin2hex($calc_data). "\n\n"; + } + + if ( $ciph =~ /aes/ ) { + $key1 ^= substr($old_calc_data . $calc_data, -$keylen); + #print STDERR bin2hex($key1)."\n"; + } elsif ( $ciph =~ /des/ ) { + die "Wrong keylen $keylen" if ($keylen != 24); + + # $nkey needed as $key holds the concatenation of the + # old key atm + my $nkey = fix_key_parity(substr($key1,0,8) ^ $calc_data); + #print STDERR "KEY1 = ". bin2hex($nkey)."\n"; + if (substr($key1,0,8) ne substr($key1,8,8)) { + #print STDERR "KEY2 recalc: KEY1==KEY3, KEY2 indep. or all KEYs are indep.\n"; + $key2 = fix_key_parity((substr($key1,8,8) ^ $old_calc_data)); + } else { + #print STDERR "KEY2 recalc: KEY1==KEY2==KEY3\n"; + $key2 = fix_key_parity((substr($key1,8,8) ^ $calc_data)); + } + #print STDERR "KEY2 = ". bin2hex($key2)."\n"; + if ( substr($key1,0,8) eq substr($key1,16)) { + #print STDERR "KEY3 recalc: KEY1==KEY2==KEY3 or KEY1==KEY3, KEY2 indep.\n"; + $key3 = fix_key_parity((substr($key1,16) ^ $calc_data)); + } else { + #print STDERR "KEY3 recalc: all KEYs are independent\n"; + $key3 = fix_key_parity((substr($key1,16) ^ $old_old_calc_data)); + } + #print STDERR "KEY3 = ". bin2hex($key3)."\n"; + + # reset the first key - concardination happens at + # beginning of loop + $key1=$nkey; + } elsif ($ciph =~ /rc4/ ) { + $key1 ^= substr($calc_data, 0, 16); + #print STDERR bin2hex($key1)."\n"; + } else { + die "Test limitation: cipher '$cipher' not supported in Monte Carlo testing"; + } + + if ($cipher =~ /des-ede3-ofb/) { + $source_data = $source_data ^ $next_source; + } elsif (!$enc && $cipher =~ /des-ede3-cfb/) { + #TDES decryption CFB has a special rule + $source_data = $next_source; + } elsif ( $ciph =~ /rc4/ || $cipher eq "des-ede3" || $cipher =~ /ecb/) { + #No resetting of IV as the IV is all zero set initially (i.e. no IV) + $source_data = $calc_data; + } elsif (! $enc && $ciph =~ /des/ ) { + #TDES in decryption mode has a special rule + $iv = $old_calc_data; + $source_data = $calc_data; + } else { + $iv = $calc_data; + $source_data = $old_calc_data; + } + } + + return $out; +} + +# Hash Monte Carlo Testing +# $1: Plaintext in hex form +# $2: hash +# return: string formatted as expected by CAVS +sub hash_mct($$) { + my $pt = shift; + my $cipher = shift; + + my $out = ""; + + $out .= "Seed = $pt\n\n"; + + for (my $j=0; $j<100; ++$j) { + $out .= "COUNT = $j\n"; + my $md0=$pt; + my $md1=$pt; + my $md2=$pt; + for (my $i=0; $i<1000; ++$i) { + #print STDERR "outer loop $j; inner loop $i\n"; + my $mi= $md0 . $md1 . $md2; + $md0=$md1; + $md1=$md2; + $md2 = &$hash($mi, $cipher); + $md2 =~ s/\n//; + } + $out .= "MD = $md2\n\n"; + $pt=$md2; + } + + return $out; +} + +# RSA SigGen test +# $1: Message to be signed in hex form +# $2: Hash algorithm +# $3: file name with RSA key in PEM form +# return: string formatted as expected by CAVS +sub rsa_siggen($$$) { + my $data = shift; + my $cipher = shift; + my $keyfile = shift; + + my $out = ""; + + $out .= "SHAAlg = $cipher\n"; + $out .= "Msg = $data\n"; + $out .= "S = " . &$rsa_sign($data, lc($cipher), $keyfile) . "\n"; + + return $out; +} + +# RSA SigVer test +# $1: Message to be verified in hex form +# $2: Hash algoritm +# $3: Signature of message in hex form +# $4: n of the RSA key in hex in hex form +# $5: e of the RSA key in hex in hex form +# return: string formatted as expected by CAVS +sub rsa_sigver($$$$$) { + my $data = shift; + my $cipher = shift; + my $signature = shift; + my $n = shift; + my $e = shift; + + my $out = ""; + + $out .= "SHAAlg = $cipher\n"; + $out .= "e = $e\n"; + $out .= "Msg = $data\n"; + $out .= "S = $signature\n"; + + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine + my $keyfile = "rsa_sigver.tmp.$$"; + gen_pubrsakey($keyfile, $n, $e); + + my $sigfile = "$keyfile.sig"; + open(FH, ">$sigfile") or die "Cannot create file $sigfile: $?"; + print FH hex2bin($signature); + close FH; + + $out .= "Result = " . (&$rsa_verify($data, lc($cipher), $keyfile, $sigfile) ? "P\n" : "F\n"); + + unlink($keyfile); + unlink($sigfile); + + return $out; +} + +# RSA X9.31 key generation test +# $1 modulus size +# $2 e +# $3 xp1 +# $4 xp2 +# $5 Xp +# $6 xq1 +# $7 xq2 +# $8 Xq +# return: string formatted as expected by CAVS +sub rsa_keygen($$$$$$$$) { + my $modulus = shift; + my $e = shift; + my $xp1 = shift; + my $xp2 = shift; + my $Xp = shift; + my $xq1 = shift; + my $xq2 = shift; + my $Xq = shift; + + my $out = ""; + + my $ret = &$rsa_derive($modulus, $e, $xp1, $xp2, $Xp, $xq1, $xq2, $Xq); + + my ($P, $Q, $N, $D) = split(/\n/, $ret); + + $out .= "e = $e\n"; + $out .= "xp1 = $xp1\n"; + $out .= "xp2 = $xp2\n"; + $out .= "Xp = $Xp\n"; + $out .= "p = $P\n"; + $out .= "xq1 = $xq1\n"; + $out .= "xq2 = $xq2\n"; + $out .= "Xq = $Xq\n"; + $out .= "q = $Q\n"; + $out .= "n = $N\n"; + $out .= "d = $D\n\n"; + + return $out; + +} + +# X9.31 RNG test +# $1 key for the AES cipher +# $2 DT value +# $3 V value +# $4 type ("VST", "MCT") +# return: string formatted as expected by CAVS +sub rngx931($$$$) { + my $key=shift; + my $dt=shift; + my $v=shift; + my $type=shift; + + my $out = "Key = $key\n"; + $out .= "DT = $dt\n"; + $out .= "V = $v\n"; + + my $count = 1; + $count = 10000 if ($type eq "MCT"); + + my $rnd_val = ""; + + # we read 16 bytes from RNG + my $bufsize = 16; + + my ($CO, $CI); + my $rng_imp = &$state_rng($key, $dt, $v); + my $pid = open2($CO, $CI, $rng_imp); + for (my $i = 0; $i < $count; ++$i) { + my $len = sysread $CO, $rnd_val, $bufsize; + #print STDERR "len=$len, bufsize=$bufsize\n"; + die "len=$len != bufsize=$bufsize" if $len ne $bufsize; + #print STDERR "calc_data=", bin2hex($rnd_val), "\n"; + } + close $CO; + close $CI; + waitpid $pid, 0; + + $out .= "R = " . bin2hex($rnd_val) . "\n\n"; + + return $out; +} + +# DSA PQGGen test +# $1 modulus size +# $2 number of rounds to perform the test +# return: string formatted as expected by CAVS +sub dsa_pqggen_driver($$) { + my $mod = shift; + my $rounds = shift; + + my $out = ""; + for(my $i=0; $i<$rounds; $i++) { + my $ret = &$dsa_pqggen($mod); + my ($P, $Q, $G, $Seed, $c, $H) = split(/\n/, $ret); + die "Return value does not contain all expected values of P, Q, G, Seed, c, H for dsa_pqggen" + if (!defined($P) || !defined($Q) || !defined($G) || + !defined($Seed) || !defined($c) || !defined($H)); + + # now change the counter to decimal as CAVS wants decimal + # counter value although all other is HEX + $c = hex($c); + + $out .= "P = $P\n"; + $out .= "Q = $Q\n"; + $out .= "G = $G\n"; + $out .= "Seed = $Seed\n"; + $out .= "c = $c\n"; + $out .= "H = $H\n\n"; + } + + return $out; +} + + +# DSA SigGen test +# $1: Message to be signed in hex form +# $2: file name with DSA key in PEM form +# return: string formatted as expected by CAVS +sub dsa_siggen($$) { + my $data = shift; + my $keyfile = shift; + + my $out = ""; + + my %ret = &$dsa_sign($data, $keyfile); + + $out .= "Msg = $data\n"; + $out .= "Y = " . $ret{'Y'} . "\n"; + $out .= "R = " . $ret{'R'} . "\n"; + $out .= "S = " . $ret{'S'} . "\n"; + + return $out; +} + + +# DSA signature verification +# $1 modulus +# $2 P +# $3 Q +# $4 G +# $5 Y - public key +# $6 r +# $7 s +# $8 message to be verified +# return: string formatted as expected by CAVS +sub dsa_sigver($$$$$$$$) { + my $modulus = shift; + my $p = shift; + my $q = shift; + my $g = shift; + my $y = shift; + my $r = shift; + my $s = shift; + my $msg = shift; + + my $out = ""; + + #PQG are already printed - do not print them here + + $out .= "Msg = $msg\n"; + $out .= "Y = $y\n"; + $out .= "R = $r\n"; + $out .= "S = $s\n"; + + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine + my $keyfile = "dsa_sigver.tmp.$$"; + &$dsa_genpubkey($keyfile, $p, $q, $g, $y); + + $out .= "Result = " . (&$dsa_verify($msg, $keyfile, $r, $s) ? "P\n" : "F\n"); + + unlink($keyfile); + + return $out; +} + +############################################################## +# Parser of input file and generator of result file +# + +sub usage() { + + print STDERR "Usage: +$0 [-R] [-D] [-I name] <CAVS-test vector file> + +-R execution of ARCFOUR instead of OpenSSL +-I NAME Use interface style NAME: + openssl OpenSSL (default) + libgcrypt Libgcrypt +-D SigGen and SigVer are executed with DSA + Please note that the DSA CAVS vectors do not allow distinguishing + them from the RSA vectors. As the RSA test is the default, you have + to supply this option to apply the DSA logic"; +} + +# Parser of CAVS test vector file +# $1: Test vector file +# $2: Output file for test results +# return: nothing +sub parse($$) { + my $infile = shift; + my $outfile = shift; + + my $out = ""; + + # this is my cipher/hash type + my $cipher = ""; + + # Test type + # 1 - cipher known answer test + # 2 - cipher Monte Carlo test + # 3 - hash known answer test + # 4 - hash Monte Carlo test + # 5 - RSA signature generation + # 6 - RSA signature verification + my $tt = 0; + + # Variables for tests + my $keytype = ""; # we can have "KEY", "KEYs", "KEY1" + my $key1 = ""; + my $key2 = undef; #undef needed for allowing + my $key3 = undef; #the use of them as input variables + my $pt = ""; + my $enc = 1; + my $iv = ""; + my $len = undef; #see key2|3 + my $n = ""; + my $e = ""; + my $signature = ""; + my $rsa_keyfile = ""; + my $dsa_keyfile = ""; + my $dt = ""; + my $v = ""; + my $klen = ""; + my $tlen = ""; + my $modulus = ""; + my $capital_n = 0; + my $capital_p = ""; + my $capital_q = ""; + my $capital_g = ""; + my $capital_y = ""; + my $capital_r = ""; + my $xp1 = ""; + my $xp2 = ""; + my $Xp = ""; + my $xq1 = ""; + my $xq2 = ""; + my $Xq = ""; + + my $mode = ""; + + open(IN, "<$infile"); + while(<IN>) { + + my $line = $_; + chomp($line); + $line =~ s/\r//; + + my $keylen = ""; + + # Mode and type check + # consider the following parsed line + # '# AESVS MCT test data for CBC' + # '# TDES Multi block Message Test for CBC' + # '# INVERSE PERMUTATION - KAT for CBC' + # '# SUBSTITUTION TABLE - KAT for CBC' + # '# TDES Monte Carlo (Modes) Test for CBC' + # '# "SHA-1 Monte" information for "IBMRHEL5"' + # '# "SigVer PKCS#1 Ver 1.5" information for "IBMRHEL5"' + # '# "SigGen PKCS#1 Ver 1.5" information for "IBMRHEL5"' + # '#RC4VS MCT test data' + + # avoid false positives from user specified 'for "PRODUCT"' strings + my $tmpline = $line; + $tmpline =~ s/ for ".*"//; + + ##### Extract cipher + # XXX there may be more - to be added + if ($tmpline =~ /^#.*(CBC|ECB|OFB|CFB|SHA-|SigGen|SigVer|RC4VS|ANSI X9\.31|Hash sizes tested|PQGGen|KeyGen RSA)/) { + if ($tmpline =~ /CBC/) { $mode="cbc"; } + elsif ($tmpline =~ /ECB/) { $mode="ecb"; } + elsif ($tmpline =~ /OFB/) { $mode="ofb"; } + elsif ($tmpline =~ /CFB/) { $mode="cfb"; } + #we do not need mode as the cipher is already clear + elsif ($tmpline =~ /SHA-1/) { $cipher="sha1"; } + elsif ($tmpline =~ /SHA-224/) { $cipher="sha224"; } + elsif ($tmpline =~ /SHA-256/) { $cipher="sha256"; } + elsif ($tmpline =~ /SHA-384/) { $cipher="sha384"; } + elsif ($tmpline =~ /SHA-512/) { $cipher="sha512"; } + #we do not need mode as the cipher is already clear + elsif ($tmpline =~ /RC4VS/) { $cipher="rc4"; } + elsif ($tmpline =~ /SigGen|SigVer/) { + die "Error: X9.31 is not supported" + if ($tmpline =~ /X9/); + $cipher="sha1"; #place holder - might be overwritten later + } + + if ($tmpline =~ /^#.*AESVS/) { + # AES cipher (part of it) + $cipher="aes"; + } + if ($tmpline =~ /^#.*(TDES|KAT)/) { + # TDES cipher (full definition) + # the FIPS-140 test generator tool does not produce + # machine readable output! + if ($mode eq "cbc") { $cipher="des-ede3-cbc"; } + if ($mode eq "ecb") { $cipher="des-ede3"; } + if ($mode eq "ofb") { $cipher="des-ede3-ofb"; } + if ($mode eq "cfb") { $cipher="des-ede3-cfb"; } + } + + # check for RNG + if ($tmpline =~ /ANSI X9\.31/) { + # change the tmpline to add the type of the + # test which is ONLY visible from the file + # name :-( + if ($infile =~ /MCT\.req/) { + $tmpline .= " MCT"; + } elsif ($infile =~ /VST\.req/) { + $tmpline .= " VST"; + } else { + die "Unexpected cipher type with $infile"; + } + } + + if ($tt == 0) { + ##### Identify the test type + if ($tmpline =~ /KeyGen RSA \(X9\.31\)/) { + $tt = 13; + die "Interface function rsa_derive for RSA key generation not defined for tested library" + if (!defined($rsa_derive)); + } elsif ($tmpline =~ /SigVer/ && $opt{'D'} ) { + $tt = 12; + die "Interface function dsa_verify or dsa_genpubkey for DSA verification not defined for tested library" + if (!defined($dsa_verify) || !defined($dsa_genpubkey)); + } elsif ($tmpline =~ /SigGen/ && $opt{'D'}) { + $tt = 11; + die "Interface function dsa_sign or gen_dsakey for DSA sign not defined for tested library" + if (!defined($dsa_sign) || !defined($gen_rsakey)); + } elsif ($tmpline =~ /PQGGen/) { + $tt = 10; + die "Interface function for DSA PQGGen testing not defined for tested library" + if (!defined($dsa_pqggen)); + } elsif ($tmpline =~ /Hash sizes tested/) { + $tt = 9; + die "Interface function hmac for HMAC testing not defined for tested library" + if (!defined($hmac)); + } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /MCT/) { + $tt = 8; + die "Interface function state_rng for RNG MCT not defined for tested library" + if (!defined($state_rng)); + } elsif ($tmpline =~ /ANSI X9\.31/ && $tmpline =~ /VST/) { + $tt = 7; + die "Interface function state_rng for RNG KAT not defined for tested library" + if (!defined($state_rng)); + } elsif ($tmpline =~ /SigVer/ ) { + $tt = 6; + die "Interface function rsa_verify or gen_rsakey for RSA verification not defined for tested library" + if (!defined($rsa_verify) || !defined($gen_rsakey)); + } elsif ($tmpline =~ /SigGen/ ) { + $tt = 5; + die "Interface function rsa_sign or gen_rsakey for RSA sign not defined for tested library" + if (!defined($rsa_sign) || !defined($gen_rsakey)); + } elsif ($tmpline =~ /Monte|MCT|Carlo/ && $cipher =~ /^sha/) { + $tt = 4; + die "Interface function hash for Hashing not defined for tested library" + if (!defined($hash)); + } elsif ($tmpline =~ /Monte|MCT|Carlo/) { + $tt = 2; + die "Interface function state_cipher for Stateful Cipher operation defined for tested library" + if (!defined($state_cipher) || !defined($state_cipher_des)); + } elsif ($cipher =~ /^sha/) { + $tt = 3; + die "Interface function hash for Hashing not defined for tested library" + if (!defined($hash)); + } else { + $tt = 1; + die "Interface function encdec for Encryption/Decryption not defined for tested library" + if (!defined($encdec)); + } + } + } + + # This is needed as ARCFOUR does not operate with an IV + $iv = "00000000000000000000000000000000" if ($cipher eq "rc4" + && $iv eq "" ); + + # we are now looking for the string + # '# Key Length : 256' + # found in AES + if ($tmpline =~ /^# Key Length.*?(128|192|256)/) { + if ($cipher eq "aes") { + $cipher="$cipher-$1-$mode"; + } else { + die "Error: Key length $1 given for cipher $cipher which is unexpected"; + } + } + + # Get the test data + if ($line =~ /^(KEY|KEY1|Key)\s*=\s*(.*)/) { # found in ciphers and RNG + die "KEY seen twice - input file crap" if ($key1 ne ""); + $keytype=$1; + $key1=$2; + $key1 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^(KEYs)\s*=\s*(.*)/) { # found in ciphers and RNG + die "KEY seen twice - input file crap" if ($key1 ne ""); + $keytype=$1; + $key1=$2; + $key1 =~ s/\s//g; #replace potential white spaces + $key2 = $key1; + $key3 = $key1; + } + elsif ($line =~ /^KEY2\s*=\s*(.*)/) { # found in TDES + die "First key not set, but got already second key - input file crap" if ($key1 eq ""); + die "KEY2 seen twice - input file crap" if (defined($key2)); + $key2=$1; + $key2 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^KEY3\s*=\s*(.*)/) { # found in TDES + die "Second key not set, but got already third key - input file crap" if ($key2 eq ""); + die "KEY3 seen twice - input file crap" if (defined($key3)); + $key3=$1; + $key3 =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^IV\s*=\s*(.*)/) { # found in ciphers + die "IV seen twice - input file crap" if ($iv ne ""); + $iv=$1; + $iv =~ s/\s//g; #replace potential white spaces + } + elsif ($line =~ /^PLAINTEXT\s*=\s*(.*)/) { # found in ciphers + if ( $1 !~ /\?/ ) { #only use it if there is valid hex data + die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); + $pt=$1; + $pt =~ s/\s//g; #replace potential white spaces + $enc=1; + } + } + elsif ($line =~ /^CIPHERTEXT\s*=\s*(.*)/) { # found in ciphers + if ( $1 !~ /\?/ ) { #only use it if there is valid hex data + die "PLAINTEXT/CIPHERTEXT seen twice - input file crap" if ($pt ne ""); + $pt=$1; + $pt =~ s/\s//g; #replace potential white spaces + $enc=0; + } + } + elsif ($line =~ /^Len\s*=\s*(.*)/) { # found in hashs + $len=$1; + } + elsif ($line =~ /^(Msg|Seed)\s*=\s*(.*)/) { # found in hashs + die "Msg/Seed seen twice - input file crap" if ($pt ne ""); + $pt=$2; + } + elsif ($line =~ /^\[mod\s*=\s*(.*)\]$/) { # found in RSA requests + $modulus = $1; + $out .= $line . "\n\n"; # print it + # generate the private key with given bit length now + # as we have the required key length in bit + if ($tt == 11) { + $dsa_keyfile = "dsa_siggen.tmp.$$"; + my %pqg = &$gen_dsakey($dsa_keyfile); + $out .= "P = " . $pqg{'P'} . "\n"; + $out .= "Q = " . $pqg{'Q'} . "\n"; + $out .= "G = " . $pqg{'G'} . "\n"; + } elsif ( $tt == 5 ) { + # XXX maybe a secure temp file name is better here + # but since it is not run on a security sensitive + # system, I hope that this is fine + $rsa_keyfile = "rsa_siggen.tmp.$$"; + &$gen_rsakey($modulus, $rsa_keyfile); + my $modulus = pipe_through_program("", "openssl rsa -pubout -modulus -in $rsa_keyfile"); + $modulus =~ s/Modulus=(.*?)\s(.|\s)*/$1/; + $out .= "n = $modulus\n"; + $out .= "\ne = 10001\n" + } + } + elsif ($line =~ /^SHAAlg\s*=\s*(.*)/) { #found in RSA requests + $cipher=$1; + } + elsif($line =~ /^n\s*=\s*(.*)/) { # found in RSA requests + $out .= $line . "\n"; + $n=$1; + } + elsif ($line =~ /^e\s*=\s*(.*)/) { # found in RSA requests + $e=$1; + } + elsif ($line =~ /^S\s*=\s*(.*)/) { # found in RSA requests + die "S seen twice - input file crap" if ($signature ne ""); + $signature=$1; + } + elsif ($line =~ /^DT\s*=\s*(.*)/) { # X9.31 RNG requests + die "DT seen twice - check input file" + if ($dt ne ""); + $dt=$1; + } + elsif ($line =~ /^V\s*=\s*(.*)/) { # X9.31 RNG requests + die "V seen twice - check input file" + if ($v ne ""); + $v=$1; + } + elsif ($line =~ /^Klen\s*=\s*(.*)/) { # HMAC requests + die "Klen seen twice - check input file" + if ($klen ne ""); + $klen=$1; + } + elsif ($line =~ /^Tlen\s*=\s*(.*)/) { # HMAC RNG requests + die "Tlen seen twice - check input file" + if ($tlen ne ""); + $tlen=$1; + } + elsif ($line =~ /^N\s*=\s*(.*)/) { #DSA PQGGen + die "N seen twice - check input file" + if ($capital_n); + $capital_n = $1; + } + elsif ($line =~ /^P\s*=\s*(.*)/) { #DSA SigVer + die "P seen twice - check input file" + if ($capital_p); + $capital_p = $1; + $out .= $line . "\n"; # print it + } + elsif ($line =~ /^Q\s*=\s*(.*)/) { #DSA SigVer + die "Q seen twice - check input file" + if ($capital_q); + $capital_q = $1; + $out .= $line . "\n"; # print it + } + elsif ($line =~ /^G\s*=\s*(.*)/) { #DSA SigVer + die "G seen twice - check input file" + if ($capital_g); + $capital_g = $1; + $out .= $line . "\n"; # print it + } + elsif ($line =~ /^Y\s*=\s*(.*)/) { #DSA SigVer + die "Y seen twice - check input file" + if ($capital_y); + $capital_y = $1; + } + elsif ($line =~ /^R\s*=\s*(.*)/) { #DSA SigVer + die "R seen twice - check input file" + if ($capital_r); + $capital_r = $1; + } + elsif ($line =~ /^xp1\s*=\s*(.*)/) { #RSA key gen + die "xp1 seen twice - check input file" + if ($xp1); + $xp1 = $1; + } + elsif ($line =~ /^xp2\s*=\s*(.*)/) { #RSA key gen + die "xp2 seen twice - check input file" + if ($xp2); + $xp2 = $1; + } + elsif ($line =~ /^Xp\s*=\s*(.*)/) { #RSA key gen + die "Xp seen twice - check input file" + if ($Xp); + $Xp = $1; + } + elsif ($line =~ /^xq1\s*=\s*(.*)/) { #RSA key gen + die "xq1 seen twice - check input file" + if ($xq1); + $xq1 = $1; + } + elsif ($line =~ /^xq2\s*=\s*(.*)/) { #RSA key gen + die "xq2 seen twice - check input file" + if ($xq2); + $xq2 = $1; + } + elsif ($line =~ /^Xq\s*=\s*(.*)/) { #RSA key gen + die "Xq seen twice - check input file" + if ($Xq); + $Xq = $1; + } + else { + $out .= $line . "\n"; + } + + # call tests if all input data is there + if ($tt == 1) { + if ($key1 ne "" && $pt ne "" && $cipher ne "") { + $out .= kat($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc); + $keytype = ""; + $key1 = ""; + $key2 = undef; + $key3 = undef; + $iv = ""; + $pt = ""; + } + } + elsif ($tt == 2) { + if ($key1 ne "" && $pt ne "" && $cipher ne "") { + $out .= crypto_mct($keytype, $key1, $key2, $key3, $iv, $pt, $cipher, $enc); + $keytype = ""; + $key1 = ""; + $key2 = undef; + $key3 = undef; + $iv = ""; + $pt = ""; + } + } + elsif ($tt == 3) { + if ($pt ne "" && $cipher ne "") { + $out .= hash_kat($pt, $cipher, $len); + $pt = ""; + $len = undef; + } + } + elsif ($tt == 4) { + if ($pt ne "" && $cipher ne "") { + $out .= hash_mct($pt, $cipher); + $pt = ""; + } + } + elsif ($tt == 5) { + if ($pt ne "" && $cipher ne "" && $rsa_keyfile ne "") { + $out .= rsa_siggen($pt, $cipher, $rsa_keyfile); + $pt = ""; + } + } + elsif ($tt == 6) { + if ($pt ne "" && $cipher ne "" && $signature ne "" && $n ne "" && $e ne "") { + $out .= rsa_sigver($pt, $cipher, $signature, $n, $e); + $pt = ""; + $signature = ""; + } + } + elsif ($tt == 7 ) { + if ($key1 ne "" && $dt ne "" && $v ne "") { + $out .= rngx931($key1, $dt, $v, "VST"); + $key1 = ""; + $dt = ""; + $v = ""; + } + } + elsif ($tt == 8 ) { + if ($key1 ne "" && $dt ne "" && $v ne "") { + $out .= rngx931($key1, $dt, $v, "MCT"); + $key1 = ""; + $dt = ""; + $v = ""; + } + } + elsif ($tt == 9) { + if ($klen ne "" && $tlen ne "" && $key1 ne "" && $pt ne "") { + $out .= hmac_kat($klen, $tlen, $key1, $pt); + $key1 = ""; + $tlen = ""; + $klen = ""; + $pt = ""; + } + } + elsif ($tt == 10) { + if ($modulus ne "" && $capital_n > 0) { + $out .= dsa_pqggen_driver($modulus, $capital_n); + #$mod is not resetted + $capital_n = 0; + } + } + elsif ($tt == 11) { + if ($pt ne "" && $dsa_keyfile ne "") { + $out .= dsa_siggen($pt, $dsa_keyfile); + $pt = ""; + } + } + elsif ($tt == 12) { + if ($modulus ne "" && + $capital_p ne "" && + $capital_q ne "" && + $capital_g ne "" && + $capital_y ne "" && + $capital_r ne "" && + $signature ne "" && + $pt ne "") { + $out .= dsa_sigver($modulus, + $capital_p, + $capital_q, + $capital_g, + $capital_y, + $capital_r, + $signature, + $pt); + + # We do not clear the domain values PQG and + # the modulus value as they + # are specified only once in a file + # and we do not need to print them as they + # are already printed above + $capital_y = ""; + $capital_r = ""; + $signature = ""; + $pt = ""; + } + } + elsif ($tt == 13) { + if($modulus ne "" && + $e ne "" && + $xp1 ne "" && + $xp2 ne "" && + $Xp ne "" && + $xq1 ne "" && + $xq2 ne "" && + $Xq ne "") { + $out .= rsa_keygen($modulus, + $e, + $xp1, + $xp2, + $Xp, + $xq1, + $xq2, + $Xq); + $e = ""; + $xp1 = ""; + $xp2 = ""; + $Xp = ""; + $xq1 = ""; + $xq2 = ""; + $Xq = ""; + } + } + elsif ($tt > 0) { + die "Test case $tt not defined"; + } + } + + close IN; + $out =~ s/\n/\r\n/g; # make it a dos file + open(OUT, ">$outfile") or die "Cannot create output file $outfile: $?"; + print OUT $out; + close OUT; + +} + +# Signalhandler +sub cleanup() { + unlink("rsa_siggen.tmp.$$"); + unlink("rsa_sigver.tmp.$$"); + unlink("rsa_sigver.tmp.$$.sig"); + unlink("rsa_sigver.tmp.$$.der"); + unlink("rsa_sigver.tmp.$$.cnf"); + unlink("dsa_siggen.tmp.$$"); + unlink("dsa_sigver.tmp.$$"); + unlink("dsa_sigver.tmp.$$.sig"); + exit; +} + +############################################################ +# +# let us pretend to be C :-) +sub main() { + + usage() unless @ARGV; + + getopts("DRI:", \%opt) or die "bad option"; + + ##### Set library + + if ( ! defined $opt{'I'} || $opt{'I'} eq 'openssl' ) { + print STDERR "Using OpenSSL interface functions\n"; + $encdec = \&openssl_encdec; + $rsa_sign = \&openssl_rsa_sign; + $rsa_verify = \&openssl_rsa_verify; + $gen_rsakey = \&openssl_gen_rsakey; + $hash = \&openssl_hash; + $state_cipher = \&openssl_state_cipher; + } elsif ( $opt{'I'} eq 'libgcrypt' ) { + print STDERR "Using libgcrypt interface functions\n"; + $encdec = \&libgcrypt_encdec; + $rsa_sign = \&libgcrypt_rsa_sign; + $rsa_verify = \&libgcrypt_rsa_verify; + $gen_rsakey = \&libgcrypt_gen_rsakey; + $rsa_derive = \&libgcrypt_rsa_derive; + $hash = \&libgcrypt_hash; + $state_cipher = \&libgcrypt_state_cipher; + $state_cipher_des = \&libgcrypt_state_cipher_des; + $state_rng = \&libgcrypt_state_rng; + $hmac = \&libgcrypt_hmac; + $dsa_pqggen = \&libgcrypt_dsa_pqggen; + $gen_dsakey = \&libgcrypt_gen_dsakey; + $dsa_sign = \&libgcrypt_dsa_sign; + $dsa_verify = \&libgcrypt_dsa_verify; + $dsa_genpubkey = \&libgcrypt_dsa_genpubkey; + } else { + die "Invalid interface option given"; + } + + my $infile=$ARGV[0]; + die "Error: Test vector file $infile not found" if (! -f $infile); + + my $outfile = $infile; + # let us add .rsp regardless whether we could strip .req + $outfile =~ s/\.req$//; + if ($opt{'R'}) { + $outfile .= ".rc4"; + } else { + $outfile .= ".rsp"; + } + if (-f $outfile) { + die "Output file $outfile could not be removed: $?" + unless unlink($outfile); + } + print STDERR "Performing tests from source file $infile with results stored in destination file $outfile\n"; + + #Signal handler + $SIG{HUP} = \&cleanup; + $SIG{INT} = \&cleanup; + $SIG{QUIT} = \&cleanup; + $SIG{TERM} = \&cleanup; + + # Do the job + parse($infile, $outfile); + + cleanup(); + +} + +########################################### +# Call it +main(); +1; diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_tests.sh b/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_tests.sh new file mode 100644 index 0000000000..b9aa62168c --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/cavs_tests.sh @@ -0,0 +1,135 @@ +#!/bin/sh +# Run FIPS CAVS tests +# Copyright 2008 Free Software Foundation, Inc. +# +# This file is free software; as a special exception the author gives +# unlimited permission to copy and/or distribute it, with or without +# modifications, as long as this notice is preserved. +# +# This file is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY, to the extent permitted by law; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Instructions: +# +# 1. Cd to the libgcrypt/tests directory +# +# 2. Unpack the test vector tarball into subdirectory named "cavs". +# An example directory layout after unpacking might be: +# libgcrypt/tests/cavs/AES/req/CBCGFSbox128.req +# libgcrypt/tests/cavs/AES/req/CFB128MCT128.req +# +# Note that below the "cavs" directory there should only be one +# directory part named "req". Further avoid directory part +# names "resp". +# +# 3. Run this script from the libgcrypt/tests directory: +# ./cavs_tests.sh +# +# 4. Send the result file cavs/CAVS_results-*.zip to the testing lab. +# + +# Stop script if something unexpected happens. +set -e + +# A global flag to keep track of errors. +errors_seen_file="$(pwd)/.#cavs_test.errors_seen.tmp" +[ -f "$errors_seen_file" ] && rm "$errors_seen_file" +continue_mode=no +[ "$1" = "--continue" ] && continue_mode=yes + + +# Function to run one test. +# The argument is the request file name. +function run_one_test () { + local reqfile="$1" + local rspfile + local tmprspfile + local respdir + local dflag="" + + tmprspfile=$(echo "$reqfile" | sed 's,.req$,.rsp,') + rspfile=$(echo "$tmprspfile" | sed 's,/req/,/resp/,' ) + respdir=$(dirname "$rspfile") + [ -f "$tmprspfile" ] && rm "$tmprspfile" + [ -d "$respdir" ] || mkdir "$respdir" + [ -f "$rspfile" ] && rm "$rspfile" + + if echo "$reqfile" | grep '/DSA/req/' >/dev/null 2>/dev/null; then + dflag="-D" + fi + + if ./cavs_driver.pl -I libgcrypt $dflag "$reqfile"; then + if [ -f "$tmprspfile" ]; then + mv "$tmprspfile" "$rspfile" + else + echo "failed test: $reqfile" >&2 + : >"$errors_seen_file" + fi + else + echo "failed test: $reqfile rc=$?" >&2 + : >"$errors_seen_file" + fi +} + + + +# Save date and system architecure to construct the output archive name +DATE=$(date +%Y%m%d) +ARCH=$(arch || echo unknown) +result_file="CAVS_results-$ARCH-$DATE.zip" + +for f in fipsdrv cavs_driver.pl; do + if [ ! -f "./$f" ]; then + echo "required program \"$f\" missing in current directory" >&2 + exit 2 + fi +done +if [ ! -d cavs ]; then + echo "required directory \"cavs\" missing below current directory" >&2 + exit 2 +fi +if [ ! zip -h >/dev/null 2>&1 ]; then + echo "required program \"zip\" is not installed on this system" >&2 + exit 2 +fi + +# Set the PATH to this directory so that the perl script is able to +# find the test drivers. +PATH=.:$PATH + +# Check whether there are any stale response files +find cavs -type f -name "*.rsp" | ( while read f ; do + echo "Stale response file: $f" >&2 + any=yes +done +if [ "$any" = "yes" ]; then + echo "Stale response files found" >&2 + if [ "$continue_mode" != "yes" ]; then + echo "use option --continue if that is not a problem" >&2 + exit 1 + fi +fi +) || exit 1 + + +# Find all test files and run the tests. +find cavs -type f -name "*.req" | while read f ; do + echo "Running test file $f" >&2 + run_one_test "$f" + if [ -f "$errors_seen_file" ]; then + break; + fi +done + +if [ -f "$errors_seen_file" ]; then + rm "$errors_seen_file" + echo "Error encountered - not packing up response file" >&2 + exit 1 +fi + +echo "Packing up all response files" >&2 +cd cavs +find . -type f -name "*rsp" -print | zip -@ "$result_file" + +echo "Result file is: cavs/$result_file" >&2 diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/fips186-dsa.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/fips186-dsa.c new file mode 100644 index 0000000000..cdb507b666 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/fips186-dsa.c @@ -0,0 +1,465 @@ +/* fips186-dsa.c - FIPS 186 DSA tests + * Copyright (C) 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include <gcrypt.h> +#endif + + +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + +static int verbose; +static int error_count; + +static void +info (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +static void +show_sexp (const char *prefix, gcry_sexp_t a) +{ + char *buf; + size_t size; + + if (prefix) + fputs (prefix, stderr); + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + fprintf (stderr, "%.*s", (int)size, buf); + gcry_free (buf); +} + +static gcry_mpi_t +mpi_from_string (const char *string) +{ + gpg_error_t err; + gcry_mpi_t a; + + err = gcry_mpi_scan (&a, GCRYMPI_FMT_HEX, string, 0, NULL); + if (err) + die ("error converting string to mpi: %s\n", gpg_strerror (err)); + return a; +} + +/* Convert STRING consisting of hex characters into its binary + representation and return it as an allocated buffer. The valid + length of the buffer is returned at R_LENGTH. The string is + delimited by end of string. The function returns NULL on + error. */ +static void * +data_from_hex (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = gcry_xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + die ("error parsing hex string `%s'\n", string); + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + + +static void +extract_cmp_mpi (gcry_sexp_t sexp, const char *name, const char *expected) +{ + gcry_sexp_t l1; + gcry_mpi_t a, b; + + l1 = gcry_sexp_find_token (sexp, name, 0); + a = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + b = mpi_from_string (expected); + if (!a) + fail ("parameter \"%s\" missing in key\n", name); + else if ( gcry_mpi_cmp (a, b) ) + fail ("parameter \"%s\" does not match expected value\n", name); + gcry_mpi_release (b); + gcry_mpi_release (a); + gcry_sexp_release (l1); +} + + +static void +extract_cmp_data (gcry_sexp_t sexp, const char *name, const char *expected) +{ + gcry_sexp_t l1; + const void *a; + size_t alen; + void *b; + size_t blen; + + l1 = gcry_sexp_find_token (sexp, name, 0); + a = gcry_sexp_nth_data (l1, 1, &alen); + b = data_from_hex (expected, &blen); + if (!a) + fail ("parameter \"%s\" missing in key\n", name); + else if ( alen != blen || memcmp (a, b, alen) ) + fail ("parameter \"%s\" does not match expected value\n", name); + gcry_free (b); + gcry_sexp_release (l1); +} + +static void +extract_cmp_int (gcry_sexp_t sexp, const char *name, int expected) +{ + gcry_sexp_t l1; + char *a; + + l1 = gcry_sexp_find_token (sexp, name, 0); + a = gcry_sexp_nth_string (l1, 1); + if (!a) + fail ("parameter \"%s\" missing in key\n", name); + else if ( strtoul (a, NULL, 10) != expected ) + fail ("parameter \"%s\" does not match expected value\n", name); + gcry_free (a); + gcry_sexp_release (l1); +} + + +static void +check_dsa_gen_186_2 (void) +{ + static struct { + int nbits; + const char *p, *q, *g; + const char *seed; + int counter; + const char *h; + } tbl[] = { + /* These tests are from FIPS 186-2, B.3.1. */ + { + 1024, + "d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" + "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" + "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" + "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69", + "9c916d121de9a03f71fb21bc2e1c0d116f065a4f", + "8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" + "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" + "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" + "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44", + "0cb1990c1fd3626055d7a0096f8fa99807399871", + 98, + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000002" + }, + { + 1024, + "f5c73304080353357de1b5967597c27d65f70aa2fe9b6aed1d0afc2b499adf22f" + "8e37937096d88548ac36c4a067f8353c7fed73f96f0d688b19b0624aedbae5dbb" + "0ee8835a4c269288c0e1d69479e701ee266bb767af39d748fe7d6afc73fdf44be" + "3eb6e661e599670061203e75fc8b3dbd59e40b54f358d0097013a0f3867f9", + "f8751166cf4f6f3b07c081fd2a9071f23ca1988d", + "1e288a442e02461c418ed67a66d24cacbeb8936fbde62ff995f5fd569dee6be62" + "4e4f0f9f8c8093f5d192ab3b3f9ae3f2665d95d27fb10e382f45cd356e7f4eb7a" + "665db432113ed06478f93b7cf188ec7a1ee97aec8f91ea7bfceaf8b6e7e5a349c" + "4ad3225362ef440c57cbc6e69df15b6699caac85f733555075f04781b2b33", + "34b3520d45d240a8861b82c8b61ffa16e67b5cce", + 622, + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000002", + }, + { + 1024, + "c6c6f4f4eed927fb1c3b0c81010967e530658e6f9698ebe058b4f47b2dc8fcbc7" + "b69296b9e8b6cf55681181fe72492668061b262b0046a0d409902e269b0cb69a4" + "55ed1a086caf41927f5912bf0e0cbc45ee81a4f98bf6146f6168a228aec80e9cc" + "1162d6f6aa412efe82d4f18b95e34ab790daac5bd7aef0b22fa08ba5dbaad", + "d32b29f065c1394a30490b6fcbf812a32a8634ab", + "06f973c879e2e89345d0ac04f9c34ad69b9eff1680f18d1c8f3e1596c2e8fa8e1" + "ecef6830409e9012d4788bef6ec7414d09c981b47c941b77f39dfc49caff5e714" + "c97abe25a7a8b5d1fe88700bb96eff91cca64d53700a28b1146d81bad1212d231" + "80154c95a01f5aeebb553a8365c38a5ebe05539b51734233776ce9aff98b2", + "b6ec750da2f824cb42c5f7e28c81350d97f75125", + 185, + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000002", + }, + { + 1024, + "b827a9dc9221a6ed1bec7b64d61232aacb2812f888b0a0b3a95033d7a22e77d0b" + "ff23bfeed0fb1281b21b8ff7421f0c727d1fb8aa2b843d6885f067e763f83d41f" + "d800ab15a7e2b12f71ec2058ee7bd62cd72c26989b272e519785da57bfa1f974b" + "c652e1a2d6cfb68477de5635fd019b37add656cff0b802558b31b6d2851e5", + "de822c03445b77cec4ad3a6fb0ca39ff97059ddf", + "65a9e2d43a378d7063813104586868cacf2fccd51aec1e0b6af8ba3e66dee6371" + "681254c3fb5e3929d65e3c4bcd20abd4ddc7cf815623e17b9fc92f02b8d44278b" + "848480ffd193104cf5612639511e45bd247708ff6028bd3824f8844c263b46c69" + "1f2076f8cd13c5d0be95f1f2a1a17ab1f7e5bc73500bac27d57b473ba9748", + "cd2221dd73815a75224e9fde7faf52829b81ac7a", + 62, + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000002", + }, + { + 1024, + "898a8d93e295c8ef2ffd46976225a1543640640d155a576fafa0be32136165803" + "ba2eff2782a2be75cc9ec65db6bd3238cca695b3a5a14726a2a314775c377d891" + "354b3de6c89e714a05599ca04132c987f889f72c4fe298ccb31f711c03b07e1d9" + "8d72af590754cf3847398b60cecd55a4611692b308809560a83880404c227", + "c6d786643d2acfc6b8d576863fda8cfbfbd5e03f", + "2fd38b8d21c58e8fb5315a177b8d5dc4c450d574e69348b7b9da367c26e72438d" + "af8372e7f0bee84ef5dcbbc3727194a2228431192f1779be24837f22a0e14d10d" + "5344da1b8b403df9f9b2655095b3d0f67418ed6cd989f35aa4232e4b7001764fb" + "e85d6b2c716980f13272fc4271ac1e234f7e24c023cfc2d2dc0aa1e9af2fb", + "73483e697599871af983a281e3afa22e0ed86b68", + 272, + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "00000000000000000000000000000000000000000000000000000000000000000" + "0000000000000000000000000000000000000000000000000000000000002", + }, + + /* These tests are generated by the OpenSSL FIPS version. */ + { + 1024, + "A404363903FDCE86839BCFD953AAD2DA2B0E70CAED3B5FF5D68F15A1C4BB0A793C" + "A9D58FC956804C5901DE0AF99F345ED1A8617C687864BAC044B7C3C3E732A2B255" + "EC986AA76EA8CB0E0815B3E0E605650AF7D8058EE7E8EBCDEFFDAB8100D3FC1033" + "11BA3AB232EF06BB74BA9A949EC0C7ED324C19B202F4AB725BBB4080C9", + "C643946CEA8748E12D430C48DB038F9165814389", + "59B7E7BA0033CCE8E6837173420FBB382A784D4154A3C166043F5A68CB92945D16" + "892D4CC5585F2D28C780E75A6C20A379E2B58304C1E5FC0D8C15E4E89C4498C8BC" + "B90FB36ED8DC0489B9D0BC09EC4411FB0BFADF25485EEAB6700BE0ACF5C44A6ED7" + "44A015382FF9B8DA7EAA00DEA135FADC59212DBBFFC1537336FA4B7225", + "02708ab36e3f0bfd67ec3b8bd8829d03b84f56bd", + 50, + "02" + }, + { + 1024, + "9C664033DB8B203D826F896D2293C62EF9351D5CFD0F4C0AD7EFDA4DDC7F15987" + "6A3C68CAB2586B44FD1BD4DEF7A17905D88D321DD77C4E1720D848CA21D79F9B3" + "D8F537338E09B44E9F481E8DA3C56569F63146596A050EF8FAEE8ACA32C666450" + "04F675C8806EB4025B0A5ECC39CE89983EA40A183A7CF5208BA958045ABD5", + "AD0D8CBA369AF6CD0D2BAC0B4CFCAF0A1F9BCDF7", + "74D717F7092A2AF725FDD6C2561D1DBE5AEE40203C638BA8B9F49003857873701" + "95A44E515C4E8B344F5CDC7F4A6D38097CD57675E7643AB9700692C69F0A99B0E" + "039FDDDFCA8CEB607BDB4ADF2834DE1690F5823FC8199FB8F6F29E5A583B6786A" + "C14C7E67106C3B30568CBB9383F89287D578159778EB18216799D16D46498", + "6481a12a50384888ee84b61024f7c9c685d6ac96", + 289, + "02" + }, + { + 1024, + + "B0DFB602EB8462B1DC8C2214A52B587D3E6842CCF1C38D0F7C7F967ED30CF6828" + "1E2675B3BAB594755FB1634E66B4C23936F0725A358F8DFF3C307E2601FD66D63" + "5B17270450C50BD2BEC29E0E9A471DF1C15B0191517952268A2763D4BD28B8503" + "B3399686272B76B11227F693D7833105EF70C2289C3194CF4527024B272DF", + "EA649C04911FAB5A41440287A517EF752A40354B", + "88C5A4563ECB949763E0B696CD04B21321360F54C0EE7B23E2CEDC30E9E486162" + "01BFB1619E7C54B653D1F890C50E04B29205F5E3E2F93A13B0751AF25491C5194" + "93C09DDF6B9C173B3846DFB0E7A5C870BBFC78419260C90E20315410691C8326C" + "858D7063E7921F3F601158E912C7EE487FF259202BEEB10F6D9E99190F696", + "5bf9d17bc62fbbf3d569c92bd4505586b2e5ef1a", + 626, + "02" + }, + { + 1024, + "F783C08D7F9463E48BA87893805C4B34B63C85DF7EBDD9EBEE94DB4AF4E4A415C" + "F0F3793AE55096BA1199598798FA8403B28DED7F7C7AFD54FD535861A0150EF4D" + "5871465B13837CCF46BEB0A22F8D38DC7D6AE0E14A3845FD0C027CFA97791B977" + "CE2808BAD9B43CE69390C0F40016056722D82C0D7B1B27413D026A39D7DAD", + "A40D9EE456AED4C8A653FDB47B6629C0B843FE8F", + "DF876263E21F263AE6DA57409BD517DCEADB9216048F066D6B58867F8E59A5EEE" + "700283A946C1455534618979BE6C227673C1B803910262BD93BC94D5089850614" + "F3E29AB64E8C989A7E3E28FE670FFA3EE21DEEEC1AB0B60E1D8E2AA39663BADD7" + "2C9F957D7F3D4F17D9FDAD050EB373A6DEFD09F5DA752EAFE046836E14B67", + "8a9a57706f69f4f566252cdf6d5cbfdf2020150b", + 397, + "02" + }, + { + 1024, + "D40E4F6461E145859CCF60FD57962840BD75FFF12C22F76626F566842252AD068" + "29745F0147056354F6C016CF12762B0E331787925B8128CF5AF81F9B176A51934" + "96D792430FF83C7B79BD595BDA10787B34600787FA552EFE3662F37B99AAD3F3A" + "093732680A01345192A19BECCE6BF5D498E44ED6BED5B0BA72AAD49E8276B", + "D12F1BD0AA78B99247FD9F18EAFEE5C136686EA5", + "468EBD20C99449C1E440E6F8E452C6A6BC7551C555FE5E94996E20CFD4DA3B9CC" + "58499D6CC2374CCF9C392715A537DE10CFCA8A6A37AFBD187CF6B88D26881E5F5" + "7521D9D2C9BBA51E7B87B070BBE73F5C5FE31E752CAF88183516D8503BAAC1159" + "928EF50DEE52D96F396B93FB4138D786464C315401A853E57C9A0F9D25839", + "30b3599944a914a330a3f49d11ec88f555422aef", + 678, + "02" + } + }; + gpg_error_t err; + int tno; + gcry_sexp_t key_spec, key, pub_key, sec_key, seed_values; + gcry_sexp_t l1; + + for (tno = 0; tno < DIM (tbl); tno++) + { + if (verbose) + info ("generating FIPS 186-2 test key %d\n", tno); + + { + void *data; + size_t datalen; + + data = data_from_hex (tbl[tno].seed, &datalen); + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (dsa (nbits %d)(use-fips186-2)" + "(derive-parms(seed %b))))", + tbl[tno].nbits, (int)datalen, data); + gcry_free (data); + } + if (err) + die ("error creating S-expression %d: %s\n", tno, gpg_strerror (err)); + + err = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (err) + { + fail ("error generating key %d: %s\n", tno, gpg_strerror (err)); + continue; + } + + if (verbose > 1) + show_sexp ("generated key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + fail ("public part missing in key %d\n", tno); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + fail ("private part missing in key %d\n", tno); + + l1 = gcry_sexp_find_token (key, "misc-key-info", 0); + if (!l1) + fail ("misc_key_info part missing in key %d\n", tno); + seed_values = gcry_sexp_find_token (l1, "seed-values", 0); + if (!seed_values) + fail ("seed-values part missing in key %d\n", tno); + gcry_sexp_release (l1); + + extract_cmp_mpi (sec_key, "p", tbl[tno].p); + extract_cmp_mpi (sec_key, "q", tbl[tno].q); + extract_cmp_mpi (sec_key, "g", tbl[tno].g); + + extract_cmp_data (seed_values, "seed", tbl[tno].seed); + extract_cmp_int (seed_values, "counter", tbl[tno].counter); + extract_cmp_mpi (seed_values, "h", tbl[tno].h); + + gcry_sexp_release (seed_values); + gcry_sexp_release (sec_key); + gcry_sexp_release (pub_key); + gcry_sexp_release (key); + } +} + + + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + { + verbose = 2; + debug = 1; + } + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version ("1.4.4")) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + + + check_dsa_gen_186_2 (); + + + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c new file mode 100644 index 0000000000..f80e30c844 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/fipsdrv.c @@ -0,0 +1,2526 @@ +/* fipsdrv.c - A driver to help with FIPS CAVS tests. + Copyright (C) 2008 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + Libgcrypt is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + Libgcrypt is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <errno.h> +#include <ctype.h> +#ifdef HAVE_W32_SYSTEM +# include <fcntl.h> /* We need setmode(). */ +#else +# include <signal.h> +#endif +#include <assert.h> +#include <unistd.h> + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include <gcrypt.h> +# define PACKAGE_BUGREPORT "devnull@example.org" +# define PACKAGE_VERSION "[build on " __DATE__ " " __TIME__ "]" +#endif + + +#define PGM "fipsdrv" + +#define my_isascii(c) (!((c) & 0x80)) +#define digitp(p) (*(p) >= '0' && *(p) <= '9') +#define hexdigitp(a) (digitp (a) \ + || (*(a) >= 'A' && *(a) <= 'F') \ + || (*(a) >= 'a' && *(a) <= 'f')) +#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \ + *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10)) +#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1)) +#define DIM(v) (sizeof(v)/sizeof((v)[0])) +#define DIMof(type,member) DIM(((type *)0)->member) + + +#define PRIV_CTL_INIT_EXTRNG_TEST 58 +#define PRIV_CTL_RUN_EXTRNG_TEST 59 +#define PRIV_CTL_DEINIT_EXTRNG_TEST 60 +#define PRIV_CTL_DISABLE_WEAK_KEY 61 +#define PRIV_CTL_GET_INPUT_VECTOR 62 + + +/* Verbose mode flag. */ +static int verbose; + +/* Binary input flag. */ +static int binary_input; + +/* Binary output flag. */ +static int binary_output; + +/* Base64 output flag. */ +static int base64_output; + +/* We need to know whether we are in loop_mode. */ +static int loop_mode; + +/* If true some functions are modified to print the output in the CAVS + response file format. */ +static int standalone_mode; + + +/* ASN.1 classes. */ +enum +{ + UNIVERSAL = 0, + APPLICATION = 1, + ASNCONTEXT = 2, + PRIVATE = 3 +}; + + +/* ASN.1 tags. */ +enum +{ + TAG_NONE = 0, + TAG_BOOLEAN = 1, + TAG_INTEGER = 2, + TAG_BIT_STRING = 3, + TAG_OCTET_STRING = 4, + TAG_NULL = 5, + TAG_OBJECT_ID = 6, + TAG_OBJECT_DESCRIPTOR = 7, + TAG_EXTERNAL = 8, + TAG_REAL = 9, + TAG_ENUMERATED = 10, + TAG_EMBEDDED_PDV = 11, + TAG_UTF8_STRING = 12, + TAG_REALTIVE_OID = 13, + TAG_SEQUENCE = 16, + TAG_SET = 17, + TAG_NUMERIC_STRING = 18, + TAG_PRINTABLE_STRING = 19, + TAG_TELETEX_STRING = 20, + TAG_VIDEOTEX_STRING = 21, + TAG_IA5_STRING = 22, + TAG_UTC_TIME = 23, + TAG_GENERALIZED_TIME = 24, + TAG_GRAPHIC_STRING = 25, + TAG_VISIBLE_STRING = 26, + TAG_GENERAL_STRING = 27, + TAG_UNIVERSAL_STRING = 28, + TAG_CHARACTER_STRING = 29, + TAG_BMP_STRING = 30 +}; + +/* ASN.1 Parser object. */ +struct tag_info +{ + int class; /* Object class. */ + unsigned long tag; /* The tag of the object. */ + unsigned long length; /* Length of the values. */ + int nhdr; /* Length of the header (TL). */ + unsigned int ndef:1; /* The object has an indefinite length. */ + unsigned int cons:1; /* This is a constructed object. */ +}; + + + +/* Print a error message and exit the process with an error code. */ +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + fputs (PGM ": ", stderr); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static void +showhex (const char *prefix, const void *buffer, size_t length) +{ + const unsigned char *p = buffer; + + if (prefix) + fprintf (stderr, PGM ": %s: ", prefix); + while (length-- ) + fprintf (stderr, "%02X", *p++); + if (prefix) + putc ('\n', stderr); +} + +/* static void */ +/* show_sexp (const char *prefix, gcry_sexp_t a) */ +/* { */ +/* char *buf; */ +/* size_t size; */ + +/* if (prefix) */ +/* fputs (prefix, stderr); */ +/* size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); */ +/* buf = gcry_xmalloc (size); */ + +/* gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); */ +/* fprintf (stderr, "%.*s", (int)size, buf); */ +/* gcry_free (buf); */ +/* } */ + + +/* Convert STRING consisting of hex characters into its binary + representation and store that at BUFFER. BUFFER needs to be of + LENGTH bytes. The function checks that the STRING will convert + exactly to LENGTH bytes. The string is delimited by either end of + string or a white space character. The function returns -1 on + error or the length of the parsed string. */ +static int +hex2bin (const char *string, void *buffer, size_t length) +{ + int i; + const char *s = string; + + for (i=0; i < length; ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return -1; /* Invalid hex digits. */ + ((unsigned char*)buffer)[i++] = xtoi_2 (s); + s += 2; + } + if (*s && (!my_isascii (*s) || !isspace (*s)) ) + return -1; /* Not followed by Nul or white space. */ + if (i != length) + return -1; /* Not of expected length. */ + if (*s) + s++; /* Skip the delimiter. */ + return s - string; +} + + +/* Convert STRING consisting of hex characters into its binary + representation and return it as an allocated buffer. The valid + length of the buffer is returned at R_LENGTH. The string is + delimited by end of string. The function returns NULL on + error. */ +static void * +hex2buffer (const char *string, size_t *r_length) +{ + const char *s; + unsigned char *buffer; + size_t length; + + buffer = gcry_xmalloc (strlen(string)/2+1); + length = 0; + for (s=string; *s; s +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + return NULL; /* Invalid hex digits. */ + ((unsigned char*)buffer)[length++] = xtoi_2 (s); + } + *r_length = length; + return buffer; +} + + +static char * +read_textline (FILE *fp) +{ + char line[256]; + char *p; + int any = 0; + + /* Read line but skip over initial empty lines. */ + do + { + do + { + if (!fgets (line, sizeof line, fp)) + { + if (feof (fp)) + return NULL; + die ("error reading input line: %s\n", strerror (errno)); + } + p = strchr (line, '\n'); + if (p) + *p = 0; + p = line + (*line? (strlen (line)-1):0); + for ( ;p > line; p--) + if (my_isascii (*p) && isspace (*p)) + *p = 0; + } + while (!any && !*line); + any = 1; + } + while (*line == '#'); /* Always skip comment lines. */ + if (verbose > 1) + fprintf (stderr, PGM ": received line: %s\n", line); + return gcry_xstrdup (line); +} + +static char * +read_hexline (FILE *fp, size_t *retlen) +{ + char *line, *p; + + line = read_textline (fp); + if (!line) + return NULL; + p = hex2buffer (line, retlen); + if (!p) + die ("error decoding hex string on input\n"); + gcry_free (line); + return p; +} + +static void +skip_to_empty_line (FILE *fp) +{ + char line[256]; + char *p; + + do + { + if (!fgets (line, sizeof line, fp)) + { + if (feof (fp)) + return; + die ("error reading input line: %s\n", strerror (errno)); + } + p = strchr (line, '\n'); + if (p) + *p =0; + } + while (*line); +} + + + +/* Read a file from stream FP into a newly allocated buffer and return + that buffer. The valid length of the buffer is stored at R_LENGTH. + Returns NULL on failure. If decode is set, the file is assumed to + be hex encoded and the decoded content is returned. */ +static void * +read_file (FILE *fp, int decode, size_t *r_length) +{ + char *buffer; + size_t buflen; + size_t nread, bufsize = 0; + + *r_length = 0; +#define NCHUNK 8192 +#ifdef HAVE_DOSISH_SYSTEM + setmode (fileno(fp), O_BINARY); +#endif + buffer = NULL; + buflen = 0; + do + { + bufsize += NCHUNK; + if (!buffer) + buffer = gcry_xmalloc (bufsize); + else + buffer = gcry_xrealloc (buffer, bufsize); + + nread = fread (buffer + buflen, 1, NCHUNK, fp); + if (nread < NCHUNK && ferror (fp)) + { + gcry_free (buffer); + return NULL; + } + buflen += nread; + } + while (nread == NCHUNK); +#undef NCHUNK + if (decode) + { + const char *s; + char *p; + + for (s=buffer,p=buffer,nread=0; nread+1 < buflen; s += 2, nread +=2 ) + { + if (!hexdigitp (s) || !hexdigitp (s+1)) + { + gcry_free (buffer); + return NULL; /* Invalid hex digits. */ + } + *(unsigned char*)p++ = xtoi_2 (s); + } + if (nread != buflen) + { + gcry_free (buffer); + return NULL; /* Odd number of hex digits. */ + } + buflen = p - buffer; + } + + *r_length = buflen; + return buffer; +} + +/* Do in-place decoding of base-64 data of LENGTH in BUFFER. Returns + the new length of the buffer. Dies on error. */ +static size_t +base64_decode (char *buffer, size_t length) +{ + static unsigned char const asctobin[128] = + { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x3e, 0xff, 0xff, 0xff, 0x3f, + 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, + 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x10, 0x11, 0x12, + 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f, 0x20, 0x21, 0x22, 0x23, 0x24, + 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d, 0x2e, 0x2f, 0x30, + 0x31, 0x32, 0x33, 0xff, 0xff, 0xff, 0xff, 0xff + }; + + int idx = 0; + unsigned char val = 0; + int c = 0; + char *d, *s; + int lfseen = 1; + + /* Find BEGIN line. */ + for (s=buffer; length; length--, s++) + { + if (lfseen && *s == '-' && length > 11 && !memcmp (s, "-----BEGIN ", 11)) + { + for (; length && *s != '\n'; length--, s++) + ; + break; + } + lfseen = (*s == '\n'); + } + + /* Decode until pad character or END line. */ + for (d=buffer; length; length--, s++) + { + if (lfseen && *s == '-' && length > 9 && !memcmp (s, "-----END ", 9)) + break; + if ((lfseen = (*s == '\n')) || *s == ' ' || *s == '\r' || *s == '\t') + continue; + if (*s == '=') + { + /* Pad character: stop */ + if (idx == 1) + *d++ = val; + break; + } + + if ( (*s & 0x80) || (c = asctobin[*(unsigned char *)s]) == 0xff) + die ("invalid base64 character %02X at pos %d detected\n", + *(unsigned char*)s, (int)(s-buffer)); + + switch (idx) + { + case 0: + val = c << 2; + break; + case 1: + val |= (c>>4)&3; + *d++ = val; + val = (c<<4)&0xf0; + break; + case 2: + val |= (c>>2)&15; + *d++ = val; + val = (c<<6)&0xc0; + break; + case 3: + val |= c&0x3f; + *d++ = val; + break; + } + idx = (idx+1) % 4; + } + + return d - buffer; +} + + +/* Parse the buffer at the address BUFFER which consists of the number + of octets as stored at BUFLEN. Return the tag and the length part + from the TLV triplet. Update BUFFER and BUFLEN on success. Checks + that the encoded length does not exhaust the length of the provided + buffer. */ +static int +parse_tag (unsigned char const **buffer, size_t *buflen, struct tag_info *ti) +{ + int c; + unsigned long tag; + const unsigned char *buf = *buffer; + size_t length = *buflen; + + ti->length = 0; + ti->ndef = 0; + ti->nhdr = 0; + + /* Get the tag */ + if (!length) + return -1; /* Premature EOF. */ + c = *buf++; length--; + ti->nhdr++; + + ti->class = (c & 0xc0) >> 6; + ti->cons = !!(c & 0x20); + tag = (c & 0x1f); + + if (tag == 0x1f) + { + tag = 0; + do + { + tag <<= 7; + if (!length) + return -1; /* Premature EOF. */ + c = *buf++; length--; + ti->nhdr++; + tag |= (c & 0x7f); + } + while ( (c & 0x80) ); + } + ti->tag = tag; + + /* Get the length */ + if (!length) + return -1; /* Premature EOF. */ + c = *buf++; length--; + ti->nhdr++; + + if ( !(c & 0x80) ) + ti->length = c; + else if (c == 0x80) + ti->ndef = 1; + else if (c == 0xff) + return -1; /* Forbidden length value. */ + else + { + unsigned long len = 0; + int count = c & 0x7f; + + for (; count; count--) + { + len <<= 8; + if (!length) + return -1; /* Premature EOF. */ + c = *buf++; length--; + ti->nhdr++; + len |= (c & 0xff); + } + ti->length = len; + } + + if (ti->class == UNIVERSAL && !ti->tag) + ti->length = 0; + + if (ti->length > length) + return -1; /* Data larger than buffer. */ + + *buffer = buf; + *buflen = length; + return 0; +} + + +/* Read the file FNAME assuming it is a PEM encoded private key file + and return an S-expression. With SHOW set, the key parameters are + printed. */ +static gcry_sexp_t +read_private_key_file (const char *fname, int show) +{ + gcry_error_t err; + FILE *fp; + char *buffer; + size_t buflen; + const unsigned char *der; + size_t derlen; + struct tag_info ti; + gcry_mpi_t keyparms[8]; + int n_keyparms = 8; + int idx; + gcry_sexp_t s_key; + + fp = fopen (fname, binary_input?"rb":"r"); + if (!fp) + die ("can't open `%s': %s\n", fname, strerror (errno)); + buffer = read_file (fp, 0, &buflen); + if (!buffer) + die ("error reading `%s'\n", fname); + fclose (fp); + + buflen = base64_decode (buffer, buflen); + + /* Parse the ASN.1 structure. */ + der = (const unsigned char*)buffer; + derlen = buflen; + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) + goto bad_asn1; + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) + goto bad_asn1; + if (ti.length != 1 || *der) + goto bad_asn1; /* The value of the first integer is no 0. */ + der += ti.length; derlen -= ti.length; + + for (idx=0; idx < n_keyparms; idx++) + { + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) + goto bad_asn1; + if (show) + { + char prefix[2]; + + prefix[0] = idx < 8? "nedpq12u"[idx] : '?'; + prefix[1] = 0; + showhex (prefix, der, ti.length); + } + err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); + if (err) + die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); + der += ti.length; derlen -= ti.length; + } + if (idx != n_keyparms) + die ("not enough RSA key parameters\n"); + + gcry_free (buffer); + + /* Convert from OpenSSL parameter ordering to the OpenPGP order. */ + /* First check that p < q; if not swap p and q and recompute u. */ + if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) + { + gcry_mpi_swap (keyparms[3], keyparms[4]); + gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); + } + + /* Build the S-expression. */ + err = gcry_sexp_build (&s_key, NULL, + "(private-key(rsa(n%m)(e%m)" + /**/ "(d%m)(p%m)(q%m)(u%m)))", + keyparms[0], keyparms[1], keyparms[2], + keyparms[3], keyparms[4], keyparms[7] ); + if (err) + die ("error building S-expression: %s\n", gpg_strerror (err)); + + for (idx=0; idx < n_keyparms; idx++) + gcry_mpi_release (keyparms[idx]); + + return s_key; + + bad_asn1: + die ("invalid ASN.1 structure in `%s'\n", fname); + return NULL; /*NOTREACHED*/ +} + + +/* Read the file FNAME assuming it is a PEM encoded public key file + and return an S-expression. With SHOW set, the key parameters are + printed. */ +static gcry_sexp_t +read_public_key_file (const char *fname, int show) +{ + gcry_error_t err; + FILE *fp; + char *buffer; + size_t buflen; + const unsigned char *der; + size_t derlen; + struct tag_info ti; + gcry_mpi_t keyparms[2]; + int n_keyparms = 2; + int idx; + gcry_sexp_t s_key; + + fp = fopen (fname, binary_input?"rb":"r"); + if (!fp) + die ("can't open `%s': %s\n", fname, strerror (errno)); + buffer = read_file (fp, 0, &buflen); + if (!buffer) + die ("error reading `%s'\n", fname); + fclose (fp); + + buflen = base64_decode (buffer, buflen); + + /* Parse the ASN.1 structure. */ + der = (const unsigned char*)buffer; + derlen = buflen; + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) + goto bad_asn1; + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) + goto bad_asn1; + /* We skip the description of the key parameters and assume it is RSA. */ + der += ti.length; derlen -= ti.length; + + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_BIT_STRING || ti.class || ti.cons || ti.ndef) + goto bad_asn1; + if (ti.length < 1 || *der) + goto bad_asn1; /* The number of unused bits needs to be 0. */ + der += 1; derlen -= 1; + + /* Parse the BIT string. */ + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_SEQUENCE || ti.class || !ti.cons || ti.ndef) + goto bad_asn1; + + for (idx=0; idx < n_keyparms; idx++) + { + if ( parse_tag (&der, &derlen, &ti) + || ti.tag != TAG_INTEGER || ti.class || ti.cons || ti.ndef) + goto bad_asn1; + if (show) + { + char prefix[2]; + + prefix[0] = idx < 2? "ne"[idx] : '?'; + prefix[1] = 0; + showhex (prefix, der, ti.length); + } + err = gcry_mpi_scan (keyparms+idx, GCRYMPI_FMT_USG, der, ti.length,NULL); + if (err) + die ("error scanning RSA parameter %d: %s\n", idx, gpg_strerror (err)); + der += ti.length; derlen -= ti.length; + } + if (idx != n_keyparms) + die ("not enough RSA key parameters\n"); + + gcry_free (buffer); + + /* Build the S-expression. */ + err = gcry_sexp_build (&s_key, NULL, + "(public-key(rsa(n%m)(e%m)))", + keyparms[0], keyparms[1] ); + if (err) + die ("error building S-expression: %s\n", gpg_strerror (err)); + + for (idx=0; idx < n_keyparms; idx++) + gcry_mpi_release (keyparms[idx]); + + return s_key; + + bad_asn1: + die ("invalid ASN.1 structure in `%s'\n", fname); + return NULL; /*NOTREACHED*/ +} + + + +/* Read the file FNAME assuming it is a binary signature result and + return an an S-expression suitable for gcry_pk_verify. */ +static gcry_sexp_t +read_sig_file (const char *fname) +{ + gcry_error_t err; + FILE *fp; + char *buffer; + size_t buflen; + gcry_mpi_t tmpmpi; + gcry_sexp_t s_sig; + + fp = fopen (fname, "rb"); + if (!fp) + die ("can't open `%s': %s\n", fname, strerror (errno)); + buffer = read_file (fp, 0, &buflen); + if (!buffer) + die ("error reading `%s'\n", fname); + fclose (fp); + + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, buffer, buflen, NULL); + if (!err) + err = gcry_sexp_build (&s_sig, NULL, + "(sig-val(rsa(s %m)))", tmpmpi); + if (err) + die ("error building S-expression: %s\n", gpg_strerror (err)); + gcry_mpi_release (tmpmpi); + gcry_free (buffer); + + return s_sig; +} + + +/* Read an S-expression from FNAME. */ +static gcry_sexp_t +read_sexp_from_file (const char *fname) +{ + gcry_error_t err; + FILE *fp; + char *buffer; + size_t buflen; + gcry_sexp_t sexp; + + fp = fopen (fname, "rb"); + if (!fp) + die ("can't open `%s': %s\n", fname, strerror (errno)); + buffer = read_file (fp, 0, &buflen); + if (!buffer) + die ("error reading `%s'\n", fname); + fclose (fp); + if (!buflen) + die ("error: file `%s' is empty\n", fname); + + err = gcry_sexp_create (&sexp, buffer, buflen, 1, gcry_free); + if (err) + die ("error parsing `%s': %s\n", fname, gpg_strerror (err)); + + return sexp; +} + + +static void +print_buffer (const void *buffer, size_t length) +{ + int writerr = 0; + + if (base64_output) + { + static const unsigned char bintoasc[64+1] = + ("ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "abcdefghijklmnopqrstuvwxyz" + "0123456789+/"); + const unsigned char *p; + unsigned char inbuf[4]; + char outbuf[4]; + int idx, quads; + + idx = quads = 0; + for (p = buffer; length; p++, length--) + { + inbuf[idx++] = *p; + if (idx > 2) + { + outbuf[0] = bintoasc[(*inbuf>>2)&077]; + outbuf[1] = bintoasc[(((*inbuf<<4)&060) + |((inbuf[1] >> 4)&017))&077]; + outbuf[2] = bintoasc[(((inbuf[1]<<2)&074) + |((inbuf[2]>>6)&03))&077]; + outbuf[3] = bintoasc[inbuf[2]&077]; + if (fwrite (outbuf, 4, 1, stdout) != 1) + writerr = 1; + idx = 0; + if (++quads >= (64/4)) + { + if (fwrite ("\n", 1, 1, stdout) != 1) + writerr = 1; + quads = 0; + } + } + } + if (idx) + { + outbuf[0] = bintoasc[(*inbuf>>2)&077]; + if (idx == 1) + { + outbuf[1] = bintoasc[((*inbuf<<4)&060)&077]; + outbuf[2] = outbuf[3] = '='; + } + else + { + outbuf[1] = bintoasc[(((*inbuf<<4)&060) + |((inbuf[1]>>4)&017))&077]; + outbuf[2] = bintoasc[((inbuf[1]<<2)&074)&077]; + outbuf[3] = '='; + } + if (fwrite (outbuf, 4, 1, stdout) != 1) + writerr = 1; + quads++; + } + if (quads && fwrite ("\n", 1, 1, stdout) != 1) + writerr = 1; + } + else if (binary_output) + { + if (fwrite (buffer, length, 1, stdout) != 1) + writerr++; + } + else + { + const unsigned char *p = buffer; + + if (verbose > 1) + showhex ("sent line", buffer, length); + while (length-- && !ferror (stdout) ) + printf ("%02X", *p++); + if (ferror (stdout)) + writerr++; + } + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + { +#ifndef HAVE_W32_SYSTEM + if (loop_mode && errno == EPIPE) + loop_mode = 0; + else +#endif + die ("writing output failed: %s\n", strerror (errno)); + } +} + + +/* Print an MPI on a line. */ +static void +print_mpi_line (gcry_mpi_t a, int no_lz) +{ + unsigned char *buf, *p; + gcry_error_t err; + int writerr = 0; + + err = gcry_mpi_aprint (GCRYMPI_FMT_HEX, &buf, NULL, a); + if (err) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + + p = buf; + if (no_lz && p[0] == '0' && p[1] == '0' && p[2]) + p += 2; + + printf ("%s\n", p); + if (ferror (stdout)) + writerr++; + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + die ("writing output failed: %s\n", strerror (errno)); + gcry_free (buf); +} + + +/* Print some data on hex format on a line. */ +static void +print_data_line (const void *data, size_t datalen) +{ + const unsigned char *p = data; + int writerr = 0; + + while (data && datalen-- && !ferror (stdout) ) + printf ("%02X", *p++); + putchar ('\n'); + if (ferror (stdout)) + writerr++; + if (!writerr && fflush (stdout) == EOF) + writerr++; + if (writerr) + die ("writing output failed: %s\n", strerror (errno)); +} + +/* Print the S-expression A to the stream FP. */ +static void +print_sexp (gcry_sexp_t a, FILE *fp) +{ + char *buf; + size_t size; + + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + if (fwrite (buf, size, 1, fp) != 1) + die ("error writing to stream: %s\n", strerror (errno)); + gcry_free (buf); +} + + + + +static gcry_error_t +init_external_rng_test (void **r_context, + unsigned int flags, + const void *key, size_t keylen, + const void *seed, size_t seedlen, + const void *dt, size_t dtlen) +{ + return gcry_control (PRIV_CTL_INIT_EXTRNG_TEST, + r_context, flags, + key, keylen, + seed, seedlen, + dt, dtlen); +} + +static gcry_error_t +run_external_rng_test (void *context, void *buffer, size_t buflen) +{ + return gcry_control (PRIV_CTL_RUN_EXTRNG_TEST, context, buffer, buflen); +} + +static void +deinit_external_rng_test (void *context) +{ + gcry_control (PRIV_CTL_DEINIT_EXTRNG_TEST, context); +} + + +/* Given an OpenSSL cipher name NAME, return the Libgcrypt algirithm + identified and store the libgcrypt mode at R_MODE. Returns 0 on + error. */ +static int +map_openssl_cipher_name (const char *name, int *r_mode) +{ + static struct { + const char *name; + int algo; + int mode; + } table[] = + { + { "bf-cbc", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, + { "bf", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CBC }, + { "bf-cfb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_CFB }, + { "bf-ecb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_ECB }, + { "bf-ofb", GCRY_CIPHER_BLOWFISH, GCRY_CIPHER_MODE_OFB }, + + { "cast-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, + { "cast", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, + { "cast5-cbc", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CBC }, + { "cast5-cfb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_CFB }, + { "cast5-ecb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_ECB }, + { "cast5-ofb", GCRY_CIPHER_CAST5, GCRY_CIPHER_MODE_OFB }, + + { "des-cbc", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, + { "des", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CBC }, + { "des-cfb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_CFB }, + { "des-ofb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_OFB }, + { "des-ecb", GCRY_CIPHER_DES, GCRY_CIPHER_MODE_ECB }, + + { "des-ede3-cbc", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, + { "des-ede3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_ECB }, + { "des3", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CBC }, + { "des-ede3-cfb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_CFB }, + { "des-ede3-ofb", GCRY_CIPHER_3DES, GCRY_CIPHER_MODE_OFB }, + + { "rc4", GCRY_CIPHER_ARCFOUR, GCRY_CIPHER_MODE_STREAM }, + + { "aes-128-cbc", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, + { "aes-128", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CBC }, + { "aes-128-cfb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_CFB }, + { "aes-128-ecb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_ECB }, + { "aes-128-ofb", GCRY_CIPHER_AES128, GCRY_CIPHER_MODE_OFB }, + + { "aes-192-cbc", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, + { "aes-192", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CBC }, + { "aes-192-cfb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_CFB }, + { "aes-192-ecb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_ECB }, + { "aes-192-ofb", GCRY_CIPHER_AES192, GCRY_CIPHER_MODE_OFB }, + + { "aes-256-cbc", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, + { "aes-256", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CBC }, + { "aes-256-cfb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_CFB }, + { "aes-256-ecb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_ECB }, + { "aes-256-ofb", GCRY_CIPHER_AES256, GCRY_CIPHER_MODE_OFB }, + + { NULL, 0 , 0 } + }; + int idx; + + for (idx=0; table[idx].name; idx++) + if (!strcmp (name, table[idx].name)) + { + *r_mode = table[idx].mode; + return table[idx].algo; + } + *r_mode = 0; + return 0; +} + + + +/* Run an encrypt or decryption operations. If DATA is NULL the + function reads its input in chunks of size DATALEN from fp and + processes it and writes it out until EOF. */ +static void +run_encrypt_decrypt (int encrypt_mode, + int cipher_algo, int cipher_mode, + const void *iv_buffer, size_t iv_buflen, + const void *key_buffer, size_t key_buflen, + const void *data, size_t datalen, FILE *fp) +{ + gpg_error_t err; + gcry_cipher_hd_t hd; + void *outbuf; + size_t outbuflen; + void *inbuf; + size_t inbuflen; + size_t blocklen; + + err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); + if (err) + die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", + cipher_algo, cipher_mode, gpg_strerror (err)); + + blocklen = gcry_cipher_get_algo_blklen (cipher_algo); + assert (blocklen); + + gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); + + err = gcry_cipher_setkey (hd, key_buffer, key_buflen); + if (err) + die ("gcry_cipher_setkey failed with keylen %u: %s\n", + (unsigned int)key_buflen, gpg_strerror (err)); + + if (iv_buffer) + { + err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); + if (err) + die ("gcry_cipher_setiv failed with ivlen %u: %s\n", + (unsigned int)iv_buflen, gpg_strerror (err)); + } + + inbuf = data? NULL : gcry_xmalloc (datalen); + outbuflen = datalen; + outbuf = gcry_xmalloc (outbuflen < blocklen? blocklen:outbuflen); + + do + { + if (inbuf) + { + int nread = fread (inbuf, 1, datalen, fp); + if (nread < (int)datalen && ferror (fp)) + die ("error reading input\n"); + data = inbuf; + inbuflen = nread; + } + else + inbuflen = datalen; + + if (encrypt_mode) + err = gcry_cipher_encrypt (hd, outbuf, outbuflen, data, inbuflen); + else + err = gcry_cipher_decrypt (hd, outbuf, outbuflen, data, inbuflen); + if (err) + die ("gcry_cipher_%scrypt failed: %s\n", + encrypt_mode? "en":"de", gpg_strerror (err)); + + print_buffer (outbuf, outbuflen); + } + while (inbuf); + + gcry_cipher_close (hd); + gcry_free (outbuf); + gcry_free (inbuf); +} + + +static void +get_current_iv (gcry_cipher_hd_t hd, void *buffer, size_t buflen) +{ + unsigned char tmp[17]; + + if (gcry_cipher_ctl (hd, PRIV_CTL_GET_INPUT_VECTOR, tmp, sizeof tmp)) + die ("error getting current input vector\n"); + if (buflen > *tmp) + die ("buffer too short to store the current input vector\n"); + memcpy (buffer, tmp+1, *tmp); +} + +/* Run the inner loop of the CAVS monte carlo test. */ +static void +run_cipher_mct_loop (int encrypt_mode, int cipher_algo, int cipher_mode, + const void *iv_buffer, size_t iv_buflen, + const void *key_buffer, size_t key_buflen, + const void *data, size_t datalen, int iterations) +{ + gpg_error_t err; + gcry_cipher_hd_t hd; + size_t blocklen; + int count; + char input[16]; + char output[16]; + char last_output[16]; + char last_last_output[16]; + char last_iv[16]; + + + err = gcry_cipher_open (&hd, cipher_algo, cipher_mode, 0); + if (err) + die ("gcry_cipher_open failed for algo %d, mode %d: %s\n", + cipher_algo, cipher_mode, gpg_strerror (err)); + + blocklen = gcry_cipher_get_algo_blklen (cipher_algo); + if (!blocklen || blocklen > sizeof output) + die ("invalid block length %d\n", blocklen); + + + gcry_cipher_ctl (hd, PRIV_CTL_DISABLE_WEAK_KEY, NULL, 0); + + err = gcry_cipher_setkey (hd, key_buffer, key_buflen); + if (err) + die ("gcry_cipher_setkey failed with keylen %u: %s\n", + (unsigned int)key_buflen, gpg_strerror (err)); + + if (iv_buffer) + { + err = gcry_cipher_setiv (hd, iv_buffer, iv_buflen); + if (err) + die ("gcry_cipher_setiv failed with ivlen %u: %s\n", + (unsigned int)iv_buflen, gpg_strerror (err)); + } + + if (datalen != blocklen) + die ("length of input (%u) does not match block length (%u)\n", + (unsigned int)datalen, (unsigned int)blocklen); + memcpy (input, data, datalen); + memset (output, 0, sizeof output); + for (count=0; count < iterations; count++) + { + memcpy (last_last_output, last_output, sizeof last_output); + memcpy (last_output, output, sizeof output); + + get_current_iv (hd, last_iv, blocklen); + + if (encrypt_mode) + err = gcry_cipher_encrypt (hd, output, blocklen, input, blocklen); + else + err = gcry_cipher_decrypt (hd, output, blocklen, input, blocklen); + if (err) + die ("gcry_cipher_%scrypt failed: %s\n", + encrypt_mode? "en":"de", gpg_strerror (err)); + + + if (encrypt_mode && (cipher_mode == GCRY_CIPHER_MODE_CFB + || cipher_mode == GCRY_CIPHER_MODE_CBC)) + memcpy (input, last_iv, blocklen); + else if (cipher_mode == GCRY_CIPHER_MODE_OFB) + memcpy (input, last_iv, blocklen); + else if (!encrypt_mode && cipher_mode == GCRY_CIPHER_MODE_CFB) + { + /* Reconstruct the output vector. */ + int i; + for (i=0; i < blocklen; i++) + input[i] ^= output[i]; + } + else + memcpy (input, output, blocklen); + } + + print_buffer (output, blocklen); + putchar ('\n'); + print_buffer (last_output, blocklen); + putchar ('\n'); + print_buffer (last_last_output, blocklen); + putchar ('\n'); + get_current_iv (hd, last_iv, blocklen); + print_buffer (last_iv, blocklen); /* Last output vector. */ + putchar ('\n'); + print_buffer (input, blocklen); /* Next input text. */ + putchar ('\n'); + if (verbose > 1) + showhex ("sent line", "", 0); + putchar ('\n'); + fflush (stdout); + + gcry_cipher_close (hd); +} + + + +/* Run a digest operation. */ +static void +run_digest (int digest_algo, const void *data, size_t datalen) +{ + gpg_error_t err; + gcry_md_hd_t hd; + const unsigned char *digest; + unsigned int digestlen; + + err = gcry_md_open (&hd, digest_algo, 0); + if (err) + die ("gcry_md_open failed for algo %d: %s\n", + digest_algo, gpg_strerror (err)); + + gcry_md_write (hd, data, datalen); + digest = gcry_md_read (hd, digest_algo); + digestlen = gcry_md_get_algo_dlen (digest_algo); + print_buffer (digest, digestlen); + gcry_md_close (hd); +} + + +/* Run a HMAC operation. */ +static void +run_hmac (int digest_algo, const void *key, size_t keylen, + const void *data, size_t datalen) +{ + gpg_error_t err; + gcry_md_hd_t hd; + const unsigned char *digest; + unsigned int digestlen; + + err = gcry_md_open (&hd, digest_algo, GCRY_MD_FLAG_HMAC); + if (err) + die ("gcry_md_open failed for HMAC algo %d: %s\n", + digest_algo, gpg_strerror (err)); + + gcry_md_setkey (hd, key, keylen); + if (err) + die ("gcry_md_setkey failed for HMAC algo %d: %s\n", + digest_algo, gpg_strerror (err)); + + gcry_md_write (hd, data, datalen); + digest = gcry_md_read (hd, digest_algo); + digestlen = gcry_md_get_algo_dlen (digest_algo); + print_buffer (digest, digestlen); + gcry_md_close (hd); +} + + + +/* Derive an RSA key using the S-expression in (DATA,DATALEN). This + S-expression is used directly as input to gcry_pk_genkey. The + result is printed to stdout with one parameter per line in hex + format and in this order: p, q, n, d. */ +static void +run_rsa_derive (const void *data, size_t datalen) +{ + gpg_error_t err; + gcry_sexp_t s_keyspec, s_key, s_top, l1; + gcry_mpi_t mpi; + const char *parmlist; + int idx; + + if (!datalen) + err = gpg_error (GPG_ERR_NO_DATA); + else + err = gcry_sexp_new (&s_keyspec, data, datalen, 1); + if (err) + die ("gcry_sexp_new failed for RSA key derive: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&s_key, s_keyspec); + if (err) + die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (s_keyspec); + + /* P and Q might have been swapped but we need to to return them in + the proper order. Build the parameter list accordingly. */ + parmlist = "pqnd"; + s_top = gcry_sexp_find_token (s_key, "misc-key-info", 0); + if (s_top) + { + l1 = gcry_sexp_find_token (s_top, "p-q-swapped", 0); + if (l1) + parmlist = "qpnd"; + gcry_sexp_release (l1); + gcry_sexp_release (s_top); + } + + /* Parse and print the parameters. */ + l1 = gcry_sexp_find_token (s_key, "private-key", 0); + s_top = gcry_sexp_find_token (l1, "rsa", 0); + gcry_sexp_release (l1); + if (!s_top) + die ("private-key part not found in result\n"); + + for (idx=0; parmlist[idx]; idx++) + { + l1 = gcry_sexp_find_token (s_top, parmlist+idx, 1); + mpi = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l1); + if (!mpi) + die ("parameter %c missing in private-key\n", parmlist[idx]); + print_mpi_line (mpi, 1); + gcry_mpi_release (mpi); + } + + gcry_sexp_release (s_top); + gcry_sexp_release (s_key); +} + + + +static size_t +compute_tag_length (size_t n) +{ + int needed = 0; + + if (n < 128) + needed += 2; /* Tag and one length byte. */ + else if (n < 256) + needed += 3; /* Tag, number of length bytes, 1 length byte. */ + else if (n < 65536) + needed += 4; /* Tag, number of length bytes, 2 length bytes. */ + else + die ("DER object too long to encode\n"); + + return needed; +} + +static unsigned char * +store_tag_length (unsigned char *p, int tag, size_t n) +{ + if (tag == TAG_SEQUENCE) + tag |= 0x20; /* constructed */ + + *p++ = tag; + if (n < 128) + *p++ = n; + else if (n < 256) + { + *p++ = 0x81; + *p++ = n; + } + else if (n < 65536) + { + *p++ = 0x82; + *p++ = n >> 8; + *p++ = n; + } + + return p; +} + + +/* Generate an RSA key of size KEYSIZE using the public exponent + PUBEXP and print it to stdout in the OpenSSL format. The format + is: + + SEQUENCE { + INTEGER (0) -- Unknown constant. + INTEGER -- n + INTEGER -- e + INTEGER -- d + INTEGER -- p + INTEGER -- q (with p < q) + INTEGER -- dmp1 = d mod (p-1) + INTEGER -- dmq1 = d mod (q-1) + INTEGER -- u = p^{-1} mod q + } + +*/ +static void +run_rsa_gen (int keysize, int pubexp) +{ + gpg_error_t err; + gcry_sexp_t keyspec, key, l1; + const char keyelems[] = "nedpq..u"; + gcry_mpi_t keyparms[8]; + size_t keyparmslen[8]; + int idx; + size_t derlen, needed, n; + unsigned char *derbuf, *der; + + err = gcry_sexp_build (&keyspec, NULL, + "(genkey (rsa (nbits %d)(rsa-use-e %d)))", + keysize, pubexp); + if (err) + die ("gcry_sexp_build failed for RSA key generation: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for RSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + + l1 = gcry_sexp_find_token (key, "private-key", 0); + if (!l1) + die ("private key not found in genkey result\n"); + gcry_sexp_release (key); + key = l1; + + l1 = gcry_sexp_find_token (key, "rsa", 0); + if (!l1) + die ("returned private key not formed as expected\n"); + gcry_sexp_release (key); + key = l1; + + /* Extract the parameters from the S-expression and store them in a + well defined order in KEYPARMS. */ + for (idx=0; idx < DIM(keyparms); idx++) + { + if (keyelems[idx] == '.') + { + keyparms[idx] = gcry_mpi_new (0); + continue; + } + l1 = gcry_sexp_find_token (key, keyelems+idx, 1); + if (!l1) + die ("no %c parameter in returned private key\n", keyelems[idx]); + keyparms[idx] = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG); + if (!keyparms[idx]) + die ("no value for %c parameter in returned private key\n", + keyelems[idx]); + gcry_sexp_release (l1); + } + + gcry_sexp_release (key); + + /* Check that p < q; if not swap p and q and recompute u. */ + if (gcry_mpi_cmp (keyparms[3], keyparms[4]) > 0) + { + gcry_mpi_swap (keyparms[3], keyparms[4]); + gcry_mpi_invm (keyparms[7], keyparms[3], keyparms[4]); + } + + /* Compute the additional parameters. */ + gcry_mpi_sub_ui (keyparms[5], keyparms[3], 1); + gcry_mpi_mod (keyparms[5], keyparms[2], keyparms[5]); + gcry_mpi_sub_ui (keyparms[6], keyparms[4], 1); + gcry_mpi_mod (keyparms[6], keyparms[2], keyparms[6]); + + /* Compute the length of the DER encoding. */ + needed = compute_tag_length (1) + 1; + for (idx=0; idx < DIM(keyparms); idx++) + { + err = gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &n, keyparms[idx]); + if (err) + die ("error formatting parameter: %s\n", gpg_strerror (err)); + keyparmslen[idx] = n; + needed += compute_tag_length (n) + n; + } + + /* Store the key parameters. */ + derlen = compute_tag_length (needed) + needed; + der = derbuf = gcry_xmalloc (derlen); + + der = store_tag_length (der, TAG_SEQUENCE, needed); + der = store_tag_length (der, TAG_INTEGER, 1); + *der++ = 0; + for (idx=0; idx < DIM(keyparms); idx++) + { + der = store_tag_length (der, TAG_INTEGER, keyparmslen[idx]); + err = gcry_mpi_print (GCRYMPI_FMT_STD, der, + keyparmslen[idx], NULL, keyparms[idx]); + if (err) + die ("error formatting parameter: %s\n", gpg_strerror (err)); + der += keyparmslen[idx]; + } + + /* Print the stuff. */ + for (idx=0; idx < DIM(keyparms); idx++) + gcry_mpi_release (keyparms[idx]); + + assert (der - derbuf == derlen); + + if (base64_output) + puts ("-----BEGIN RSA PRIVATE KEY-----"); + print_buffer (derbuf, derlen); + if (base64_output) + puts ("-----END RSA PRIVATE KEY-----"); + + gcry_free (derbuf); +} + + + +/* Sign DATA of length DATALEN using the key taken from the PEM + encoded KEYFILE and the hash algorithm HASHALGO. */ +static void +run_rsa_sign (const void *data, size_t datalen, + int hashalgo, int pkcs1, const char *keyfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp; + gcry_mpi_t sig_mpi = NULL; + unsigned char *outbuf; + size_t outlen; + +/* showhex ("D", data, datalen); */ + if (pkcs1) + { + unsigned char hash[64]; + unsigned int hashsize; + + hashsize = gcry_md_get_algo_dlen (hashalgo); + if (!hashsize || hashsize > sizeof hash) + die ("digest too long for buffer or unknown hash algorithm\n"); + gcry_md_hash_buffer (hashalgo, hash, data, datalen); + err = gcry_sexp_build (&s_data, NULL, + "(data (flags pkcs1)(hash %s %b))", + gcry_md_algo_name (hashalgo), + (int)hashsize, hash); + } + else + { + gcry_mpi_t tmp; + + err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmp); + gcry_mpi_release (tmp); + } + } + if (err) + die ("gcry_sexp_build failed for RSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_private_key_file (keyfile, 0); + + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { + gcry_sexp_release (read_private_key_file (keyfile, 1)); + die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", + (int)datalen, keyfile, gpg_strerror (err)); + } + gcry_sexp_release (s_key); + gcry_sexp_release (s_data); + + s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); + if (s_tmp) + { + gcry_sexp_release (s_sig); + s_sig = s_tmp; + s_tmp = gcry_sexp_find_token (s_sig, "rsa", 0); + if (s_tmp) + { + gcry_sexp_release (s_sig); + s_sig = s_tmp; + s_tmp = gcry_sexp_find_token (s_sig, "s", 0); + if (s_tmp) + { + gcry_sexp_release (s_sig); + s_sig = s_tmp; + sig_mpi = gcry_sexp_nth_mpi (s_sig, 1, GCRYMPI_FMT_USG); + } + } + } + gcry_sexp_release (s_sig); + + if (!sig_mpi) + die ("no value in returned S-expression\n"); + err = gcry_mpi_aprint (GCRYMPI_FMT_STD, &outbuf, &outlen, sig_mpi); + if (err) + die ("gcry_mpi_aprint failed: %s\n", gpg_strerror (err)); + gcry_mpi_release (sig_mpi); + + print_buffer (outbuf, outlen); + gcry_free (outbuf); +} + + + +/* Verify DATA of length DATALEN using the public key taken from the + PEM encoded KEYFILE and the hash algorithm HASHALGO against the + binary signature in SIGFILE. */ +static void +run_rsa_verify (const void *data, size_t datalen, int hashalgo, int pkcs1, + const char *keyfile, const char *sigfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; + + if (pkcs1) + { + unsigned char hash[64]; + unsigned int hashsize; + + hashsize = gcry_md_get_algo_dlen (hashalgo); + if (!hashsize || hashsize > sizeof hash) + die ("digest too long for buffer or unknown hash algorithm\n"); + gcry_md_hash_buffer (hashalgo, hash, data, datalen); + err = gcry_sexp_build (&s_data, NULL, + "(data (flags pkcs1)(hash %s %b))", + gcry_md_algo_name (hashalgo), + (int)hashsize, hash); + } + else + { + gcry_mpi_t tmp; + + err = gcry_mpi_scan (&tmp, GCRYMPI_FMT_USG, data, datalen,NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmp); + gcry_mpi_release (tmp); + } + } + if (err) + die ("gcry_sexp_build failed for RSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_public_key_file (keyfile, 0); + + s_sig = read_sig_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); + if (!err) + puts ("GOOD signature"); + else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) + puts ("BAD signature"); + else + printf ("ERROR (%s)\n", gpg_strerror (err)); + + gcry_sexp_release (s_sig); + gcry_sexp_release (s_key); + gcry_sexp_release (s_data); +} + + + +/* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ +static gcry_sexp_t +dsa_gen (int keysize) +{ + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, + "(genkey (dsa (nbits %d)(use-fips186-2)))", + keysize); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + + return key; +} + + +/* Generate a DSA key of size KEYSIZE and return the complete + S-expression. */ +static gcry_sexp_t +dsa_gen_with_seed (int keysize, const void *seed, size_t seedlen) +{ + gpg_error_t err; + gcry_sexp_t keyspec, key; + + err = gcry_sexp_build (&keyspec, NULL, + "(genkey" + " (dsa" + " (nbits %d)" + " (use-fips186-2)" + " (derive-parms" + " (seed %b))))", + keysize, (int)seedlen, seed); + if (err) + die ("gcry_sexp_build failed for DSA key generation: %s\n", + gpg_strerror (err)); + + err = gcry_pk_genkey (&key, keyspec); + if (err) + die ("gcry_pk_genkey failed for DSA: %s\n", gpg_strerror (err)); + + gcry_sexp_release (keyspec); + + return key; +} + + +/* Print the domain parameter as well as the derive information. KEY + is the complete key as returned by dsa_gen. We print to stdout + with one parameter per line in hex format using this order: p, q, + g, seed, counter, h. */ +static void +print_dsa_domain_parameters (gcry_sexp_t key) +{ + gcry_sexp_t l1, l2; + gcry_mpi_t mpi; + int idx; + const void *data; + size_t datalen; + char *string; + + l1 = gcry_sexp_find_token (key, "public-key", 0); + if (!l1) + die ("public key not found in genkey result\n"); + + l2 = gcry_sexp_find_token (l1, "dsa", 0); + if (!l2) + die ("returned public key not formed as expected\n"); + gcry_sexp_release (l1); + l1 = l2; + + /* Extract the parameters from the S-expression and print them to stdout. */ + for (idx=0; "pqg"[idx]; idx++) + { + l2 = gcry_sexp_find_token (l1, "pqg"+idx, 1); + if (!l2) + die ("no %c parameter in returned public key\n", "pqg"[idx]); + mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + if (!mpi) + die ("no value for %c parameter in returned public key\n","pqg"[idx]); + gcry_sexp_release (l2); + if (standalone_mode) + printf ("%c = ", "PQG"[idx]); + print_mpi_line (mpi, 1); + gcry_mpi_release (mpi); + } + gcry_sexp_release (l1); + + /* Extract the seed values. */ + l1 = gcry_sexp_find_token (key, "misc-key-info", 0); + if (!l1) + die ("misc-key-info not found in genkey result\n"); + + l2 = gcry_sexp_find_token (l1, "seed-values", 0); + if (!l2) + die ("no seed-values in returned key\n"); + gcry_sexp_release (l1); + l1 = l2; + + l2 = gcry_sexp_find_token (l1, "seed", 0); + if (!l2) + die ("no seed value in returned key\n"); + data = gcry_sexp_nth_data (l2, 1, &datalen); + if (!data) + die ("no seed value in returned key\n"); + if (standalone_mode) + printf ("Seed = "); + print_data_line (data, datalen); + gcry_sexp_release (l2); + + l2 = gcry_sexp_find_token (l1, "counter", 0); + if (!l2) + die ("no counter value in returned key\n"); + string = gcry_sexp_nth_string (l2, 1); + if (!string) + die ("no counter value in returned key\n"); + if (standalone_mode) + printf ("c = %ld\n", strtoul (string, NULL, 10)); + else + printf ("%lX\n", strtoul (string, NULL, 10)); + gcry_free (string); + gcry_sexp_release (l2); + + l2 = gcry_sexp_find_token (l1, "h", 0); + if (!l2) + die ("no n value in returned key\n"); + mpi = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + if (!mpi) + die ("no h value in returned key\n"); + if (standalone_mode) + printf ("H = "); + print_mpi_line (mpi, 1); + gcry_mpi_release (mpi); + gcry_sexp_release (l2); + + gcry_sexp_release (l1); +} + + +/* Generate DSA domain parameters for a modulus size of KEYSIZE. The + result is printed to stdout with one parameter per line in hex + format and in this order: p, q, g, seed, counter, h. If SEED is + not NULL this seed value will be used for the generation. */ +static void +run_dsa_pqg_gen (int keysize, const void *seed, size_t seedlen) +{ + gcry_sexp_t key; + + if (seed) + key = dsa_gen_with_seed (keysize, seed, seedlen); + else + key = dsa_gen (keysize); + print_dsa_domain_parameters (key); + gcry_sexp_release (key); +} + + +/* Generate a DSA key of size of KEYSIZE and write the private key to + FILENAME. Also write the parameters to stdout in the same way as + run_dsa_pqg_gen. */ +static void +run_dsa_gen (int keysize, const char *filename) +{ + gcry_sexp_t key, private_key; + FILE *fp; + + key = dsa_gen (keysize); + private_key = gcry_sexp_find_token (key, "private-key", 0); + if (!private_key) + die ("private key not found in genkey result\n"); + print_dsa_domain_parameters (key); + + fp = fopen (filename, "wb"); + if (!fp) + die ("can't create `%s': %s\n", filename, strerror (errno)); + print_sexp (private_key, fp); + fclose (fp); + + gcry_sexp_release (private_key); + gcry_sexp_release (key); +} + + + +/* Sign DATA of length DATALEN using the key taken from the S-expression + encoded KEYFILE. */ +static void +run_dsa_sign (const void *data, size_t datalen, const char *keyfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig, s_tmp, s_tmp2; + char hash[20]; + gcry_mpi_t tmpmpi; + + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmpmpi); + gcry_mpi_release (tmpmpi); + } + if (err) + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_sexp_from_file (keyfile); + + err = gcry_pk_sign (&s_sig, s_data, s_key); + if (err) + { + gcry_sexp_release (read_private_key_file (keyfile, 1)); + die ("gcry_pk_signed failed (datalen=%d,keyfile=%s): %s\n", + (int)datalen, keyfile, gpg_strerror (err)); + } + gcry_sexp_release (s_data); + + /* We need to return the Y parameter first. */ + s_tmp = gcry_sexp_find_token (s_key, "private-key", 0); + if (!s_tmp) + die ("private key part not found in provided key\n"); + + s_tmp2 = gcry_sexp_find_token (s_tmp, "dsa", 0); + if (!s_tmp2) + die ("private key part is not a DSA key\n"); + gcry_sexp_release (s_tmp); + + s_tmp = gcry_sexp_find_token (s_tmp2, "y", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no y parameter in DSA key\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + gcry_sexp_release (s_key); + + + /* Now return the actual signature. */ + s_tmp = gcry_sexp_find_token (s_sig, "sig-val", 0); + if (!s_tmp) + die ("no sig-val element in returned S-expression\n"); + + gcry_sexp_release (s_sig); + s_sig = s_tmp; + s_tmp = gcry_sexp_find_token (s_sig, "dsa", 0); + if (!s_tmp) + die ("no dsa element in returned S-expression\n"); + + gcry_sexp_release (s_sig); + s_sig = s_tmp; + + s_tmp = gcry_sexp_find_token (s_sig, "r", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no r parameter in returned S-expression\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + s_tmp = gcry_sexp_find_token (s_sig, "s", 0); + tmpmpi = gcry_sexp_nth_mpi (s_tmp, 1, GCRYMPI_FMT_USG); + if (!tmpmpi) + die ("no s parameter in returned S-expression\n"); + print_mpi_line (tmpmpi, 1); + gcry_mpi_release (tmpmpi); + gcry_sexp_release (s_tmp); + + gcry_sexp_release (s_sig); +} + + + +/* Verify DATA of length DATALEN using the public key taken from the + S-expression in KEYFILE against the S-expression formatted + signature in SIGFILE. */ +static void +run_dsa_verify (const void *data, size_t datalen, + const char *keyfile, const char *sigfile) + +{ + gpg_error_t err; + gcry_sexp_t s_data, s_key, s_sig; + char hash[20]; + gcry_mpi_t tmpmpi; + + gcry_md_hash_buffer (GCRY_MD_SHA1, hash, data, datalen); + /* Note that we can't simply use %b with HASH to build the + S-expression, because that might yield a negative value. */ + err = gcry_mpi_scan (&tmpmpi, GCRYMPI_FMT_USG, hash, 20, NULL); + if (!err) + { + err = gcry_sexp_build (&s_data, NULL, + "(data (flags raw)(value %m))", tmpmpi); + gcry_mpi_release (tmpmpi); + } + if (err) + die ("gcry_sexp_build failed for DSA data input: %s\n", + gpg_strerror (err)); + + s_key = read_sexp_from_file (keyfile); + s_sig = read_sexp_from_file (sigfile); + + err = gcry_pk_verify (s_sig, s_data, s_key); + if (!err) + puts ("GOOD signature"); + else if (gpg_err_code (err) == GPG_ERR_BAD_SIGNATURE) + puts ("BAD signature"); + else + printf ("ERROR (%s)\n", gpg_strerror (err)); + + gcry_sexp_release (s_sig); + gcry_sexp_release (s_key); + gcry_sexp_release (s_data); +} + + + + +static void +usage (int show_help) +{ + if (!show_help) + { + fputs ("usage: " PGM + " [OPTION] [FILE] (try --help for more information)\n", stderr); + exit (2); + } + fputs + ("Usage: " PGM " [OPTIONS] MODE [FILE]\n" + "Run a crypto operation using hex encoded input and output.\n" + "MODE:\n" + " encrypt, decrypt, digest, random, hmac-sha,\n" + " rsa-{derive,gen,sign,verify}, dsa-{pqg-gen,gen,sign,verify}\n" + "OPTIONS:\n" + " --verbose Print additional information\n" + " --binary Input and output is in binary form\n" + " --no-fips Do not force FIPS mode\n" + " --key KEY Use the hex encoded KEY\n" + " --iv IV Use the hex encoded IV\n" + " --dt DT Use the hex encoded DT for the RNG\n" + " --algo NAME Use algorithm NAME\n" + " --keysize N Use a keysize of N bits\n" + " --signature NAME Take signature from file NAME\n" + " --chunk N Read in chunks of N bytes (implies --binary)\n" + " --pkcs1 Use PKCS#1 encoding\n" + " --mct-server Run a monte carlo test server\n" + " --loop Enable random loop mode\n" + " --progress Print pogress indicators\n" + " --help Print this text\n" + "With no FILE, or when FILE is -, read standard input.\n" + "Report bugs to " PACKAGE_BUGREPORT ".\n" , stdout); + exit (0); +} + +int +main (int argc, char **argv) +{ + int last_argc = -1; + gpg_error_t err; + int no_fips = 0; + int progress = 0; + int use_pkcs1 = 0; + const char *mode_string; + const char *key_string = NULL; + const char *iv_string = NULL; + const char *dt_string = NULL; + const char *algo_string = NULL; + const char *keysize_string = NULL; + const char *signature_string = NULL; + FILE *input; + void *data; + size_t datalen; + size_t chunksize = 0; + int mct_server = 0; + + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + usage (1); + } + else if (!strcmp (*argv, "--version")) + { + fputs (PGM " (Libgcrypt) " PACKAGE_VERSION "\n", stdout); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--binary")) + { + binary_input = binary_output = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--no-fips")) + { + no_fips++; + argc--; argv++; + } + else if (!strcmp (*argv, "--loop")) + { + loop_mode = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--progress")) + { + progress = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--key")) + { + argc--; argv++; + if (!argc) + usage (0); + key_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--iv")) + { + argc--; argv++; + if (!argc) + usage (0); + iv_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--dt")) + { + argc--; argv++; + if (!argc) + usage (0); + dt_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--algo")) + { + argc--; argv++; + if (!argc) + usage (0); + algo_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--keysize")) + { + argc--; argv++; + if (!argc) + usage (0); + keysize_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--signature")) + { + argc--; argv++; + if (!argc) + usage (0); + signature_string = *argv; + argc--; argv++; + } + else if (!strcmp (*argv, "--chunk")) + { + argc--; argv++; + if (!argc) + usage (0); + chunksize = atoi (*argv); + binary_input = binary_output = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--pkcs1")) + { + use_pkcs1 = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--mct-server")) + { + mct_server = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--standalone")) + { + standalone_mode = 1; + argc--; argv++; + } + } + + if (!argc || argc > 2) + usage (0); + mode_string = *argv; + + if (!strcmp (mode_string, "rsa-derive")) + binary_input = 1; + + if (argc == 2 && strcmp (argv[1], "-")) + { + input = fopen (argv[1], binary_input? "rb":"r"); + if (!input) + die ("can't open `%s': %s\n", argv[1], strerror (errno)); + } + else + input = stdin; + +#ifndef HAVE_W32_SYSTEM + if (loop_mode) + signal (SIGPIPE, SIG_IGN); +#endif + + if (verbose) + fprintf (stderr, PGM ": started (mode=%s)\n", mode_string); + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); + if (!no_fips) + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + if (!gcry_check_version ("1.4.3")) + die ("Libgcrypt is not sufficient enough\n"); + if (verbose) + fprintf (stderr, PGM ": using Libgcrypt %s\n", gcry_check_version (NULL)); + if (no_fips) + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + /* Most operations need some input data. */ + if (!chunksize + && !mct_server + && strcmp (mode_string, "random") + && strcmp (mode_string, "rsa-gen") + && strcmp (mode_string, "dsa-gen") ) + { + data = read_file (input, !binary_input, &datalen); + if (!data) + die ("error reading%s input\n", binary_input?"":" and decoding"); + if (verbose) + fprintf (stderr, PGM ": %u bytes of input data\n", + (unsigned int)datalen); + } + else + { + data = NULL; + datalen = 0; + } + + + if (!strcmp (mode_string, "encrypt") || !strcmp (mode_string, "decrypt")) + { + int cipher_algo, cipher_mode; + void *iv_buffer = NULL; + void *key_buffer = NULL; + size_t iv_buflen, key_buflen; + + if (!algo_string) + die ("option --algo is required in this mode\n"); + cipher_algo = map_openssl_cipher_name (algo_string, &cipher_mode); + if (!cipher_algo) + die ("cipher algorithm `%s' is not supported\n", algo_string); + if (mct_server) + { + int iterations; + + for (;;) + { + gcry_free (key_buffer); key_buffer = NULL; + gcry_free (iv_buffer); iv_buffer = NULL; + gcry_free (data); data = NULL; + if (!(key_buffer = read_textline (input))) + { + if (feof (input)) + break; + die ("no version info in input\n"); + } + if (atoi (key_buffer) != 1) + die ("unsupported input version %s\n", key_buffer); + gcry_free (key_buffer); + if (!(key_buffer = read_textline (input))) + die ("no iteration count in input\n"); + iterations = atoi (key_buffer); + gcry_free (key_buffer); + if (!(key_buffer = read_hexline (input, &key_buflen))) + die ("no key in input\n"); + if (!(iv_buffer = read_hexline (input, &iv_buflen))) + die ("no IV in input\n"); + if (!(data = read_hexline (input, &datalen))) + die ("no data in input\n"); + skip_to_empty_line (input); + + run_cipher_mct_loop ((*mode_string == 'e'), + cipher_algo, cipher_mode, + iv_buffer, iv_buflen, + key_buffer, key_buflen, + data, datalen, iterations); + } + } + else + { + if (cipher_mode != GCRY_CIPHER_MODE_ECB) + { + if (!iv_string) + die ("option --iv is required in this mode\n"); + iv_buffer = hex2buffer (iv_string, &iv_buflen); + if (!iv_buffer) + die ("invalid value for IV\n"); + } + else + { + iv_buffer = NULL; + iv_buflen = 0; + } + if (!key_string) + die ("option --key is required in this mode\n"); + key_buffer = hex2buffer (key_string, &key_buflen); + if (!key_buffer) + die ("invalid value for KEY\n"); + + run_encrypt_decrypt ((*mode_string == 'e'), + cipher_algo, cipher_mode, + iv_buffer, iv_buflen, + key_buffer, key_buflen, + data, data? datalen:chunksize, input); + } + gcry_free (key_buffer); + gcry_free (iv_buffer); + } + else if (!strcmp (mode_string, "digest")) + { + int algo; + + if (!algo_string) + die ("option --algo is required in this mode\n"); + algo = gcry_md_map_name (algo_string); + if (!algo) + die ("digest algorithm `%s' is not supported\n", algo_string); + if (!data) + die ("no data available (do not use --chunk)\n"); + + run_digest (algo, data, datalen); + } + else if (!strcmp (mode_string, "random")) + { + void *context; + unsigned char key[16]; + unsigned char seed[16]; + unsigned char dt[16]; + unsigned char buffer[16]; + size_t count = 0; + + if (hex2bin (key_string, key, 16) < 0 ) + die ("value for --key are not 32 hex digits\n"); + if (hex2bin (iv_string, seed, 16) < 0 ) + die ("value for --iv are not 32 hex digits\n"); + if (hex2bin (dt_string, dt, 16) < 0 ) + die ("value for --dt are not 32 hex digits\n"); + + /* The flag value 1 disables the dup check, so that the RNG + returns all generated data. */ + err = init_external_rng_test (&context, 1, key, 16, seed, 16, dt, 16); + if (err) + die ("init external RNG test failed: %s\n", gpg_strerror (err)); + + do + { + err = run_external_rng_test (context, buffer, sizeof buffer); + if (err) + die ("running external RNG test failed: %s\n", gpg_strerror (err)); + print_buffer (buffer, sizeof buffer); + if (progress) + { + if (!(++count % 1000)) + fprintf (stderr, PGM ": %lu random bytes so far\n", + (unsigned long int)count * sizeof buffer); + } + } + while (loop_mode); + + if (progress) + fprintf (stderr, PGM ": %lu random bytes\n", + (unsigned long int)count * sizeof buffer); + + deinit_external_rng_test (context); + } + else if (!strcmp (mode_string, "hmac-sha")) + { + int algo; + void *key_buffer; + size_t key_buflen; + + if (!data) + die ("no data available (do not use --chunk)\n"); + if (!algo_string) + die ("option --algo is required in this mode\n"); + switch (atoi (algo_string)) + { + case 1: algo = GCRY_MD_SHA1; break; + case 224: algo = GCRY_MD_SHA224; break; + case 256: algo = GCRY_MD_SHA256; break; + case 384: algo = GCRY_MD_SHA384; break; + case 512: algo = GCRY_MD_SHA512; break; + default: algo = 0; break; + } + if (!algo) + die ("no digest algorithm found for hmac type `%s'\n", algo_string); + if (!key_string) + die ("option --key is required in this mode\n"); + key_buffer = hex2buffer (key_string, &key_buflen); + if (!key_buffer) + die ("invalid value for KEY\n"); + + run_hmac (algo, key_buffer, key_buflen, data, datalen); + + gcry_free (key_buffer); + } + else if (!strcmp (mode_string, "rsa-derive")) + { + if (!data) + die ("no data available (do not use --chunk)\n"); + run_rsa_derive (data, datalen); + } + else if (!strcmp (mode_string, "rsa-gen")) + { + int keysize; + + if (!binary_output) + base64_output = 1; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 128 || keysize > 16384) + die ("invalid keysize specified; needs to be 128 .. 16384\n"); + run_rsa_gen (keysize, 65537); + } + else if (!strcmp (mode_string, "rsa-sign")) + { + int algo; + + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!algo_string) + die ("option --algo is required in this mode\n"); + algo = gcry_md_map_name (algo_string); + if (!algo) + die ("digest algorithm `%s' is not supported\n", algo_string); + if (!data) + die ("no data available (do not use --chunk)\n"); + + run_rsa_sign (data, datalen, algo, use_pkcs1, key_string); + + } + else if (!strcmp (mode_string, "rsa-verify")) + { + int algo; + + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!algo_string) + die ("option --algo is required in this mode\n"); + algo = gcry_md_map_name (algo_string); + if (!algo) + die ("digest algorithm `%s' is not supported\n", algo_string); + if (!data) + die ("no data available (do not use --chunk)\n"); + if (!signature_string) + die ("option --signature is required in this mode\n"); + if (access (signature_string, R_OK)) + die ("option --signature needs to specify an existing file\n"); + + run_rsa_verify (data, datalen, algo, use_pkcs1, key_string, + signature_string); + + } + else if (!strcmp (mode_string, "dsa-pqg-gen")) + { + int keysize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + run_dsa_pqg_gen (keysize, datalen? data:NULL, datalen); + } + else if (!strcmp (mode_string, "dsa-gen")) + { + int keysize; + + keysize = keysize_string? atoi (keysize_string) : 0; + if (keysize < 1024 || keysize > 3072) + die ("invalid keysize specified; needs to be 1024 .. 3072\n"); + if (!key_string) + die ("option --key is required in this mode\n"); + run_dsa_gen (keysize, key_string); + } + else if (!strcmp (mode_string, "dsa-sign")) + { + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!data) + die ("no data available (do not use --chunk)\n"); + + run_dsa_sign (data, datalen, key_string); + } + else if (!strcmp (mode_string, "dsa-verify")) + { + if (!key_string) + die ("option --key is required in this mode\n"); + if (access (key_string, R_OK)) + die ("option --key needs to specify an existing keyfile\n"); + if (!data) + die ("no data available (do not use --chunk)\n"); + if (!signature_string) + die ("option --signature is required in this mode\n"); + if (access (signature_string, R_OK)) + die ("option --signature needs to specify an existing file\n"); + + run_dsa_verify (data, datalen, key_string, signature_string); + } + else + usage (0); + + gcry_free (data); + + /* Because Libgcrypt does not enforce FIPS mode in all cases we let + the process die if Libgcrypt is not anymore in FIPS mode after + the actual operation. */ + if (!no_fips && !gcry_fips_mode_active ()) + die ("FIPS mode is not anymore active\n"); + + if (verbose) + fputs (PGM ": ready\n", stderr); + + return 0; +} + diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/hmac.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/hmac.c new file mode 100644 index 0000000000..9d87dbb5b9 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/hmac.c @@ -0,0 +1,171 @@ +/* hmac.c - HMAC regression tests + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +static int verbose; +static int error_count; + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + + +static void +check_one_mac (int algo, + const void *key, size_t keylen, + const void *data, size_t datalen, + const char *expect) +{ + gcry_md_hd_t hd; + unsigned char *p; + int mdlen; + int i; + gcry_error_t err = 0; + + err = gcry_md_open (&hd, algo, GCRY_MD_FLAG_HMAC); + if (err) + { + fail ("algo %d, grcy_md_open failed: %s\n", algo, gpg_strerror (err)); + return; + } + + mdlen = gcry_md_get_algo_dlen (algo); + if (mdlen < 1 || mdlen > 500) + { + fail ("algo %d, grcy_md_get_algo_dlen failed: %d\n", algo, mdlen); + return; + } + + err = gcry_md_setkey (hd, key, keylen); + if (err) + { + fail ("algo %d, grcy_md_setkey failed: %s\n", algo, gpg_strerror (err)); + return; + } + + gcry_md_write (hd, data, datalen); + + p = gcry_md_read (hd, 0); + + if (memcmp (p, expect, mdlen)) + { + printf ("computed: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", p[i] & 0xFF); + printf ("\nexpected: "); + for (i = 0; i < mdlen; i++) + printf ("%02x ", expect[i] & 0xFF); + printf ("\n"); + + fail ("algo %d, MAC does not match\n", algo); + } + + gcry_md_close (hd); +} + +static void +check_hmac (void) +{ + unsigned char key[128]; + int i, j; + + if (verbose) + fprintf (stderr, "checking FIPS-198a, A.1\n"); + for (i=0; i < 64; i++) + key[i] = i; + check_one_mac (GCRY_MD_SHA1, key, 64, "Sample #1", 9, + "\x4f\x4c\xa3\xd5\xd6\x8b\xa7\xcc\x0a\x12" + "\x08\xc9\xc6\x1e\x9c\x5d\xa0\x40\x3c\x0a"); + + if (verbose) + fprintf (stderr, "checking FIPS-198a, A.2\n"); + for (i=0, j=0x30; i < 20; i++) + key[i] = j++; + check_one_mac (GCRY_MD_SHA1, key, 20, "Sample #2", 9, + "\x09\x22\xd3\x40\x5f\xaa\x3d\x19\x4f\x82" + "\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24"); + + if (verbose) + fprintf (stderr, "checking FIPS-198a, A.3\n"); + for (i=0, j=0x50; i < 100; i++) + key[i] = j++; + check_one_mac (GCRY_MD_SHA1, key, 100, "Sample #3", 9, + "\xbc\xf4\x1e\xab\x8b\xb2\xd8\x02\xf3\xd0" + "\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa"); + + if (verbose) + fprintf (stderr, "checking FIPS-198a, A.4\n"); + for (i=0, j=0x70; i < 49; i++) + key[i] = j++; + check_one_mac (GCRY_MD_SHA1, key, 49, "Sample #4", 9, + "\x9e\xa8\x86\xef\xe2\x68\xdb\xec\xce\x42" + "\x0c\x75\x24\xdf\x32\xe0\x75\x1a\x2a\x26"); + +} + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + check_hmac (); + + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/keygen.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/keygen.c new file mode 100644 index 0000000000..f5d5610cb0 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/keygen.c @@ -0,0 +1,311 @@ +/* keygen.c - key generation regression tests + * Copyright (C) 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "../src/gcrypt.h" + + + +static int verbose; +static int debug; +static int error_count; + +static void +fail ( const char *format, ... ) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + error_count++; +} + +static void +die ( const char *format, ... ) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + + +static void +print_mpi (const char *text, gcry_mpi_t a) +{ + char *buf; + void *bufaddr = &buf; + gcry_error_t rc; + + rc = gcry_mpi_aprint (GCRYMPI_FMT_HEX, bufaddr, NULL, a); + if (rc) + fprintf (stderr, "%s=[error printing number: %s]\n", + text, gpg_strerror (rc)); + else + { + fprintf (stderr, "%s=0x%s\n", text, buf); + gcry_free (buf); + } +} + + +static void +check_generated_rsa_key (gcry_sexp_t key, unsigned long expected_e) +{ + gcry_sexp_t skey, pkey, list; + + pkey = gcry_sexp_find_token (key, "public-key", 0); + if (!pkey) + fail ("public part missing in return value\n"); + else + { + gcry_mpi_t e = NULL; + + list = gcry_sexp_find_token (pkey, "e", 0); + if (!list || !(e=gcry_sexp_nth_mpi (list, 1, 0)) ) + fail ("public exponent not found\n"); + else if (!expected_e) + { + if (verbose) + print_mpi ("e", e); + } + else if ( gcry_mpi_cmp_ui (e, expected_e)) + { + print_mpi ("e", e); + fail ("public exponent is not %lu\n", expected_e); + } + gcry_sexp_release (list); + gcry_mpi_release (e); + gcry_sexp_release (pkey); + } + + skey = gcry_sexp_find_token (key, "private-key", 0); + if (!skey) + fail ("private part missing in return value\n"); + else + { + int rc = gcry_pk_testkey (skey); + if (rc) + fail ("gcry_pk_testkey failed: %s\n", gpg_strerror (rc)); + gcry_sexp_release (skey); + } + + } + +static void +check_rsa_keys (void) +{ + gcry_sexp_t keyparm, key; + int rc; + int i; + + /* Check that DSA generation works and that it can grok the qbits + argument. */ + if (verbose) + fprintf (stderr, "creating 5 1024 bit DSA keys\n"); + for (i=0; i < 5; i++) + { + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" + " (nbits 4:1024)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, keyparm); + gcry_sexp_release (keyparm); + if (rc) + die ("error generating DSA key: %s\n", gpg_strerror (rc)); + gcry_sexp_release (key); + if (verbose) + fprintf (stderr, " done\n"); + } + + if (verbose) + fprintf (stderr, "creating 1536 bit DSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (dsa\n" + " (nbits 4:1536)\n" + " (qbits 3:224)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, keyparm); + gcry_sexp_release (keyparm); + if (rc) + die ("error generating DSA key: %s\n", gpg_strerror (rc)); + if (debug) + { + char buffer[20000]; + gcry_sexp_sprint (key, GCRYSEXP_FMT_ADVANCED, buffer, sizeof buffer); + if (verbose) + printf ("=============================\n%s\n" + "=============================\n", buffer); + } + gcry_sexp_release (key); + + if (verbose) + fprintf (stderr, "creating 1024 bit RSA key\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" + " (nbits 4:1024)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, keyparm); + gcry_sexp_release (keyparm); + if (rc) + die ("error generating RSA key: %s\n", gpg_strerror (rc)); + + check_generated_rsa_key (key, 65537); + gcry_sexp_release (key); + + + if (verbose) + fprintf (stderr, "creating 512 bit RSA key with e=257\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" + " (nbits 3:512)\n" + " (rsa-use-e 3:257)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, keyparm); + gcry_sexp_release (keyparm); + if (rc) + die ("error generating RSA key: %s\n", gpg_strerror (rc)); + + check_generated_rsa_key (key, 257); + gcry_sexp_release (key); + + if (verbose) + fprintf (stderr, "creating 512 bit RSA key with default e\n"); + rc = gcry_sexp_new (&keyparm, + "(genkey\n" + " (rsa\n" + " (nbits 3:512)\n" + " (rsa-use-e 1:0)\n" + " ))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gpg_strerror (rc)); + rc = gcry_pk_genkey (&key, keyparm); + gcry_sexp_release (keyparm); + if (rc) + die ("error generating RSA key: %s\n", gpg_strerror (rc)); + + check_generated_rsa_key (key, 0); /* We don't expect a constant exponent. */ + gcry_sexp_release (key); + +} + + +static void +check_nonce (void) +{ + char a[32], b[32]; + int i,j; + int oops=0; + + if (verbose) + fprintf (stderr, "checking gcry_create_nonce\n"); + + gcry_create_nonce (a, sizeof a); + for (i=0; i < 10; i++) + { + gcry_create_nonce (b, sizeof b); + if (!memcmp (a, b, sizeof a)) + die ("identical nounce found\n"); + } + for (i=0; i < 10; i++) + { + gcry_create_nonce (a, sizeof a); + if (!memcmp (a, b, sizeof a)) + die ("identical nounce found\n"); + } + + again: + for (i=1,j=0; i < sizeof a; i++) + if (a[0] == a[i]) + j++; + if (j+1 == sizeof (a)) + { + if (oops) + die ("impossible nonce found\n"); + oops++; + gcry_create_nonce (a, sizeof a); + goto again; + } +} + + +static void +progress_cb (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + (void)what; + (void)current; + (void)total; + + if (printchar == '\n') + fputs ( "<LF>", stdout); + else + putchar (printchar); + fflush (stdout); +} + + +int +main (int argc, char **argv) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + if (verbose) + gcry_set_progress_handler ( progress_cb, NULL ); + + check_rsa_keys (); + check_nonce (); + + return error_count? 1:0; +} + diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/keygrip.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/keygrip.c new file mode 100644 index 0000000000..e1908ba3e4 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/keygrip.c @@ -0,0 +1,208 @@ +/* keygrip.c - verifies that keygrips are calculated as expected + * Copyright (C) 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include <assert.h> + +#include "../src/gcrypt.h" + +static int verbose; + + + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +static void +print_hex (const char *text, const void *buf, size_t n) +{ + const unsigned char *p = buf; + + fputs (text, stdout); + for (; n; n--, p++) + printf ("%02X", *p); + putchar ('\n'); +} + + + + +static struct +{ + int algo; + const char *key; + const unsigned char grip[20]; +} key_grips[] = + { + { + GCRY_PK_RSA, + "(private-key" + " (rsa" + " (n #00B6B509596A9ECABC939212F891E656A626BA07DA8521A9CAD4C08E640C04052FBB87F424EF1A0275A48A9299AC9DB69ABE3D0124E6C756B1F7DFB9B842D6251AEA6EE85390495CADA73D671537FCE5850A932F32BAB60AB1AC1F852C1F83C625E7A7D70CDA9EF16D5C8E47739D77DF59261ABE8454807FF441E143FBD37F8545#)" + " (e #010001#)" + " (d #077AD3DE284245F4806A1B82B79E616FBDE821C82D691A65665E57B5FAD3F34E67F401E7BD2E28699E89D9C496CF821945AE83AC7A1231176A196BA6027E77D85789055D50404A7A2A95B1512F91F190BBAEF730ED550D227D512F89C0CDB31AC06FA9A19503DDF6B66D0B42B9691BFD6140EC1720FFC48AE00C34796DC899E5#)" + " (p #00D586C78E5F1B4BF2E7CD7A04CA091911706F19788B93E44EE20AAF462E8363E98A72253ED845CCBF2481BB351E8557C85BCFFF0DABDBFF8E26A79A0938096F27#)" + " (q #00DB0CDF60F26F2A296C88D6BF9F8E5BE45C0DDD713C96CC73EBCB48B061740943F21D2A93D6E42A7211E7F02A95DCED6C390A67AD21ECF739AE8A0CA46FF2EBB3#)" + " (u #33149195F16912DB20A48D020DBC3B9E3881B39D722BF79378F6340F43148A6E9FC5F53E2853B7387BA4443BA53A52FCA8173DE6E85B42F9783D4A7817D0680B#)))", + "\x32\xCF\xFA\x85\xB1\x79\x1F\xBB\x26\x14\xE9\x1A\xFD\xF3\xAF\xE3\x32\x08\x2E\x25" + }, + { + GCRY_PK_DSA, + " (public-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + + }, + { + GCRY_PK_DSA, + "(private-key" + " (dsa" + " (p #0084E4C626E16005770BD9509ABF7354492E85B8C0060EFAAAEC617F725B592FAA59DF5460575F41022776A9718CE62EDD542AB73C7720869EBDBC834D174ADCD7136827DF51E2613545A25CA573BC502A61B809000B6E35F5EB7FD6F18C35678C23EA1C3638FB9CFDBA2800EE1B62F41A4479DE824F2834666FBF8DC5B53C2617#)" + " (q #00B0E6F710051002A9F425D98A677B18E0E5B038AB#)" + " (g #44370CEE0FE8609994183DBFEBA7EEA97D466838BCF65EFF506E35616DA93FA4E572A2F08886B74977BC00CA8CD3DBEA7AEB7DB8CBB180E6975E0D2CA76E023E6DE9F8CCD8826EBA2F72B8516532F6001DEFFAE76AA5E59E0FA33DBA3999B4E92D1703098CDEDCC416CF008801964084CDE1980132B2B78CB4CE9C15A559528B#)" + " (y #3D5DD14AFA2BF24A791E285B90232213D0E3BA74AB1109E768AED19639A322F84BB7D959E2BA92EF73DE4C7F381AA9F4053CFA3CD4527EF9043E304E5B95ED0A3A5A9D590AA641C13DB2B6E32B9B964A6A2C730DD3EA7C8E13F7A140AFF1A91CE375E9B9B960384779DC4EA180FA1F827C52288F366C0770A220F50D6D8FD6F6#)" + " (x #0087F9E91BFBCC1163DE71ED86D557708E32F8ADDE#)))", + "\x04\xA3\x4F\xA0\x2B\x03\x94\xD7\x32\xAD\xD5\x9B\x50\xAF\xDB\x5D\x57\x22\xA6\x10" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (a #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC#)" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (p #00FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF#)" + " (curve \"NIST P-256\")" + " (b #5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B#)" + " (g #046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5#)" + " (n #00FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551#)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + }, + { + GCRY_PK_ECDSA, + "(public-key" + " (ecdsa" + " (curve secp256r1)" + " (q #04C8A4CEC2E9A9BC8E173531A67B0840DF345C32E261ADD780E6D83D56EFADFD5DE872F8B854819B59543CE0B7F822330464FBC4E6324DADDCD9D059554F63B344#)))", + "\xE6\xDF\x94\x2D\xBD\x8C\x77\x05\xA3\xDD\x41\x6E\xFC\x04\x01\xDB\x31\x0E\x99\xB6" + } + + }; + +static void +check (void) +{ + unsigned char buf[20]; + unsigned char *ret; + gcry_error_t err; + gcry_sexp_t sexp; + unsigned int i; + + for (i = 0; i < (sizeof (key_grips) / sizeof (*key_grips)); i++) + { + if (gcry_pk_test_algo (key_grips[i].algo)) + { + if (verbose) + fprintf (stderr, "algo %d not available; test skipped\n", + key_grips[i].algo); + continue; + } + err = gcry_sexp_sscan (&sexp, NULL, key_grips[i].key, + strlen (key_grips[i].key)); + if (err) + die ("scanning data %d failed: %s\n", i, gpg_strerror (err)); + ret = gcry_pk_get_keygrip (sexp, buf); + if (!ret) + die ("gcry_pk_get_keygrip failed for %d\n", i); + + if ( memcmp (key_grips[i].grip, buf, sizeof (buf)) ) + { + print_hex ("keygrip: ", buf, sizeof buf); + die ("keygrip for %d does not match\n", i); + } + + gcry_sexp_release (sexp); + } +} + + + +static void +progress_handler (void *cb_data, const char *what, int printchar, + int current, int total) +{ + (void)cb_data; + (void)what; + (void)current; + (void)total; + + putchar (printchar); +} + +int +main (int argc, char **argv) +{ + int debug = 0; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_set_progress_handler (progress_handler, NULL); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + + check (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/mpitests.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/mpitests.c new file mode 100644 index 0000000000..3ccfae001e --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/mpitests.c @@ -0,0 +1,302 @@ +/* mpitests.c - basic mpi tests + * Copyright (C) 2001, 2002, 2003, 2006 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + * USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#ifdef _GCRYPT_IN_LIBGCRYPT +# include "../src/gcrypt.h" +#else +# include <gcrypt.h> +#endif + +static int verbose; +static int debug; + + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + + +/* Set up some test patterns */ + +/* 48 bytes with value 1: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char ones[] = { + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, + 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01 +}; + +/* 48 bytes with value 2: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char twos[] = { + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, + 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02, 0x02 +}; + +/* 48 bytes with value 3: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char threes[] = { + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, + 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03, 0x03 +}; + +/* 48 bytes with value 0x80: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char eighties[] = { + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, + 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 +}; + +/* 48 bytes with value 0xff: this results in 8 limbs for 64bit limbs, 16limb for 32 bit limbs */ +unsigned char manyff[] = { + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, + 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff +}; + + + +static int +test_add (void) +{ + gcry_mpi_t one; + gcry_mpi_t two; + gcry_mpi_t ff; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + gcry_mpi_scan(&ff, GCRYMPI_FMT_USG, manyff, sizeof(manyff), NULL); + result = gcry_mpi_new(0); + + gcry_mpi_add(result, one, two); + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (verbose) + printf("Result of one plus two:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_add(result, ff, one); + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (verbose) + printf("Result of ff plus one:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(one); + gcry_mpi_release(two); + gcry_mpi_release(ff); + gcry_mpi_release(result); + return 1; +} + + +static int +test_sub (void) +{ + gcry_mpi_t one; + gcry_mpi_t two; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&one, GCRYMPI_FMT_USG, ones, sizeof(ones), NULL); + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + result = gcry_mpi_new(0); + gcry_mpi_sub(result, two, one); + + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (verbose) + printf("Result of two minus one:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(one); + gcry_mpi_release(two); + gcry_mpi_release(result); + return 1; +} + + +static int +test_mul (void) +{ + gcry_mpi_t two; + gcry_mpi_t three; + gcry_mpi_t result; + unsigned char* pc; + + gcry_mpi_scan(&two, GCRYMPI_FMT_USG, twos, sizeof(twos), NULL); + gcry_mpi_scan(&three, GCRYMPI_FMT_USG, threes, sizeof(threes), NULL); + result = gcry_mpi_new(0); + gcry_mpi_mul(result, two, three); + + gcry_mpi_aprint(GCRYMPI_FMT_HEX, &pc, NULL, result); + if (verbose) + printf("Result of two mul three:\n%s\n", pc); + gcry_free(pc); + + gcry_mpi_release(two); + gcry_mpi_release(three); + gcry_mpi_release(result); + return 1; +} + + +/* What we test here is that we don't overwrite our args and that + using thne same mpi for several args works. */ +static int +test_powm (void) +{ + int b_int = 17; + int e_int = 3; + int m_int = 19; + gcry_mpi_t base = gcry_mpi_set_ui (NULL, b_int); + gcry_mpi_t exp = gcry_mpi_set_ui (NULL, e_int); + gcry_mpi_t mod = gcry_mpi_set_ui (NULL, m_int); + gcry_mpi_t res = gcry_mpi_new (0); + + gcry_mpi_powm (res, base, exp, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using base for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, exp, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using exp for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (exp, base, exp, mod); + if (gcry_mpi_cmp (res, exp)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check using mod for the result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui (exp, e_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, exp, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (exp, e_int)) + die ("test_powm_ui failed for exp at %d\n", __LINE__); + + /* Now check base ^ base mod mod. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (res, base, base, mod); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (base, base, base, mod); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (mod, m_int)) + die ("test_powm failed for mod at %d\n", __LINE__); + + /* Check base ^ base mod mod with mod as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_set_ui(mod, m_int); + gcry_mpi_powm (mod, base, base, mod); + if (gcry_mpi_cmp (res, mod)) + die ("test_powm failed at %d\n", __LINE__); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Now check base ^ base mod base. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (res, base, base, base); + if (gcry_mpi_cmp_ui (base, b_int)) + die ("test_powm failed for base at %d\n", __LINE__); + + /* Check base ^ base mod base with base as result. */ + gcry_mpi_set_ui (base, b_int); + gcry_mpi_powm (base, base, base, base); + if (gcry_mpi_cmp (res, base)) + die ("test_powm failed at %d\n", __LINE__); + + /* Fixme: We should add the rest of the cases of course. */ + + + + return 1; +} + + +int +main (int argc, char* argv[]) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + { + fputs ("version mismatch\n", stderr); + exit (1); + } + gcry_control(GCRYCTL_DISABLE_SECMEM); + + test_add (); + test_sub (); + test_mul (); + test_powm (); + + return 0; +} + diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/pkbench.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/pkbench.c new file mode 100644 index 0000000000..67b94dc9a6 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/pkbench.c @@ -0,0 +1,514 @@ +/* pkbench.c - Pubkey menchmarking + * Copyright (C) 2004, 2005, 2008 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <gcrypt.h> +#include <assert.h> +#include <stdlib.h> +#include <ctype.h> +#include <sys/stat.h> +#ifndef HAVE_W32_SYSTEM +# include <sys/times.h> +#endif /*HAVE_W32_SYSTEM*/ +#include <unistd.h> +#include <fcntl.h> +#include <time.h> +#include <errno.h> + +#define PGM "pkbench" + + +static int verbose; +static int debug; +static int error_count; + + +typedef struct context +{ + gcry_sexp_t key_secret; + gcry_sexp_t key_public; + gcry_sexp_t data; + gcry_sexp_t data_encrypted; + gcry_sexp_t data_signed; +} *context_t; + +typedef int (*work_t) (context_t context, unsigned int final); + + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fputs ( PGM ": ", stderr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + putchar ('\n'); + fputs ( PGM ": ", stderr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +static void +show_sexp (const char *prefix, gcry_sexp_t a) +{ + char *buf; + size_t size; + + fputs (prefix, stderr); + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + fprintf (stderr, "%.*s", (int)size, buf); + gcry_free (buf); +} + + +static void * +read_file (const char *fname, size_t *r_length) +{ + FILE *fp; + struct stat st; + char *buf; + size_t buflen; + + fp = fopen (fname, "rb"); + if (!fp) + { + fail ("can't open `%s': %s\n", fname, strerror (errno)); + return NULL; + } + + if (fstat (fileno(fp), &st)) + { + fail ("can't stat `%s': %s\n", fname, strerror (errno)); + fclose (fp); + return NULL; + } + + buflen = st.st_size; + buf = gcry_xmalloc (buflen+1); + if (fread (buf, buflen, 1, fp) != 1) + { + fail ("error reading `%s': %s\n", fname, strerror (errno)); + fclose (fp); + gcry_free (buf); + return NULL; + } + fclose (fp); + + if (r_length) + *r_length = buflen; + return buf; +} + + + +static void +benchmark (work_t worker, context_t context) +{ + clock_t timer_start, timer_stop; + unsigned int loop = 10; + unsigned int i = 0; + struct tms timer; + int ret = 0; + +#ifdef HAVE_W32_SYSTEM + timer_start = clock (); +#else + times (&timer); + timer_start = timer.tms_utime; +#endif + for (i = 0; i < loop; i++) + { + ret = (*worker) (context, (i + 1) == loop); + if (! ret) + break; + } +#ifdef HAVE_W32_SYSTEM + timer_stop = clock (); +#else + times (&timer); + timer_stop = timer.tms_utime; +#endif + + if (ret) + printf ("%.0f ms\n", + (((double) ((timer_stop - timer_start) / loop)) / CLOCKS_PER_SEC) + * 10000000); + else + printf ("[skipped]\n"); +} + +static int +work_encrypt (context_t context, unsigned int final) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_sexp_t data_encrypted = NULL; + int ret = 1; + + err = gcry_pk_encrypt (&data_encrypted, + context->data, context->key_public); + if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) + { + err = GPG_ERR_NO_ERROR; + ret = 0; + } + else + { + assert (! err); + + if (final) + context->data_encrypted = data_encrypted; + else + gcry_sexp_release (data_encrypted); + } + + return ret; +} + +static int +work_decrypt (context_t context, unsigned int final) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + int ret = 1; + + if (! context->data_encrypted) + ret = 0; + else + { + gcry_sexp_t data_decrypted = NULL; + + err = gcry_pk_decrypt (&data_decrypted, + context->data_encrypted, + context->key_secret); + assert (! err); + if (final) + { + gcry_sexp_release (context->data_encrypted); + context->data_encrypted = NULL; + } + gcry_sexp_release (data_decrypted); + } + + return ret; +} + +static int +work_sign (context_t context, unsigned int final) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_sexp_t data_signed = NULL; + int ret = 1; + + err = gcry_pk_sign (&data_signed, + context->data, context->key_secret); + if (gpg_err_code (err) == GPG_ERR_NOT_IMPLEMENTED) + { + err = GPG_ERR_NO_ERROR; + ret = 0; + } + else if (err) + { + fail ("pk_sign failed: %s\n", gpg_strerror (err)); + ret = 0; + } + else + { + if (final) + context->data_signed = data_signed; + else + gcry_sexp_release (data_signed); + } + + return ret; +} + +static int +work_verify (context_t context, unsigned int final) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + int ret = 1; + + if (!context->data_signed) + return 0; + + err = gcry_pk_verify (context->data_signed, + context->data, + context->key_public); + if (err) + { + show_sexp ("data_signed:\n", context->data_signed); + show_sexp ("data:\n", context->data); + fail ("pk_verify failed: %s\n", gpg_strerror (err)); + ret = 0; + } + else if (final) + { + gcry_sexp_release (context->data_signed); + context->data_signed = NULL; + } + + return ret; +} + +static void +process_key_pair (context_t context) +{ + struct + { + work_t worker; + const char *identifier; + } worker_functions[] = { { work_encrypt, "encrypt" }, + { work_decrypt, "decrypt" }, + { work_sign, "sign" }, + { work_verify, "verify" } }; + unsigned int i = 0; + + for (i = 0; i < (sizeof (worker_functions) / sizeof (*worker_functions)); i++) + { + printf ("%s: ", worker_functions[i].identifier); + benchmark (worker_functions[i].worker, context); + } +} + +static void +context_init (context_t context, gcry_sexp_t key_secret, gcry_sexp_t key_public) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + unsigned int key_size = 0; + gcry_mpi_t data = NULL; + gcry_sexp_t data_sexp = NULL; + + key_size = gcry_pk_get_nbits (key_secret); + assert (key_size); + + data = gcry_mpi_new (key_size); + assert (data); + + gcry_mpi_randomize (data, key_size, GCRY_STRONG_RANDOM); + gcry_mpi_clear_bit (data, key_size - 1); + err = gcry_sexp_build (&data_sexp, NULL, + "(data (flags raw) (value %m))", + data); + assert (! err); + gcry_mpi_release (data); + + context->key_secret = key_secret; + context->key_public = key_public; + context->data = data_sexp; + context->data_encrypted = NULL; + context->data_signed = NULL; +} + +static void +context_destroy (context_t context) +{ + gcry_sexp_release (context->key_secret); + gcry_sexp_release (context->key_public); + gcry_sexp_release (context->data); +} + +static void +process_key_pair_file (const char *key_pair_file) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + void *key_pair_buffer = NULL; + gcry_sexp_t key_pair_sexp = NULL; + gcry_sexp_t key_secret_sexp = NULL; + gcry_sexp_t key_public_sexp = NULL; + struct context context = { NULL }; + size_t file_length; + + key_pair_buffer = read_file (key_pair_file, &file_length); + if (!key_pair_buffer) + die ("failed to open `%s'\n", key_pair_file); + + err = gcry_sexp_sscan (&key_pair_sexp, NULL, + key_pair_buffer, file_length); + if (err) + die ("gcry_sexp_sscan failed\n"); + + key_secret_sexp = gcry_sexp_find_token (key_pair_sexp, "private-key", 0); + assert (key_secret_sexp); + key_public_sexp = gcry_sexp_find_token (key_pair_sexp, "public-key", 0); + assert (key_public_sexp); + + gcry_sexp_release (key_pair_sexp); + + context_init (&context, key_secret_sexp, key_public_sexp); + + printf ("Key file: %s\n", key_pair_file); + process_key_pair (&context); + printf ("\n"); + + context_destroy (&context); + gcry_free (key_pair_buffer); +} + + +static void +generate_key (const char *algorithm, const char *key_size) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + size_t key_pair_buffer_size = 0; + char *key_pair_buffer = NULL; + gcry_sexp_t key_spec = NULL; + gcry_sexp_t key_pair = NULL; + + if (isdigit ((unsigned int)*key_size)) + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (%s (nbits %s)))", + algorithm, key_size); + else + err = gcry_sexp_build (&key_spec, NULL, + "(genkey (%s (curve %s)))", + algorithm, key_size); + if (err) + die ("sexp_build failed: %s\n", gpg_strerror (err)); + + err = gcry_pk_genkey (&key_pair, key_spec); + if (err) + { + show_sexp ("request:\n", key_spec); + die ("pk_genkey failed: %s\n", gpg_strerror (err)); + } + + key_pair_buffer_size = gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED, + NULL, 0); + key_pair_buffer = gcry_xmalloc (key_pair_buffer_size); + + gcry_sexp_sprint (key_pair, GCRYSEXP_FMT_ADVANCED, + key_pair_buffer, key_pair_buffer_size); + + printf ("%.*s", (int)key_pair_buffer_size, key_pair_buffer); + gcry_free (key_pair_buffer); +} + + + +int +main (int argc, char **argv) +{ + int last_argc = -1; + int genkey_mode = 0; + int fips_mode = 0; + + if (argc) + { argc--; argv++; } + + while (argc && last_argc != argc ) + { + last_argc = argc; + if (!strcmp (*argv, "--")) + { + argc--; argv++; + break; + } + else if (!strcmp (*argv, "--help")) + { + puts ("Usage: " PGM " [OPTIONS] [FILES]\n" + "Various public key tests:\n\n" + " Default is to process all given key files\n\n" + " --genkey ALGONAME SIZE Generate a public key\n" + "\n" + " --verbose enable extra informational output\n" + " --debug enable additional debug output\n" + " --help display this help and exit\n\n"); + exit (0); + } + else if (!strcmp (*argv, "--verbose")) + { + verbose++; + argc--; argv++; + } + else if (!strcmp (*argv, "--debug")) + { + verbose = debug = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--genkey")) + { + genkey_mode = 1; + argc--; argv++; + } + else if (!strcmp (*argv, "--fips")) + { + fips_mode = 1; + argc--; argv++; + } + } + + gcry_control (GCRYCTL_SET_VERBOSITY, (int)verbose); + + if (fips_mode) + gcry_control (GCRYCTL_FORCE_FIPS_MODE, 0); + + gcry_control (GCRYCTL_DISABLE_SECMEM); + if (!gcry_check_version (GCRYPT_VERSION)) + { + fprintf (stderr, PGM ": version mismatch\n"); + exit (1); + } + + if (genkey_mode) + { + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + } + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + + if (genkey_mode && argc == 2) + { + generate_key (argv[0], argv[1]); + } + else if (!genkey_mode && argc) + { + int i; + + for (i = 0; i < argc; i++) + process_key_pair_file (argv[i]); + } + else + { + fprintf (stderr, "usage: " PGM + " [OPTIONS] [FILES] (try --help for more information)\n"); + exit (1); + } + + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/prime.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/prime.c new file mode 100644 index 0000000000..12bcc89439 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/prime.c @@ -0,0 +1,122 @@ +/* prime.c - part of the Libgcrypt test suite. + Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> + +#include "../src/gcrypt.h" + +static int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +static void +check_primes (void) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + gcry_mpi_t *factors = NULL; + gcry_mpi_t prime = NULL; + gcry_mpi_t g; + unsigned int i = 0; + struct prime_spec + { + unsigned int prime_bits; + unsigned int factor_bits; + unsigned int flags; + } prime_specs[] = + { + { 1024, 100, GCRY_PRIME_FLAG_SPECIAL_FACTOR }, + { 128, 0, 0 }, + { 0 }, + }; + + for (i = 0; prime_specs[i].prime_bits; i++) + { + err = gcry_prime_generate (&prime, + prime_specs[i].prime_bits, + prime_specs[i].factor_bits, + &factors, + NULL, NULL, + GCRY_WEAK_RANDOM, + prime_specs[i].flags); + assert (! err); + if (verbose) + { + fprintf (stderr, "test %d: p = ", i); + gcry_mpi_dump (prime); + putc ('\n', stderr); + } + + err = gcry_prime_check (prime, 0); + assert (! err); + + err = gcry_prime_group_generator (&g, prime, factors, NULL); + assert (!err); + gcry_prime_release_factors (factors); factors = NULL; + + if (verbose) + { + fprintf (stderr, " %d: g = ", i); + gcry_mpi_dump (g); + putc ('\n', stderr); + } + gcry_mpi_release (g); + + + gcry_mpi_add_ui (prime, prime, 1); + err = gcry_prime_check (prime, 0); + assert (err); + } +} + +int +main (int argc, char **argv) +{ + int debug = 0; + + if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) + verbose = 1; + else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) + verbose = debug = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (! gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + + check_primes (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/pubkey.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/pubkey.c new file mode 100644 index 0000000000..e5ec464acd --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/pubkey.c @@ -0,0 +1,890 @@ +/* pubkey.c - Public key encryption/decryption tests + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, see <http://www.gnu.org/licenses/>. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + + +#include "../src/gcrypt.h" + +/* Sample RSA keys, taken from basic.c. */ + +static const char sample_private_key_1[] = +"(private-key\n" +" (openpgp-rsa\n" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" +" (e #010001#)\n" +" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" + "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" + "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" + "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" +" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" + "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" +" (q #00f7a7ca5367c661f8e62df34f0d05c10c88e5492348dd7bddc942c9a8f369f9" + "35a07785d2db805215ed786e4285df1658eed3ce84f469b81b50d358407b4ad361#)\n" +" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" + "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" +" )\n" +")\n"; + +/* The same key as above but without p, q and u to test the non CRT case. */ +static const char sample_private_key_1_1[] = +"(private-key\n" +" (openpgp-rsa\n" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" +" (e #010001#)\n" +" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" + "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" + "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" + "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" +" )\n" +")\n"; + +/* The same key as above but just without q to test the non CRT case. This + should fail. */ +static const char sample_private_key_1_2[] = +"(private-key\n" +" (openpgp-rsa\n" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" +" (e #010001#)\n" +" (d #046129F2489D71579BE0A75FE029BD6CDB574EBF57EA8A5B0FDA942CAB943B11" + "7D7BB95E5D28875E0F9FC5FCC06A72F6D502464DABDED78EF6B716177B83D5BD" + "C543DC5D3FED932E59F5897E92E6F58A0F33424106A3B6FA2CBF877510E4AC21" + "C3EE47851E97D12996222AC3566D4CCB0B83D164074ABF7DE655FC2446DA1781#)\n" +" (p #00e861b700e17e8afe6837e7512e35b6ca11d0ae47d8b85161c67baf64377213" + "fe52d772f2035b3ca830af41d8a4120e1c1c70d12cc22f00d28d31dd48a8d424f1#)\n" +" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e" + "ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)\n" +" )\n" +")\n"; + +static const char sample_public_key_1[] = +"(public-key\n" +" (rsa\n" +" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa" + "2d1ff95a7f542465c6c0c19d276e4526ce048868a7a914fd343cc3a87dd74291" + "ffc565506d5bbb25cbac6a0e2dd1f8bcaab0d4a29c2f37c950f363484bf269f7" + "891440464baf79827e03a36e70b814938eebdc63e964247be75dc58b014b7ea251#)\n" +" (e #010001#)\n" +" )\n" +")\n"; + + +static int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +static void +show_sexp (const char *prefix, gcry_sexp_t a) +{ + char *buf; + size_t size; + + if (prefix) + fputs (prefix, stderr); + size = gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, NULL, 0); + buf = gcry_xmalloc (size); + + gcry_sexp_sprint (a, GCRYSEXP_FMT_ADVANCED, buf, size); + fprintf (stderr, "%.*s", (int)size, buf); + gcry_free (buf); +} + + +static void +check_keys_crypt (gcry_sexp_t pkey, gcry_sexp_t skey, + gcry_sexp_t plain0, gpg_err_code_t decrypt_fail_code) +{ + gcry_sexp_t plain1, cipher, l; + gcry_mpi_t x0, x1; + int rc; + int have_flags; + + /* Extract data from plaintext. */ + l = gcry_sexp_find_token (plain0, "value", 0); + x0 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + + /* Encrypt data. */ + rc = gcry_pk_encrypt (&cipher, plain0, pkey); + if (rc) + die ("encryption failed: %s\n", gcry_strerror (rc)); + + l = gcry_sexp_find_token (cipher, "flags", 0); + have_flags = !!l; + gcry_sexp_release (l); + + /* Decrypt data. */ + rc = gcry_pk_decrypt (&plain1, cipher, skey); + gcry_sexp_release (cipher); + if (rc) + { + if (decrypt_fail_code && gpg_err_code (rc) == decrypt_fail_code) + return; /* This is the expected failure code. */ + die ("decryption failed: %s\n", gcry_strerror (rc)); + } + + /* Extract decrypted data. Note that for compatibility reasons, the + output of gcry_pk_decrypt depends on whether a flags lists (even + if empty) occurs in its input data. Because we passed the output + of encrypt directly to decrypt, such a flag value won't be there + as of today. We check it anyway. */ + l = gcry_sexp_find_token (plain1, "value", 0); + if (l) + { + if (!have_flags) + die ("compatibility mode of pk_decrypt broken\n"); + gcry_sexp_release (plain1); + x1 = gcry_sexp_nth_mpi (l, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l); + } + else + { + if (have_flags) + die ("compatibility mode of pk_decrypt broken\n"); + x1 = gcry_sexp_nth_mpi (plain1, 0, GCRYMPI_FMT_USG); + gcry_sexp_release (plain1); + } + + /* Compare. */ + if (gcry_mpi_cmp (x0, x1)) + die ("data corrupted\n"); +} + +static void +check_keys (gcry_sexp_t pkey, gcry_sexp_t skey, unsigned int nbits_data, + gpg_err_code_t decrypt_fail_code) +{ + gcry_sexp_t plain; + gcry_mpi_t x; + int rc; + + /* Create plain text. */ + x = gcry_mpi_new (nbits_data); + gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); + + rc = gcry_sexp_build (&plain, NULL, "(data (flags raw) (value %m))", x); + if (rc) + die ("converting data for encryption failed: %s\n", + gcry_strerror (rc)); + + check_keys_crypt (pkey, skey, plain, decrypt_fail_code); + gcry_sexp_release (plain); + gcry_mpi_release (x); + + /* Create plain text. */ + x = gcry_mpi_new (nbits_data); + gcry_mpi_randomize (x, nbits_data, GCRY_WEAK_RANDOM); + + rc = gcry_sexp_build (&plain, NULL, + "(data (flags raw no-blinding) (value %m))", x); + if (rc) + die ("converting data for encryption failed: %s\n", + gcry_strerror (rc)); + + check_keys_crypt (pkey, skey, plain, decrypt_fail_code); + gcry_sexp_release (plain); +} + +static void +get_keys_sample (gcry_sexp_t *pkey, gcry_sexp_t *skey, int secret_variant) +{ + gcry_sexp_t pub_key, sec_key; + int rc; + static const char *secret; + + + switch (secret_variant) + { + case 0: secret = sample_private_key_1; break; + case 1: secret = sample_private_key_1_1; break; + case 2: secret = sample_private_key_1_2; break; + default: die ("BUG\n"); + } + + rc = gcry_sexp_sscan (&pub_key, NULL, sample_public_key_1, + strlen (sample_public_key_1)); + if (!rc) + rc = gcry_sexp_sscan (&sec_key, NULL, secret, strlen (secret)); + if (rc) + die ("converting sample keys failed: %s\n", gcry_strerror (rc)); + + *pkey = pub_key; + *skey = sec_key; +} + +static void +get_keys_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new (&key_spec, + "(genkey (rsa (nbits 4:1024)))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating RSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated RSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (! pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (! sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_keys_x931_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new (&key_spec, + "(genkey (rsa (nbits 4:1024)(use-x931)))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating RSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated RSA (X9.31) key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_elg_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int fixed_x) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + (fixed_x + ? "(genkey (elg (nbits 4:1024)(xvalue my.not-so-secret.key)))" + : "(genkey (elg (nbits 3:512)))"), + 0, 1); + + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating Elgamal key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated ELG key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_dsa_key_new (gcry_sexp_t *pkey, gcry_sexp_t *skey, int transient_key) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new (&key_spec, + transient_key + ? "(genkey (dsa (nbits 4:1024)(transient-key)))" + : "(genkey (dsa (nbits 4:1024)))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_dsa_key_fips186_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, "(genkey (dsa (nbits 4:1024)(use-fips186)))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key (fips 186):\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_dsa_key_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey (dsa (transient-key)(domain" + "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" + "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" + "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" + "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" + "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" + "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" + "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" + "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" + "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" + ")))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + +static void +get_dsa_key_fips186_with_domain_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey (dsa (transient-key)(use-fips186)(domain" + "(p #d3aed1876054db831d0c1348fbb1ada72507e5fbf9a62cbd47a63aeb7859d6921" + "4adeb9146a6ec3f43520f0fd8e3125dd8bbc5d87405d1ac5f82073cd762a3f8d7" + "74322657c9da88a7d2f0e1a9ceb84a39cb40876179e6a76e400498de4bb9379b0" + "5f5feb7b91eb8fea97ee17a955a0a8a37587a272c4719d6feb6b54ba4ab69#)" + "(q #9c916d121de9a03f71fb21bc2e1c0d116f065a4f#)" + "(g #8157c5f68ca40b3ded11c353327ab9b8af3e186dd2e8dade98761a0996dda99ab" + "0250d3409063ad99efae48b10c6ab2bba3ea9a67b12b911a372a2bba260176fad" + "b4b93247d9712aad13aa70216c55da9858f7a298deb670a403eb1e7c91b847f1e" + "ccfbd14bd806fd42cf45dbb69cd6d6b43add2a78f7d16928eaa04458dea44#)" + ")))", 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key:\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +get_dsa_key_fips186_with_seed_new (gcry_sexp_t *pkey, gcry_sexp_t *skey) +{ + gcry_sexp_t key_spec, key, pub_key, sec_key; + int rc; + + rc = gcry_sexp_new + (&key_spec, + "(genkey" + " (dsa" + " (nbits 4:1024)" + " (use-fips186)" + " (transient-key)" + " (derive-parms" + " (seed #0cb1990c1fd3626055d7a0096f8fa99807399871#))))", + 0, 1); + if (rc) + die ("error creating S-expression: %s\n", gcry_strerror (rc)); + rc = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (rc) + die ("error generating DSA key: %s\n", gcry_strerror (rc)); + + if (verbose > 1) + show_sexp ("generated DSA key (fips 186 with seed):\n", key); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key\n"); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key\n"); + + gcry_sexp_release (key); + *pkey = pub_key; + *skey = sec_key; +} + + +static void +check_run (void) +{ + gpg_error_t err; + gcry_sexp_t pkey, skey; + int variant; + + for (variant=0; variant < 3; variant++) + { + if (verbose) + fprintf (stderr, "Checking sample key (%d).\n", variant); + get_keys_sample (&pkey, &skey, variant); + /* Check gcry_pk_testkey which requires all elements. */ + err = gcry_pk_testkey (skey); + if ((variant == 0 && err) + || (variant > 0 && gpg_err_code (err) != GPG_ERR_NO_OBJ)) + die ("gcry_pk_testkey failed: %s\n", gpg_strerror (err)); + /* Run the usual check but expect an error from variant 2. */ + check_keys (pkey, skey, 800, variant == 2? GPG_ERR_NO_OBJ : 0); + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + } + + if (verbose) + fprintf (stderr, "Checking generated RSA key.\n"); + get_keys_new (&pkey, &skey); + check_keys (pkey, skey, 800, 0); + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Checking generated RSA key (X9.31).\n"); + get_keys_x931_new (&pkey, &skey); + check_keys (pkey, skey, 800, 0); + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Checking generated Elgamal key.\n"); + get_elg_key_new (&pkey, &skey, 0); + check_keys (pkey, skey, 400, 0); + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Checking passphrase generated Elgamal key.\n"); + get_elg_key_new (&pkey, &skey, 1); + check_keys (pkey, skey, 800, 0); + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key.\n"); + get_dsa_key_new (&pkey, &skey, 0); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (!gcry_fips_mode_active ()) + { + if (verbose) + fprintf (stderr, "Generating transient DSA key.\n"); + get_dsa_key_new (&pkey, &skey, 1); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + } + + if (verbose) + fprintf (stderr, "Generating DSA key (FIPS 186).\n"); + get_dsa_key_fips186_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given domain.\n"); + get_dsa_key_with_domain_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given domain (FIPS 186).\n"); + get_dsa_key_fips186_with_domain_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); + + if (verbose) + fprintf (stderr, "Generating DSA key with given seed (FIPS 186).\n"); + get_dsa_key_fips186_with_seed_new (&pkey, &skey); + /* Fixme: Add a check function for DSA keys. */ + gcry_sexp_release (pkey); + gcry_sexp_release (skey); +} + + + +static gcry_mpi_t +key_param_from_sexp (gcry_sexp_t sexp, const char *topname, const char *name) +{ + gcry_sexp_t l1, l2; + gcry_mpi_t result; + + l1 = gcry_sexp_find_token (sexp, topname, 0); + if (!l1) + return NULL; + + l2 = gcry_sexp_find_token (l1, name, 0); + if (!l2) + { + gcry_sexp_release (l1); + return NULL; + } + + result = gcry_sexp_nth_mpi (l2, 1, GCRYMPI_FMT_USG); + gcry_sexp_release (l2); + gcry_sexp_release (l1); + return result; +} + + +static void +check_x931_derived_key (int what) +{ + static struct { + const char *param; + const char *expected_d; + } testtable[] = { + { /* First example from X9.31 (D.1.1). */ + "(genkey\n" + " (rsa\n" + " (nbits 4:1024)\n" + " (rsa-use-e 1:3)\n" + " (derive-parms\n" + " (Xp1 #1A1916DDB29B4EB7EB6732E128#)\n" + " (Xp2 #192E8AAC41C576C822D93EA433#)\n" + " (Xp #D8CD81F035EC57EFE822955149D3BFF70C53520D\n" + " 769D6D76646C7A792E16EBD89FE6FC5B605A6493\n" + " 39DFC925A86A4C6D150B71B9EEA02D68885F5009\n" + " B98BD984#)\n" + " (Xq1 #1A5CF72EE770DE50CB09ACCEA9#)\n" + " (Xq2 #134E4CAA16D2350A21D775C404#)\n" + " (Xq #CC1092495D867E64065DEE3E7955F2EBC7D47A2D\n" + " 7C9953388F97DDDC3E1CA19C35CA659EDC2FC325\n" + " 6D29C2627479C086A699A49C4C9CEE7EF7BD1B34\n" + " 321DE34A#))))\n", + "1CCDA20BCFFB8D517EE9666866621B11822C7950D55F4BB5BEE37989A7D173" + "12E326718BE0D79546EAAE87A56623B919B1715FFBD7F16028FC4007741961" + "C88C5D7B4DAAAC8D36A98C9EFBB26C8A4A0E6BC15B358E528A1AC9D0F042BE" + "B93BCA16B541B33F80C933A3B769285C462ED5677BFE89DF07BED5C127FD13" + "241D3C4B" + }, + + { /* Second example from X9.31 (D.2.1). */ + "(genkey\n" + " (rsa\n" + " (nbits 4:1536)\n" + " (rsa-use-e 1:3)\n" + " (derive-parms\n" + " (Xp1 #18272558B61316348297EACA74#)\n" + " (Xp2 #1E970E8C6C97CEF91F05B0FA80#)\n" + " (Xp #F7E943C7EF2169E930DCF23FE389EF7507EE8265\n" + " 0D42F4A0D3A3CEFABE367999BB30EE680B2FE064\n" + " 60F707F46005F8AA7CBFCDDC4814BBE7F0F8BC09\n" + " 318C8E51A48D134296E40D0BBDD282DCCBDDEE1D\n" + " EC86F0B1C96EAFF5CDA70F9AEB6EE31E#)\n" + " (Xq1 #11FDDA6E8128DC1629F75192BA#)\n" + " (Xq2 #18AB178ECA907D72472F65E480#)\n" + " (Xq #C47560011412D6E13E3E7D007B5C05DBF5FF0D0F\n" + " CFF1FA2070D16C7ABA93EDFB35D8700567E5913D\n" + " B734E3FBD15862EBC59FA0425DFA131E549136E8\n" + " E52397A8ABE4705EC4877D4F82C4AAC651B33DA6\n" + " EA14B9D5F2A263DC65626E4D6CEAC767#))))\n", + "1FB56069985F18C4519694FB71055721A01F14422DC901C35B03A64D4A5BD1" + "259D573305F5B056AC931B82EDB084E39A0FD1D1A86CC5B147A264F7EF4EB2" + "0ED1E7FAAE5CAE4C30D5328B7F74C3CAA72C88B70DED8EDE207B8629DA2383" + "B78C3CE1CA3F9F218D78C938B35763AF2A8714664CC57F5CECE2413841F5E9" + "EDEC43B728E25A41BF3E1EF8D9EEE163286C9F8BF0F219D3B322C3E4B0389C" + "2E8BB28DC04C47DA2BF38823731266D2CF6CC3FC181738157624EF051874D0" + "BBCCB9F65C83" + /* Note that this example in X9.31 gives this value for D: + + "7ED581A6617C6311465A53EDC4155C86807C5108B724070D6C0E9935296F44" + "96755CCC17D6C15AB24C6E0BB6C2138E683F4746A1B316C51E8993DFBD3AC8" + "3B479FEAB972B930C354CA2DFDD30F2A9CB222DC37B63B7881EE18A7688E0E" + "DE30F38728FE7C8635E324E2CD5D8EBCAA1C51993315FD73B38904E107D7A7" + "B7B10EDCA3896906FCF87BE367BB858CA1B27E2FC3C8674ECC8B0F92C0E270" + "BA2ECA3701311F68AFCE208DCC499B4B3DB30FF0605CE055D893BC1461D342" + "EF32E7D9720B" + + This is a bug in X9.31, obviously introduced by using + + d = e^{-1} mod (p-1)(q-1) + + instead of using the universal exponent as required by 4.1.3: + + d = e^{-1} mod lcm(p-1,q-1) + + The examples in X9.31 seem to be pretty buggy, see + cipher/primegen.c for another bug. Not only that I had to + spend 100 USD for the 66 pages of the document, it also took + me several hours to figure out that the bugs are in the + document and not in my code. + */ + }, + + { /* First example from NIST RSAVS (B.1.1). */ + "(genkey\n" + " (rsa\n" + " (nbits 4:1024)\n" + " (rsa-use-e 1:3)\n" + " (derive-parms\n" + " (Xp1 #1ed3d6368e101dab9124c92ac8#)\n" + " (Xp2 #16e5457b8844967ce83cab8c11#)\n" + " (Xp #b79f2c2493b4b76f329903d7555b7f5f06aaa5ea\n" + " ab262da1dcda8194720672a4e02229a0c71f60ae\n" + " c4f0d2ed8d49ef583ca7d5eeea907c10801c302a\n" + " cab44595#)\n" + " (Xq1 #1a5d9e3fa34fb479bedea412f6#)\n" + " (Xq2 #1f9cca85f185341516d92e82fd#)\n" + " (Xq #c8387fd38fa33ddcea6a9de1b2d55410663502db\n" + " c225655a9310cceac9f4cf1bce653ec916d45788\n" + " f8113c46bc0fa42bf5e8d0c41120c1612e2ea8bb\n" + " 2f389eda#))))\n", + "17ef7ad4fd96011b62d76dfb2261b4b3270ca8e07bc501be954f8719ef586b" + "f237e8f693dd16c23e7adecc40279dc6877c62ab541df5849883a5254fccfd" + "4072a657b7f4663953930346febd6bbd82f9a499038402cbf97fd5f068083a" + "c81ad0335c4aab0da19cfebe060a1bac7482738efafea078e21df785e56ea0" + "dc7e8feb" + }, + + { /* Second example from NIST RSAVS (B.1.1). */ + "(genkey\n" + " (rsa\n" + " (nbits 4:1536)\n" + " (rsa-use-e 1:3)\n" + " (derive-parms\n" + " (Xp1 #1e64c1af460dff8842c22b64d0#)\n" + " (Xp2 #1e948edcedba84039c81f2ac0c#)\n" + " (Xp #c8c67df894c882045ede26a9008ab09ea0672077\n" + " d7bc71d412511cd93981ddde8f91b967da404056\n" + " c39f105f7f239abdaff92923859920f6299e82b9\n" + " 5bd5b8c959948f4a034d81613d6235a3953b49ce\n" + " 26974eb7bb1f14843841281b363b9cdb#)\n" + " (Xq1 #1f3df0f017ddd05611a97b6adb#)\n" + " (Xq2 #143edd7b22d828913abf24ca4d#)\n" + " (Xq #f15147d0e7c04a1e3f37adde802cdc610999bf7a\n" + " b0088434aaeda0c0ab3910b14d2ce56cb66bffd9\n" + " 7552195fae8b061077e03920814d8b9cfb5a3958\n" + " b3a82c2a7fc97e55db543948d3396289245336ec\n" + " 9e3cb308cc655aebd766340da8921383#))))\n", + "1f8b19f3f5f2ac9fc599f110cad403dcd9bdf5f7f00fb2790e78e820398184" + "1f3fb3dd230fb223d898f45719d9b2d3525587ff2b8bcc7425e40550a5b536" + "1c8e9c1d26e83fbd9c33c64029c0e878b829d55def12912b73d94fd758c461" + "0f473e230c41b5e4c86e27c5a5029d82c811c88525d0269b95bd2ff272994a" + "dbd80f2c2ecf69065feb8abd8b445b9c6d306b1585d7d3d7576d49842bc7e2" + "8b4a2f88f4a47e71c3edd35fdf83f547ea5c2b532975c551ed5268f748b2c4" + "2ccf8a84835b" + } + }; + gpg_error_t err; + gcry_sexp_t key_spec, key, pub_key, sec_key; + gcry_mpi_t d_expected, d_have; + + if (what < 0 && what >= sizeof testtable) + die ("invalid WHAT value\n"); + + err = gcry_sexp_new (&key_spec, testtable[what].param, 0, 1); + if (err) + die ("error creating S-expression [%d]: %s\n", what, gpg_strerror (err)); + + err = gcry_pk_genkey (&key, key_spec); + gcry_sexp_release (key_spec); + if (err) + die ("error generating RSA key [%d]: %s\n", what, gpg_strerror (err)); + + pub_key = gcry_sexp_find_token (key, "public-key", 0); + if (!pub_key) + die ("public part missing in key [%d]\n", what); + + sec_key = gcry_sexp_find_token (key, "private-key", 0); + if (!sec_key) + die ("private part missing in key [%d]\n", what); + + err = gcry_mpi_scan + (&d_expected, GCRYMPI_FMT_HEX, testtable[what].expected_d, 0, NULL); + if (err) + die ("error converting string [%d]\n", what); + + if (verbose > 1) + show_sexp ("generated key:\n", key); + + d_have = key_param_from_sexp (sec_key, "rsa", "d"); + if (!d_have) + die ("parameter d not found in RSA secret key [%d]\n", what); + if (gcry_mpi_cmp (d_expected, d_have)) + { + show_sexp (NULL, sec_key); + die ("parameter d does match expected value [%d]\n", what); + } + gcry_mpi_release (d_expected); + gcry_mpi_release (d_have); + + gcry_sexp_release (key); + gcry_sexp_release (pub_key); + gcry_sexp_release (sec_key); +} + + + + +int +main (int argc, char **argv) +{ + int debug = 0; + int i; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + { + verbose = 2; + debug = 1; + } + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + /* No valuable keys are create, so we can speed up our RNG. */ + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + + for (i=0; i < 2; i++) + check_run (); + + for (i=0; i < 4; i++) + check_x931_derived_key (i); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/random.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/random.c new file mode 100644 index 0000000000..502a37582a --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/random.c @@ -0,0 +1,255 @@ +/* random.c - part of the Libgcrypt test suite. + Copyright (C) 2005 Free Software Foundation, Inc. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 + USA. */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <assert.h> +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <errno.h> +#include <signal.h> +#include <unistd.h> +#include <sys/wait.h> + +#include "../src/gcrypt.h" + +static int verbose; + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + + +static void +print_hex (const char *text, const void *buf, size_t n) +{ + const unsigned char *p = buf; + + fputs (text, stdout); + for (; n; n--, p++) + printf ("%02X", *p); + putchar ('\n'); +} + + +static int +writen (int fd, const void *buf, size_t nbytes) +{ + size_t nleft = nbytes; + int nwritten; + + while (nleft > 0) + { + nwritten = write (fd, buf, nleft); + if (nwritten < 0) + { + if (errno == EINTR) + nwritten = 0; + else + return -1; + } + nleft -= nwritten; + buf = (const char*)buf + nwritten; + } + + return 0; +} + +static int +readn (int fd, void *buf, size_t buflen, size_t *ret_nread) +{ + size_t nleft = buflen; + int nread; + char *p; + + p = buf; + while ( nleft > 0 ) + { + nread = read ( fd, buf, nleft ); + if (nread < 0) + { + if (nread == EINTR) + nread = 0; + else + return -1; + } + else if (!nread) + break; /* EOF */ + nleft -= nread; + buf = (char*)buf + nread; + } + if (ret_nread) + *ret_nread = buflen - nleft; + return 0; +} + + + +/* Check that forking won't return the same random. */ +static void +check_forking (void) +{ + pid_t pid; + int rp[2]; + int i, status; + size_t nread; + char tmp1[16], tmp1c[16], tmp1p[16]; + + /* We better make sure that the RNG has been initialzied. */ + gcry_randomize (tmp1, sizeof tmp1, GCRY_STRONG_RANDOM); + if (verbose) + print_hex ("initial random: ", tmp1, sizeof tmp1); + + if (pipe (rp) == -1) + die ("pipe failed: %s\n", strerror (errno)); + + pid = fork (); + if (pid == (pid_t)(-1)) + die ("fork failed: %s\n", strerror (errno)); + if (!pid) + { + gcry_randomize (tmp1c, sizeof tmp1c, GCRY_STRONG_RANDOM); + if (writen (rp[1], tmp1c, sizeof tmp1c)) + die ("write failed: %s\n", strerror (errno)); + if (verbose) + { + print_hex (" child random: ", tmp1c, sizeof tmp1c); + fflush (stdout); + } + _exit (0); + } + gcry_randomize (tmp1p, sizeof tmp1p, GCRY_STRONG_RANDOM); + if (verbose) + print_hex (" parent random: ", tmp1p, sizeof tmp1p); + + close (rp[1]); + if (readn (rp[0], tmp1c, sizeof tmp1c, &nread)) + die ("read failed: %s\n", strerror (errno)); + if (nread != sizeof tmp1c) + die ("read too short\n"); + + while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) + ; + if (i != (pid_t)(-1) + && WIFEXITED (status) && !WEXITSTATUS (status)) + ; + else + die ("child failed\n"); + + if (!memcmp (tmp1p, tmp1c, sizeof tmp1c)) + die ("parent and child got the same random number\n"); +} + + + +/* Check that forking won't return the same nonce. */ +static void +check_nonce_forking (void) +{ + pid_t pid; + int rp[2]; + int i, status; + size_t nread; + char nonce1[10], nonce1c[10], nonce1p[10]; + + /* We won't get the same nonce back if we never initialized the + nonce subsystem, thus we get one nonce here and forget about + it. */ + gcry_create_nonce (nonce1, sizeof nonce1); + if (verbose) + print_hex ("initial nonce: ", nonce1, sizeof nonce1); + + if (pipe (rp) == -1) + die ("pipe failed: %s\n", strerror (errno)); + + pid = fork (); + if (pid == (pid_t)(-1)) + die ("fork failed: %s\n", strerror (errno)); + if (!pid) + { + gcry_create_nonce (nonce1c, sizeof nonce1c); + if (writen (rp[1], nonce1c, sizeof nonce1c)) + die ("write failed: %s\n", strerror (errno)); + if (verbose) + { + print_hex (" child nonce: ", nonce1c, sizeof nonce1c); + fflush (stdout); + } + _exit (0); + } + gcry_create_nonce (nonce1p, sizeof nonce1p); + if (verbose) + print_hex (" parent nonce: ", nonce1p, sizeof nonce1p); + + close (rp[1]); + if (readn (rp[0], nonce1c, sizeof nonce1c, &nread)) + die ("read failed: %s\n", strerror (errno)); + if (nread != sizeof nonce1c) + die ("read too short\n"); + + while ( (i=waitpid (pid, &status, 0)) == -1 && errno == EINTR) + ; + if (i != (pid_t)(-1) + && WIFEXITED (status) && !WEXITSTATUS (status)) + ; + else + die ("child failed\n"); + + if (!memcmp (nonce1p, nonce1c, sizeof nonce1c)) + die ("parent and child got the same nonce\n"); +} + + + + + + +int +main (int argc, char **argv) +{ + int debug = 0; + + if ((argc > 1) && (! strcmp (argv[1], "--verbose"))) + verbose = 1; + else if ((argc > 1) && (! strcmp (argv[1], "--debug"))) + verbose = debug = 1; + + signal (SIGPIPE, SIG_IGN); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + + check_forking (); + check_nonce_forking (); + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/register.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/register.c new file mode 100644 index 0000000000..df90fe094c --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/register.c @@ -0,0 +1,187 @@ +/* register.c - Test for registering of additional cipher modules. + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> + +#include "../src/gcrypt.h" + +static int verbose; +static int in_fips_mode; + +static void +die (const char *format, ...) +{ + va_list arg_ptr ; + + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + exit (1); +} + +gcry_err_code_t +foo_setkey (void *c, const unsigned char *key, unsigned keylen) +{ + (void)c; + (void)key; + (void)keylen; + + return 0; +} + +#define FOO_BLOCKSIZE 16 + +void +foo_encrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf) +{ + int i; + + (void)c; + + for (i = 0; i < FOO_BLOCKSIZE; i++) + outbuf[i] = inbuf[i] ^ 0x42; +} + +void +foo_decrypt (void *c, unsigned char *outbuf, const unsigned char *inbuf) +{ + int i; + + (void)c; + + for (i = 0; i < FOO_BLOCKSIZE; i++) + outbuf[i] = inbuf[i] ^ 0x42; +} + +gcry_cipher_spec_t cipher_spec_foo = + { + "FOO", NULL, NULL, 16, 0, 0, + foo_setkey, foo_encrypt, foo_decrypt, + NULL, NULL, + }; + +int +check_list (int algorithm) +{ + gcry_error_t err = GPG_ERR_NO_ERROR; + int *list, list_length; + int i, ret = 0; + + err = gcry_cipher_list (NULL, &list_length); + assert (! err); + list = malloc (sizeof (int) * list_length); + assert (list); + err = gcry_cipher_list (list, &list_length); + + for (i = 0; i < list_length && (! ret); i++) + if (list[i] == algorithm) + ret = 1; + + return ret; +} + +void +check_run (void) +{ + int err, algorithm; + gcry_cipher_hd_t h; + char plain[16] = "Heil Discordia!"; + char encrypted[16], decrypted[16]; + gcry_module_t module; + int ret; + + err = gcry_cipher_register (&cipher_spec_foo, &algorithm, &module); + if (in_fips_mode) + { + if (gpg_err_code (err) != GPG_ERR_NOT_SUPPORTED) + die ("register cipher failed in fips mode: %s\n", gpg_strerror (err)); + return; + } + else + { + if (err) + die ("register cipher failed: %s\n", gpg_strerror (err)); + } + + err = gcry_cipher_open (&h, algorithm, GCRY_CIPHER_MODE_CBC, 0); + if (err) + die ("gcry_cipher_open failed: %s\n", gpg_strerror (err)); + + err = gcry_cipher_encrypt (h, + (unsigned char *) encrypted, sizeof (encrypted), + (unsigned char *) plain, sizeof (plain)); + assert (! err); + assert (memcmp ((void *) plain, (void *) encrypted, sizeof (plain))); + + err = gcry_cipher_reset (h); + assert (! err); + + err = gcry_cipher_decrypt (h, + (unsigned char *) decrypted, sizeof (decrypted), + (unsigned char *) encrypted, sizeof (encrypted)); + assert (! err); + assert (! memcmp ((void *) plain, (void *) decrypted, sizeof (plain))); + + ret = check_list (algorithm); + assert (ret); + + gcry_cipher_close (h); + + gcry_cipher_unregister (module); + + ret = check_list (algorithm); + assert (! ret); +} + +int +main (int argc, char **argv) +{ + int debug = 0; + int i = 1; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u , 0); + + if ( gcry_control (GCRYCTL_FIPS_MODE_P, 0) ) + in_fips_mode = 1; + + for (; i > 0; i--) + check_run (); + + /* In fips mode we let the Makefile skip this test because a PASS + would not make much sense with all egistering disabled. */ + return in_fips_mode? 77:0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/rsa-16k.key b/plugins/MirOTR/libgcrypt-1.4.6/tests/rsa-16k.key new file mode 100644 index 0000000000..017915a239 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/rsa-16k.key @@ -0,0 +1,18 @@ +(key-data + (public-key + (rsa + (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#) + (e #010001#) + ) + ) + (private-key + (rsa + (n #00D6007A7AD47BB8D6B356E4F24DFAEE3A722FEE77F7E9547F866CB369C233E6CB3916D416973E3157B4DC1837E6D4C907D1063855735EAA857176A7DA3CA9F378FF7AE9EF227C193965F106F35DB2A833D2760CF9F2D041938CD310D9CE38EDD179C33EBC4963A02221D8000FDBF4BEB592CAB1ED1EEEC9D6916F27263C76DE70184F5399DE3B3862227346B1B3FBA306174D08BEC3675E2593CFD42159655B0BE1A2B69C2BA9F4F03B8C6BA505F6BFDFC6163D74F42A6D4908284D6879CECCF6512F9225612E3030ACF3663DFB77B41AFFCFC70BC11B224E14B397D25AC15E4E342B34B363056EA76CB0265DBD41F733C7FDE98B7C2340289E338CD31F993ABFACA6E83B54BCB50DD1DD11165C188C80EBDA190A11B6D8982CDA1B6B9D1631AA3EACC93040237831A52D15826A0D3E92C833D0234975C92A7236F902FA6703C89C7779765020C11F714B4C9D33B76CD466DC2BE9A102488B0635F31E6FBB9282E5139D32623E10ED9C295DA3B39F68227218EDF8C6FE9372F174AE1DE5BBE7B0AF09A869CAEDBEFE05458BFD43CF32F10F5C345A2E3D588C8C16B4DA8B44FA9539C679B81133A35498696F5D866E3B6A89811AEA7BFD1BF690EC329D87989CDADA7EAB106785D2D6661BD400D76C113E28F13FD883027E1CAC848B13750C7CCD530273C165BDFDA93E6F72897E97F003308704B95801F223EE89160786B1DE440BA9C1F371CBA37E5B09650CDB3AA1ABAA237AD15B89DCD03390A28308643E219490BEC83403F6A09B94F81D7BB391C121FC9028A6908E5B287AC79209B905B33724B1869A679CB347BF192D80D2D66CF1DAEFEBBF22CEDB8CEC010D6F8D86CD055ED71425DA72DF1C07A573E6F070235C378DAB5404ED004B4946CCDA4786ACBBF379A47CC36A049C50651CA4B1CEF03EE87DB6D2484C3D10AF71798A6AD1E20780814F79348D45BD1004880D2DEDEBD152694C80B9F93DF32F5930911DB379B4CBB9230CFC5FC126B9B77F074B9C82BDB4F12471B3FE92079525FD276293B63B978B55E039024EE688180D7C7C6C094B754AB9B652AC31812F2F7E45EF2B6D4478D7C6E5C8F3CB0A4D04A3E693D1DD4D8F894E910D9A999DDABE0427A1AB0C715C5A695A69140B20B9DA1195E6C9536B5DF24B4D45ED24D0F2C276E3CF48066EFB977C2B7096B02EB52309D916BD432347D72799BF9D76A03D54DE211460017C0E268BC9E23B415ABF46EB8B939B5A413EBD3F20E95F704E1F2CDCDF974A8743923DBC6D8363DC8948BE85EF1D368CD3EABDBE5B82648D2F676EB310D7B77465D3A14B86050463E43AC745F3781E7A6F582BD7B8AB22BC4EEECD2CB155E6E0B2604843E3906D47EBDA2C10B6D8BFCBB5722CE5394EB50721E90EFD28C63A62269C8C14593D69076D0F198D2BDCCB6D753CB81C4BED56A90E2DDBFFC0B9076C65F973B5EA3242E71E3CBBFE0976CFE22475F56726058D2D0CE3BD52AA940A0F559DD055BE9A6F50846902E02B70DB4FF5BED33762E10409D25ABDACF661BD9BA2A22212E02893A1625CA44850887B4B3A00D0AF63645E2EC42333035062090E8E7E63037C692FBA0B3FC7F3686FC2831F4DE2D4D82CF6FD6321D6621C8227715E3772EE8805911AA9E67083C511F17863C4D6F2C29E19CF329200024E539A7C5BF1A9D601AFF8DB7CFD75C6532488469E44BAC7266A3C127720E640328F9970B75509E292CCEC0B55A1F729456CB2804BE50451185F8CDA313C7D4DF6C1C67D6C411025A2BFFF06C5062470F97B17E75B4F81CD1FEC777465D684849809B4281B690D2A8FE5C4FA87DB00328630FC31BFDDA4641B29CB434147806A614E450E3E2B50317E3B4EE6262A2D4D0A8FE7530CEDFBCB5016C4D6E61C34E61AFA324871A9C75F9BC6BF6C92B95910C9D0FE049AEEF2E96E4C9E69E1FCE1F6CC687D533668F55367E2695197BE392A7FE66C4F88C0B1A9DEC6DFF682675855979DEA2A5644748DD882CE1F0D8FDA8530617BAA130AD9C16ABF8D76B5853104AD2E0C54C9639C3F6E1343AC94139621245EE8E12CA4366A6EC752BD9D1A0948CCC3626CEDB882BA4638115BBF55444DD4544EEC561F0E762C9989A9306D4749ABD47C31F40AD3F735FEEE6E1FDCEB626073CD5F76730B348103B041B9EEB941EFA61581DD9278802A2934C33FF0668C25CEF2546C44263A68919ECBB540B4A18E1867EA15C9F7A2853F55EFBB01C3D27D28579E030D0A771B754680FCD46B56EBD3431C24F202A343E20294076E56A09FA5F6C3E844DAF5BDCFBFF55CCC3FDDDB060FBC680BA520153098E57FC7741D77DFA8932F9028D8E0E66600974A41DAC5BBA4690407AC36EC206655ADCECC8AA0471601F67C3DF48B830585FA15C52061C4FF958453B1E75626120CDC0ADCE44743027FA4C59C1931E90726CD2BE240D0DC6D61CDE5165350D86FFF17260A823C0AE3467A597D774A67BE843951975E17BC1CB69DC8A0C7BFF799FB8FD2BDB37853D2EB28C9B7B8A2212FC73FDF2F21FF3FBCD798533FC4867739E48BA061B174BAC224064F3E867A1CF52E091FDD36871955FBEA90CD3D23B1BF0039930E0636080E6A36206ED5DD1CE4546EC0B0802BBEE2869DCCAEA01B8FC3A6392820180AA4D99AB67C57E8FD0874E7C54BBC7B9A2AA4D1EA4ADC1A2802DF908AF74F915AF98EEEBF822AC958CD0D9AF5A754AB2F4790225F18864A94734E526BDE497FF21F3392472D4F0E3B7E2EE97DDCA15060BF35A05E2593418809D3C9738C328EB4D44F35E6C913069096B0742809F55F01D06D40EB0476C34950FDAEF9BD2CC1F7653B4BCF1AA304963530C8F0C39697EAD32ADF464E3CAC931D33992B357A3A231FB978A56C3592A61411A5428C3549A991D811#) + (e #010001#) + (d #0125A7ED14E014111AE2BD8FD81A69B0BDED886DBE477D9CC08C6B07F1F82BD5BD73797FF9FFFB0D2542BE97FD1DCE9FE30F516F117DB449B513C85EF779DC91DD57B6B2E1BDD077A1EBE148486C2ADC8FEAC7FE1BD40BDD45E6833B26FB75388D05293177EE12678B197B42EFD59A38985B4BB471A3761E41F1BA8AB3A2AFA5A241B999096B8A9809BC7C5DBB3BDF476049AE7671A47213C9922B7E4C1A5545BA92C555100DB00AB77254C8E1DFC283F3EDE901819B611CD5E551133D14E8FD18840F6331D29E2EED47118E7094C1E36E53DA2AA90133856A351367224B51F80C184A5C3C4CDA5CC822126B3DF696AE96BFB8B836FA56E4E8D7D8A545E5F668F23203AC6968BE0A8A0C3BEEAC0AC9CFAE994B8EA5E293A5B9817D49B89761528595BB99D83C2B1AA4054FA2FF1D1D4F8ADBC3E863D8F4BD8C76C38E057D81740FB4FB12BC3CF80AB510223934FE8D3FD461D17E9B4EA07380A7E5202DD93A40B1F2E6C2048160949A247AC9A3F962A4E2F4EE809F00C76AF8DA4737D1398E6A95BE4637C949A33492C9691B254EB239EA7B1EC0E2D4261A27183F90577F04B356FD10FDB5E23A4471068952930EAFF4EDC757ACE25781DBA807A0C153FEDDCCB55A08B774AB44AD2CC75BD319D4822BFC6AF24C9F837C72D1A615109882906ADC2B2C679630A6FAE363144B77A134F2856DF1D8E9A77AAEC08A72FD67C122BD280D591A6C4045D0497362FB91C8C38C00A457A0BBE8D625210E4BF55FC4041FBE0A1515B70EA98C4F4284B3C96C15DD21C8CC15305DB5BFA2C21EB9520C9ACD823F5E7ABCDA3993D89A7B561C101FEC08A8AE6621245CAA1406D7536FBC6E835692D2B1BB540B8F2B2EAB7A1406B2FE83873CDEDFB0A0E717A037CD3A6322AE0B6F5E36187646866A0D406F7F54007FEC9711311BCE87FC6B4F44C5D1F7BEDD2DED081F1439F38312FA27CB65665B1595F88713378797AB624C728CA6632653EC8E762A76E3E597AAD4C3C3FE41648AEB07FCB8BFE9C70A1818E4F1B19124BECD320E4CDA6A9FD02B0A422114B5DE31376549C3B5FE1A896F8FCB256B814BD100FFBF5359510D8FD243DB014DBCFA3036C857A41DCBAE29ECE25012AF0B88827A1B3F3FA6E75EDF1790B0CCD794D0E733315743EF50FA18E5E1A93DC5D1EB28F555C0A8541B729954EA1865C6FDBE810D153CB50C024E8E7A59D324C22B626A30F4AAA0FA46EDCA4CC42F4B2D033B147DA54A67D103633A88EBFFF0EFFB61AA98DD2B057700FAC0986A9FB27C2CC29EE30B699DE063C76A1E2863D13951C35C5ABD357555781D2A5E68B0BFACF2E11747006E0810DD0CF97D585318A3B0DF7A67465EC3761004AA9B7C141B4E5444D9EB649BBD94F983FCFAEC982D994C7A620DE2D8AEE012BFD22AA9322F3DD3BD5CE90C17660D18F8CB679B02BDABC0D4D0F876B0DD6D258E08DC50B35544A4BDBE5F75604493D5FDF98B7FB812475C7B7122DDEC512322E1855C31105397AF284B7C2B4DC315D2E8D5017BBD2400885D5EB6C321B5093EF98A14EB4C29DC2B7DF9565D9E23A2BE6A2E334CE3485A8677E463DD86F49E3B56D2974F7D930FFDD60BA54AB49AE9DCDC588A4FC7AFCDB89A7713C51FA97BFA8868EE207C3C0032FDB302E45DFA0DFD8A2DE4D50A959A424626CC92CE74F8A2627C3B20406D714BB64825FBAE1B44A2F7569E32A8CBB41DBA3D9115691B07C3951A2D1394BF06BB0690B710D438CCC4E5B92B0CF302109A60C836E3AB40E4D3579C2E1C77F432C62925A751D92A564440A563B3C373D9A46FFCB0EB478962450C11192FDE187718F9AEDFF61DFE39AE98714B1DD49C356593F23F2BADE0E753B25BDCB3D618E3CDC5C5D8F37974A449E6E2D21B46FA90435F399AFF98988DEA9048B8031E1AE2E4B2B7C3FBB7CA775B6058500DB8852FF7358251CBF12A3CA233719760D251939A29778D7B4BDE15B5244B8AB47555C18925222331443DD6B227282A101443F14851734796FF4E323B66ED8304E594973EDBCA57B9413BB83574673623CB9BA282F92FBE49BFC7D6D18644C1741DAFEE86B58A174AA1B576F2599CAA8F15C9AC513CCC3778EAB81D6EF90557E73E207E96BC2D83BD3FED3717B0E8E527AE27BD05B28962280099AD1AF8C8D0B0E668EDC73AB3BD7E21C9C9134BFBC837BBC8E68FE8DF48365491371D378CB768A24A956F0D625D47EDBBAB051E4B4EE5D59574A4F2C4371D491ED182CD945DDAF11EB17382A58F2AFB6B79DE3EA1636C67449340F77A1CF14DFEDCB42B18BFFB866DD007B9A606C7BAEA70F9C5EAC98CBB52ECE5932F2925ACEAAE412E6114090CB54145A751E430EF1CA3A418C4D76EA7D797FF882401FD21984F4FBC347C4BFBB5B2B946B65F4FE0C7B9E5E16CBC1B6612325A0C83A8740D5D885C443EB8D02289BFC72E3BD2925E599B863F117C8A32E81F4B6F2C0C5D8CEA6E75C03E564E3F8D1663B5F3D21D844B6F80FB982484809303019670115FF5CC5FF6681E1C9B9AB01EA719AECAB7A4C4F1044017449741C726A4D1D97D0FB0D390F37DE0F838038270AEDD5E058113252D4F8E91B1377FD24F528EEDF58AE575327BE17F4A9D68E24B39DDF1187C8ABCEB1A84AB6BAB0735F3756E512641E62D3B51DF0316D065949379DD06C07606A82126A129A2A70F91EF54096CFCBC3447B49D5DD5F7DC7AA9F3E86E8ECD581F51731DF726194CD3143CC1E608AE882EA8848CDFD9F3FF6282AC6D722C2D5F51F2652724FEB601E02E1F078E32B36892ED9E2DE0A637836A005B01CEFDADF90534049565E8B965224B3E7EFF5707F3DEB6BFDB8D8045549168CD1C81910E584978A555DE877CFBDCB8D7388D3081F9DD8067198562521FEE99C57E3401#) + (p #00E6BBCBEBFCA813CED7907F5FA73C4C2D3532AF7A7650C4A88563DF805D54D0CEA528347A60F703C8FFE91997505F8C238383E03C53DFD347D0E385A5CFFE4E2A944DD45ACBC481D54D7B22F4C59A2BFC8C686E527B907AD9C5ECE870D102550D8D4A02B404DAE7023CC8F0436DE5F50A7CE1F4E741147F676B5DC9437CB47727B93155AE5C1EBE236E9F436D723FF770104305A1460C21BE9361582CB107CAF036F0600BCC6D78DE73C1F44C25F377B9A65349E9B73C446E5C6281DCB68EC65AF684AB39F6C84CF96E4CD909B61FA2D8BBB69A7994B78865FFEACD3838F851C944039C2422B75AE4F9C2A1702B005641EB41CE9FB042757E86F6E9651428EBA4D908D60A99AD61E5D09E7A05C7E59A9615DE965200CFB75A228B1D5DB8D2C040A65D940D5516C9FC5069B94D2F1903EF6B07F70ECF3E8D720F74139A4647D79131835CF7F15EA839350A00BD9D733359503497BCE39A2497CACCAD41B0AE7A36E6F01FECA1B0B062F9C3232BD6F6734C97DB2EE7DE050370087210F8161B07237E712E29E0BA6B2B661EC22DAD0509D50EF75255D40B954D2B3694C30E5982EB2D15B72A8709BC4F9B6FEFC4E6F01FF04D128311209B4C4353AF43BDE58D631DB7E047D7B469CDE4A9176415F6F7B60BC129E0BA8363D77140DA0FC685DB76FCB968C8C58657DB86FC908E7D11F41D907CA367C17AD3EF81280721FD40E6AEDC118538AFE109B8FA818502982578BB2EAE3ACC3028EF79C4CAB575CC8473E05FF5D911186058BCA7F5269FAA66CBB68CE47EE0748F2A8E52EEB8475030D34E54C365572BA282226730ADA3BEF16D582A409F15AB89188F1737F7CA82EE0D96BD2B3A2153CDF6EE27FD04F4AEF4AA3FC6EB02E92EC21359864507EAD3E09D3117EEDD61AF34265412C362EE01B26B925BC74A2679A1C112C653AE88FD124220742A05DDCB1CDE7DF2342669FDF76E1C3F9BF8FE13633ADF33050FA491FA708A918ECA787FF074E90F9A0AA216ACB1160D22BE7A9817DEF5FA2E27FC906ACF5B5774A5DB069A66F5F1752D7521E1CE49F8888218BA24C97A92C287DAB8B08B4433EC1DDEB5C7A3D96956EBCC46A2DE2B95CACA91BECBCB15DCA20D13C977F50F6DC0D705DB78B597581F850E20E0EEB6EA9A7A9D2708A650A3CD0748EE1DDAEA559C80D2A00F2DBD29C3EF58C13CB0B84AFA30C508BC8AD71A4FC3E14690F16B52943013D7BB09F5627D7D1343DAED88198D5ADA23E0B94484E06A827FE49227540110ECEC9E354F87E27496B7FF5ED31521817C8B5B182129EE0C521C85A996BF5EAF1F87583BDFE69386EDCE63337252F58D37AEC742702D97F3B97CE0FD06EE60EE4380C2E48D7AAD49E26F76CE981237ADB617B0BB6D59DAE31B6335866E7F9670F8A25D9BC44D7C32602BA3D58002BD53473E3F781249AB17C1C78C496611#) + (q #00ED6FA36442A240865581B5C398C93F55AFD5386A801AF1D8BF8A9FF8AB9C578F97DA02AFC44180AB581A1E10A4D65B7D1E9C0B04D57FB1FD13B7ECF1AD7C0296F1F5D52C3223CB117E6C6BED1FDA701A7A4079FBD35B180D2295B216FEAB284F85594EDDDC179C9AAE6E6CA545D2FBCA308B0961B21A1B4A4E9DE27CF8D6922FC902C35313B05F0FFB5CC667E64E0706D5210D3919074B384CA5968359CBA5F4BCA096323AD48E2CDE9D25F08E2EF945A1DD46457F48B4BF8EBEC2DC3737CC09E333E30F17A3ACD19567A5C5D200E7A4303A97A893F0884ED3CD976B41C2BCEEF04D9FCE4F30218CC9AAE26FFC5749B10011B805ADA9C4857B691A7A820F2564DF5979F570F8D524DDE268F702891E9CCDBD9F821C2ECF27F60C795E743AC67CADB07D22D3A7BD322DA9C3E7A35AC6A35333F871FE6DE0162BA2A1F9565E411ADD424FF0727B2280BAFDDF522C272D3A2910EFE27F5590F8E0F6C38BEA1895A0893755F44BDF41FECF3BF3BA27C6D6F036A1AA70736DE71465FA78EA46F34341E05DE7AB37A5074B4E99E0BAB54D658629503E1242ACAFDE08721058F208D3F62FAE742D158CAE521994514CF0BEC580F075046319FBFC8E971F0FF5EED9E2AB7D194CD21ECCCB2E54D239AA3B0254F4AB1641E6E8E1512FF1D1ED579205F1807898828CFA24B80D230FA6C52C6A92348E1A069C239F7B6F2E7CC995BD3CD1B413FC86C626FE962C7EC3CF19FA193B3A732AF17E51E6B57CC263DE82A5C45CB9E37C2BAB44E88E5792FBBC40748F86134D221BF775E2BF57F98A884FCBA494718661A3FF73AAE04A6F5CDFB6F143D680D09BA4CCD6C6F186E92569B8F67A35B5796B9F2ED404F11C54ED290D7D7836501473F06D8A623D53AB586B644F3F5BDF8B0B670CA696A23B7B52319C91D2CA27FCDF421030CEA8A6B079FEC2E467BE0427AFCEA12648F3E12F09745166D20D3D1CD6965EABA2732469C077B3C4E44D3503D882937DA5139076144FAEAB75083BF4E16725BB9625A99DE92F6F226DE343F73E974577F8D6F5B57CFBEB60763627240A28C90A73BC7A9E47D74CBABB6486988C983A5A3DC91A4D8E353AE6C608499D21391E32D8EF3A030925959B52C1BC03F17AAE2FEE4E28B2B51889EC2A5FE587C60139C9CF29AF46555B089B54B5EF0BB3B92BCC0EA0E6E94F944FE8E9741DDA902F185E0D16876A10351AD22FE6ABD4378AD74A13CD2BD9696F0B59A069CD6582F92458A89B15648E833614598D6FDABAC026791CDB3FA87873CA86E3DF7187C9230AFFB1089EF83B8CB54856ADC234D07DF479514A8F47EC9903930E47F9E93AE1F96D7358F4208E19CCED8AEC063AFE8A31E39C921F7D7867D57E8F68B1494793E6DCD06F3DC68809BD455DBB44076D6AB64586E0A09A42CEBA2829A5F81BDEA5EDB23DC251D69C373D2E275201#) + (u #00EA2CBBEFBFFBD4BD3850584AEA315F88ED892F7398E5C4ECD17F8E4588B073DA32AC708DADC0E55417553FB4DC25130F42A9A04E435C63E1091744232D53FF98ABA450E3B91AF512631E28BF453BE4FCB9713112F890F368523FE175B0909385F0B404B3E6370FA6DB33490DC216CE3DE548FDDF68C81FE49BB9683C30FA6D1DE8B019A94683E508B720F2EDA20133325FD4644620D086182F1E8283215D2BCBBC1B302DEA714CE1E59FE8E996489018078F8CCDDAEF086EFDF82BA45DF424E539ABC9D61ABEC14346275AA9256031514AAC59FF40C7D1B4363AC7C74E8CC3854C9E57F6913C2CFC599E9DBB446D553482C9B531563A7CADD562D64151B3961FB52A0D542406D491F8090EBB737C388016F95918313C0EC987F701F2A25AE3F0CEF2B9F3460A9E48AEE382F01CB09B0A9372104FAC2EE692BB2B14E6FE376A29891687E157C40F09FB3283402E4D319C9791E7A06025C542B4411EEA71890D22E34E8038B3002AC7FB75A50ED29AAEAFF36588950A06A8D2139B0420673DCB37087E8196A034D0A5C78A824BCD0A74BBD7E08B04B8F08F473C09F6350508CEB476DEE1E41D0CF960CA3E87AE8489811577F7D49CB1EF885453F7087B8126FB99028B5771EC9E159040109102DEE175DAFA038EE7B62B96797E56E6361C37DFC42398020114765E28C3F3B4B6A4C33A86A995A0D5647068B7147552F4E6130866527D4833949E9F9204406F096735F33BFD1BB57734E15D0B4035A37CCA7C897C18162B12951A684F586F1B7FF041A85B7F44FAC125A80AC782AD3F4D7EC52C318EEA52CFA6AF09EBA50813B5BAC8367B1FF80A99DB8BDEC3E3842455A06D22DA99F0BE5B52330D1D5C0CCACB3661D703BE1D96E7832A159C8858E08CC23101FBC0DE783D3209A80A3ED4EBCF57661B01D84EBCFBE70A0EC921588B8CD9B9BF21918D86C3C97B0F6BBF4037E80C99A349A1A2B78F337CC4029415FF0DB54AC9A3A1DF7E07482DC9F04E638C9D5BBAAD32A627F2EF1DC3E17AEC365E416C703C449AA40104DEC358202F7F78CCF77115ADAD567CDAE6B4B2C81DA4FBE6A97BBF2A704389911E4A5B39C3C1F187101E53B3DF7A0CE05C4B7956F4ED31DD225B46036C5344B3CDB236E5B1A12E159008D106D1CF6C14C5F7335A4A5D80E008F0106F636EF750723B50511F37B3BA6FFBEB27A270828B9CB123D7F59EA0BE956C0D024C77AC06086460998F18610ECB94651DF47AB37DDDCDB9797203A4321CBC1E6E85EC64919EB74AC7E2F3C15FEB5DFCCFC2359D353C8B6B600152D4211A55477FF31026B34C10C5F1FC1A1DD1C1EF6A14B26CFD1AF70D6BAA4461B4387631E4DCFDFFAB118F710A8B8B2D12EEC4924751720B9AA9D94527B9F19E8B352222567F662FC6753AA4BE22C2A851F2378AD5EE5539C1E0F4DD90400DD7DC6F1EA675D9#) + ) + ) + ) diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/t-mpi-bit.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/t-mpi-bit.c new file mode 100644 index 0000000000..aaad0f1d66 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/t-mpi-bit.c @@ -0,0 +1,361 @@ +/* t-mpi-bit.c - Tests for bit level functions + * Copyright (C) 2006 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, + * MA 02110-1301, USA. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +#define PGM "t-mpi-bit" + +static const char *wherestr; +static int verbose; +static int error_count; + +#define xmalloc(a) gcry_xmalloc ((a)) +#define xcalloc(a,b) gcry_xcalloc ((a),(b)) +#define xfree(a) gcry_free ((a)) +#define pass() do { ; } while (0) + +static void +show (const char *format, ...) +{ + va_list arg_ptr; + + if (!verbose) + return; + fprintf (stderr, "%s: ", PGM); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); +} + +static void +fail (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + error_count++; +} + +static void +die (const char *format, ...) +{ + va_list arg_ptr; + + fflush (stdout); + fprintf (stderr, "%s: ", PGM); + if (wherestr) + fprintf (stderr, "%s: ", wherestr); + va_start (arg_ptr, format); + vfprintf (stderr, format, arg_ptr); + va_end (arg_ptr); + exit (1); +} + +/* Allocate a bit string consisting of '0' and '1' from the MPI + A. Return the LENGTH least significant bits. Caller needs to xfree + the result. */ +static char * +mpi2bitstr (gcry_mpi_t a, size_t length) +{ + char *p, *buf; + + buf = p = xmalloc (length+1); + while (length--) + *p++ = gcry_mpi_test_bit (a, length) ? '1':'0'; + *p = 0; + + return buf; +} + +/* Allocate a bit string consisting of '0' and '1' from the MPI A. Do + not return any leading zero bits. Caller needs to xfree the + result. */ +static char * +mpi2bitstr_nlz (gcry_mpi_t a) +{ + char *p, *buf; + size_t length = gcry_mpi_get_nbits (a); + + if (!length) + { + buf = p = xmalloc (2); + *p++ = '0'; + } + else + { + buf = p = xmalloc (length + 1); + while (length-- > 1) + *p++ = gcry_mpi_test_bit (a, length) ? '1':'0'; + *p++ = gcry_mpi_test_bit (a, 0) ? '1':'0'; + } + *p = 0; + return buf; +} + +/* Shift a bit string to the right. */ +static void +rshiftbitstring (char *string, size_t n) +{ + size_t len = strlen (string); + + if (n > len) + n = len; + + memmove (string+n, string, len-n); + memset (string, '0', n); +} + +/* Shift a bit string to the left. Caller needs to free the result. */ +static char * +lshiftbitstring (const char *string, size_t n) +{ + size_t len = strlen (string); + char *result; + + if (len+n+1 < len) + die ("internal overflow\n"); + /* Allocate enough space. */ + result = xmalloc (len+n+1); + for (; *string == '0' && string[1]; string++, len--) + ; + memcpy (result, string, len); + if (*string == '0' && !string[1]) + n = 0; /* Avoid extra nulls for an only 0 string. */ + else + memset (result+len, '0', n); + result[len+n] = 0; + return result; +} + + +/* This is to check a bug reported by bpgcrypt at itaparica.org on + 2006-07-31 against libgcrypt 1.2.2. */ +static void +one_bit_only (int highbit) +{ + gcry_mpi_t a; + char *result; + int i; + + wherestr = "one_bit_only"; + show ("checking that set_%sbit does only set one bit\n", highbit?"high":""); + + a = gcry_mpi_new (0); + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + gcry_mpi_set_ui (a, 0); + + if (highbit) + gcry_mpi_set_highbit (a, 42); + else + gcry_mpi_set_bit (a, 42); + if (!gcry_mpi_test_bit (a, 42)) + fail ("failed to set a bit\n"); + gcry_mpi_clear_bit (a, 42); + if (gcry_mpi_test_bit (a, 42)) + fail ("failed to clear a bit\n"); + result = mpi2bitstr (a, 70); + assert (strlen (result) == 70); + for (i=0; result[i]; i++) + if ( result[i] != '0' ) + break; + if (result[i]) + fail ("spurious bits detected\n"); + xfree (result); + gcry_mpi_release (a); +} + +/* Check that right shifting actually works for an amount larger than + the number of bits per limb. */ +static void +test_rshift (int pass) +{ + gcry_mpi_t a, b; + char *result, *result2; + int i; + + wherestr = "test_rshift"; + show ("checking that rshift works as expected (pass %d)\n", pass); + + a = gcry_mpi_new (0); + b = gcry_mpi_new (0); + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + + for (i=0; i < 75; i++) + { + gcry_mpi_rshift (b, a, i); + + result = mpi2bitstr (b, 72); + result2 = mpi2bitstr (a, 72); + rshiftbitstring (result2, i); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("rshift by %d failed\n", i); + } + xfree (result); + xfree (result2); + } + + /* Again. This time using in-place operation. */ + gcry_mpi_randomize (a, 70, GCRY_WEAK_RANDOM); + + for (i=0; i < 75; i++) + { + gcry_mpi_release (b); + b = gcry_mpi_copy (a); + gcry_mpi_rshift (b, b, i); + + result = mpi2bitstr (b, 72); + result2 = mpi2bitstr (a, 72); + rshiftbitstring (result2, i); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("in-place rshift by %d failed\n", i); + } + xfree (result2); + xfree (result); + } + + gcry_mpi_release (b); + gcry_mpi_release (a); +} + +/* Check that left shifting works correctly. */ +static void +test_lshift (int pass) +{ + static int size_list[] = {1, 31, 32, 63, 64, 65, 70, 0}; + int size_idx; + gcry_mpi_t a, b; + char *tmpstr, *result, *result2; + int i; + + wherestr = "test_lshift"; + show ("checking that lshift works as expected (pass %d)\n", pass); + + for (size_idx=0; size_list[size_idx]; size_idx++) + { + a = gcry_mpi_new (0); + b = gcry_mpi_new (0); + + /* gcry_mpi_randomize rounds up to full bytes, thus we need to + use gcry_mpi_clear_highbit to fix that. */ + gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); + gcry_mpi_clear_highbit (a, size_list[size_idx]); + + for (i=0; i < 75; i++) + { + gcry_mpi_lshift (b, a, i); + + result = mpi2bitstr_nlz (b); + tmpstr = mpi2bitstr_nlz (a); + result2 = lshiftbitstring (tmpstr, i); + xfree (tmpstr); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("lshift by %d failed\n", i); + } + xfree (result); + xfree (result2); + } + + /* Again. This time using in-place operation. */ + gcry_mpi_randomize (a, size_list[size_idx], GCRY_WEAK_RANDOM); + gcry_mpi_clear_highbit (a, size_list[size_idx]); + + for (i=0; i < 75; i++) + { + gcry_mpi_release (b); + b = gcry_mpi_copy (a); + gcry_mpi_lshift (b, b, i); + + result = mpi2bitstr_nlz (b); + tmpstr = mpi2bitstr_nlz (a); + result2 = lshiftbitstring (tmpstr, i); + xfree (tmpstr); + if (strcmp (result, result2)) + { + show ("got =%s\n", result); + show ("want=%s\n", result2); + fail ("in-place lshift by %d failed\n", i); + } + xfree (result2); + xfree (result); + } + + gcry_mpi_release (b); + gcry_mpi_release (a); + } +} + + +int +main (int argc, char **argv) +{ + int debug = 0; + int i; + + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + else if (argc > 1 && !strcmp (argv[1], "--debug")) + verbose = debug = 1; + + if (!gcry_check_version (GCRYPT_VERSION)) + die ("version mismatch\n"); + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0); + if (debug) + gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0); + + gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0); + + one_bit_only (0); + one_bit_only (1); + for (i=0; i < 5; i++) + test_rshift (i); /* Run several times due to random initializations. */ + + for (i=0; i < 5; i++) + test_lshift (i); /* Run several times due to random initializations. */ + + show ("All tests completed. Errors: %d\n", error_count); + return error_count ? 1 : 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/testapi.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/testapi.c new file mode 100644 index 0000000000..e14ae7b537 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/testapi.c @@ -0,0 +1,112 @@ +/* testapi.c - for libgcrypt + * Copyright (C) 2000, 2002 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser general Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <gcrypt.h> + + +#define BUG() do {fprintf ( stderr, "Ooops at %s:%d\n", __FILE__ , __LINE__ );\ + exit(2);} while(0) + +/* an ElGamal public key */ +struct { + const char *p,*g,*y; +} elg_testkey1 = { + "0x9D559F31A6D30492C383213844AEBB7772963A85D3239F3611AAB93A2A985F64FB735B9259EC326BF5720F909980D609D37C288C9223B0350FBE493C3B5AF54CA23031E952E92F8A3DBEDBC5A684993D452CD54F85B85160166FCD25BD7AB6AE9B1EB4FCC9D300DAFF081C4CBA6694906D3E3FF18196A5CCF7F0A6182962166B", + "0x5", + "0x9640024BB2A277205813FF685048AA27E2B192B667163E7C59E381E27003D044C700C531CE8FD4AA781B463BC9FFE74956AF09A38A098322B1CF72FC896F009E3A6BFF053D3B1D1E1994BF9CC07FA12963D782F027B51511DDE8C5F43421FBC12734A9C070F158C729A370BEE5FC51A772219438EDA8202C35FA3F5D8CD1997B" +}; + +void +test_sexp ( int argc, char **argv ) +{ + int rc, nbits; + gcry_sexp_t sexp; + gcry_mpi_t key[3]; + size_t n; + char *buf; + + if ( gcry_mpi_scan( &key[0], GCRYMPI_FMT_HEX, elg_testkey1.p, NULL ) ) + BUG(); + if ( gcry_mpi_scan( &key[1], GCRYMPI_FMT_HEX, elg_testkey1.g, NULL ) ) + BUG(); + if ( gcry_mpi_scan( &key[2], GCRYMPI_FMT_HEX, elg_testkey1.y, NULL ) ) + BUG(); + + /* get nbits from a key */ + rc = gcry_sexp_build ( &sexp, NULL, + "(public-key(elg(p%m)(g%m)(y%m)))", + key[0], key[1], key[2] ); + fputs ( "DUMP of PK:\n", stderr ); + gcry_sexp_dump ( sexp ); + { gcry_sexp_t x; + x = gcry_sexp_cdr ( sexp ); + fputs ( "DUMP of CDR:\n", stderr ); + gcry_sexp_dump ( x ); + gcry_sexp_release ( x ); + } + nbits = gcry_pk_get_nbits( sexp ); + printf ( "elg_testkey1 - nbits=%d\n", nbits ); + n = gcry_sexp_sprint ( sexp, 0, NULL, 0 ); + buf = gcry_xmalloc ( n ); + n = gcry_sexp_sprint ( sexp, 0, buf, n ); + printf ( "sprint length=%u\n", (unsigned int)n ); + gcry_free ( buf ); + gcry_sexp_release( sexp ); +} + + +void +test_genkey ( int argc, char **argv ) +{ + int rc, nbits = 1024; + gcry_sexp_t s_parms, s_key; + + gcry_control( GCRYCTL_INIT_SECMEM, 16384, 0 ); + rc = gcry_sexp_build ( &s_parms, NULL, "(genkey(dsa(nbits %d)))", nbits ); + rc = gcry_pk_genkey( &s_key, s_parms ); + if ( rc ) { + fprintf ( stderr, "genkey failed: %s\n", gpg_strerror (rc) ); + return; + } + gcry_sexp_release( s_parms ); + gcry_sexp_dump ( s_key ); + gcry_sexp_release( s_key ); +} + +int +main( int argc, char **argv ) +{ + if ( argc < 2 ) + printf("%s\n", gcry_check_version ( NULL ) ); + else if ( !strcmp ( argv[1], "version") ) + printf("%s\n", gcry_check_version ( argc > 2 ? argv[2] : NULL ) ); + else if ( !strcmp ( argv[1], "sexp" ) ) + test_sexp ( argc-2, argv+2 ); + else if ( !strcmp ( argv[1], "genkey" ) ) + test_genkey ( argc-2, argv+2 ); + else { + fprintf (stderr, "usage: testapi mode-string [mode-args]\n"); + return 1; + } + + return 0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/tsexp.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/tsexp.c new file mode 100644 index 0000000000..21d54a62f9 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/tsexp.c @@ -0,0 +1,456 @@ +/* tsexp.c - S-expression regression tests + * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc. + * + * This file is part of Libgcrypt. + * + * Libgcrypt is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * Libgcrypt is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> +#include "../src/gcrypt.h" + +#define PGMNAME "tsexp" + +static int verbose; +static int error_count; + +static void +info (const char *format, ...) +{ + va_list arg_ptr; + + if (verbose) + { + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + } +} + +static void +fail ( const char *format, ... ) +{ + va_list arg_ptr ; + + fputs (PGMNAME ": ", stderr); + va_start( arg_ptr, format ) ; + vfprintf (stderr, format, arg_ptr ); + va_end(arg_ptr); + error_count++; +} + + +/* fixme: we need better tests */ +static void +basic (void) +{ + int pass; + gcry_sexp_t sexp; + int idx; + char *secure_buffer; + size_t secure_buffer_len; + const char *string; + static struct { + const char *token; + const char *parm; + } values[] = { + { "public-key", NULL }, + { "dsa", NULL }, + { "dsa", "p" }, + { "dsa", "y" }, + { "dsa", "q" }, + { "dsa", "g" }, + { NULL } + }; + + info ("doing some pretty pointless tests\n"); + + secure_buffer_len = 99; + secure_buffer = gcry_xmalloc_secure (secure_buffer_len); + memset (secure_buffer, 'G', secure_buffer_len); + + for (pass=0;;pass++) + { + switch (pass) + { + case 0: + string = ("(public-key (dsa (p #41424344#) (y this_is_y) " + "(q #61626364656667#) (g %m)))"); + + if ( gcry_sexp_build (&sexp, NULL, string, + gcry_mpi_set_ui (NULL, 42)) ) + { + fail (" scanning `%s' failed\n", string); + return; + } + break; + + case 1: + string = ("(public-key (dsa (p #41424344#) (y this_is_y) " + "(q %b) (g %m)))"); + + if ( gcry_sexp_build (&sexp, NULL, string, + 15, "foo\0\x01\0x02789012345", + gcry_mpi_set_ui (NULL, 42)) ) + { + fail (" scanning `%s' failed\n", string); + return; + } + break; + + case 2: + string = ("(public-key (dsa (p #41424344#) (y silly_y_value) " + "(q %b) (g %m)))"); + + if ( gcry_sexp_build (&sexp, NULL, string, + secure_buffer_len, secure_buffer, + gcry_mpi_set_ui (NULL, 17)) ) + { + fail (" scanning `%s' failed\n", string); + return; + } + if (!gcry_is_secure (sexp)) + fail ("gcry_sexp_build did not switch to secure memory\n"); + break; + + case 3: + { + gcry_sexp_t help_sexp; + + if (gcry_sexp_new (&help_sexp, + "(foobar-parms (xp #1234#)(xq #03#))", 0, 1)) + { + fail (" scanning fixed string failed\n"); + return; + } + + string = ("(public-key (dsa (p #41424344#) (parm %S) " + "(y dummy)(q %b) (g %m)))"); + if ( gcry_sexp_build (&sexp, NULL, string, help_sexp, + secure_buffer_len, secure_buffer, + gcry_mpi_set_ui (NULL, 17)) ) + { + fail (" scanning `%s' failed\n", string); + return; + } + gcry_sexp_release (help_sexp); + } + break; + + + default: + return; /* Ready. */ + } + + + /* now find something */ + for (idx=0; values[idx].token; idx++) + { + const char *token = values[idx].token; + const char *parm = values[idx].parm; + gcry_sexp_t s1, s2; + gcry_mpi_t a; + const char *p; + size_t n; + + s1 = gcry_sexp_find_token (sexp, token, strlen(token) ); + if (!s1) + { + fail ("didn't found `%s'\n", token); + continue; + } + + p = gcry_sexp_nth_data (s1, 0, &n); + if (!p) + { + fail ("no car for `%s'\n", token); + continue; + } + info ("car=`%.*s'\n", (int)n, p); + + s2 = gcry_sexp_cdr (s1); + if (!s2) + { + fail ("no cdr for `%s'\n", token); + continue; + } + + p = gcry_sexp_nth_data (s2, 0, &n); + if (p) + { + fail ("data at car of `%s'\n", token); + continue; + } + + if (parm) + { + s2 = gcry_sexp_find_token (s1, parm, strlen (parm)); + if (!s2) + { + fail ("didn't found `%s'\n", parm); + continue; + } + p = gcry_sexp_nth_data (s2, 0, &n); + if (!p) + { + fail("no car for `%s'\n", parm ); + continue; + } + info ("car=`%.*s'\n", (int)n, p); + p = gcry_sexp_nth_data (s2, 1, &n); + if (!p) + { + fail("no cdr for `%s'\n", parm ); + continue; + } + info ("cdr=`%.*s'\n", (int)n, p); + + a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG); + if (!a) + { + fail("failed to cdr the mpi for `%s'\n", parm); + continue; + } + } + } + + gcry_sexp_release (sexp); + sexp = NULL; + } + gcry_free (secure_buffer); +} + + +static void +canon_len (void) +{ + static struct { + size_t textlen; /* length of the buffer */ + size_t expected;/* expected length or 0 on error and then ... */ + size_t erroff; /* ... and at this offset */ + gcry_error_t errcode; /* ... with this error code */ + const char *text; + } values[] = { + { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " }, + { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" }, + { 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" }, + { 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" }, + { 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"}, + { 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"}, + { 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"}, + { 2, 2, 0, GPG_ERR_NO_ERROR, "()"}, + { 4, 2, 0, GPG_ERR_NO_ERROR, "()()"}, + { 4, 4, 0, GPG_ERR_NO_ERROR, "(())"}, + { 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"}, + { 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"}, + { 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"}, + { 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"}, + /* fixme: we need much more cases */ + { 0 }, + }; + int idx; + gcry_error_t errcode; + size_t n, erroff; + + info ("checking canoncial length test function\n"); + for (idx=0; values[idx].text; idx++) + { + n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text, + values[idx].textlen, + &erroff, &errcode); + + if (n && n == values[idx].expected) + ; /* success */ + else if (!n && !values[idx].expected) + { /* we expected an error - check that this is the right one */ + if (values[idx].erroff != erroff) + fail ("canonical length test %d - wrong error offset %u\n", + idx, (unsigned int)erroff); + if (gcry_err_code (errcode) != values[idx].errcode) + fail ("canonical length test %d - wrong error code %d\n", + idx, errcode); + } + else + fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n", + idx, (unsigned int)n, (unsigned int)erroff, errcode); + } +} + + +static void +back_and_forth_one (int testno, const char *buffer, size_t length) +{ + gcry_error_t rc; + gcry_sexp_t se, se1; + size_t n, n1; + char *p1; + + rc = gcry_sexp_new (&se, buffer, length, 1); + if (rc) + { + fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc)); + return; + } + n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0); + if (!n1) + { + fail ("baf %d: get required length for canon failed\n", testno); + return; + } + p1 = gcry_xmalloc (n1); + n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1); + if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */ + { + fail ("baf %d: length mismatch for canon\n", testno); + return; + } + rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free); + if (rc) + { + fail ("baf %d: gcry_sexp_create failed: %s\n", + testno, gpg_strerror (rc)); + return; + } + gcry_sexp_release (se1); + + /* Again but with memory checking. */ + p1 = gcry_xmalloc (n1+2); + *p1 = '\x55'; + p1[n1+1] = '\xaa'; + n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1); + if (n1 != n+1) /* sprints adds an extra 0 but does not return it */ + { + fail ("baf %d: length mismatch for canon\n", testno); + return; + } + if (*p1 != '\x55' || p1[n1+1] != '\xaa') + fail ("baf %d: memory corrupted (1)\n", testno); + rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL); + if (rc) + { + fail ("baf %d: gcry_sexp_create failed: %s\n", + testno, gpg_strerror (rc)); + return; + } + if (*p1 != '\x55' || p1[n1+1] != '\xaa') + fail ("baf %d: memory corrupted (2)\n", testno); + gcry_sexp_release (se1); + if (*p1 != '\x55' || p1[n1+1] != '\xaa') + fail ("baf %d: memory corrupted (3)\n", testno); + gcry_free (p1); + + /* FIXME: we need a lot more tests */ + + gcry_sexp_release (se); +} + + + +static void +back_and_forth (void) +{ + static struct { const char *buf; int len; } tests[] = { + { "(7:g34:fgh1::2:())", 0 }, + { "(7:g34:fgh1::2:())", 18 }, + { +"(protected-private-key \n" +" (rsa \n" +" (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n" +" (e #010001#)\n" +" (protected openpgp-s2k3-sha1-aes-cbc \n" +" (\n" +" (sha1 #C2A5673BD3882405# \"96\")\n" +" #8D08AAF6A9209ED69D71EB7E64D78715#)\n" +" #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n" +" )\n" +" )\n", 0 }, + { NULL, 0 } + }; + int idx; + + for (idx=0; tests[idx].buf; idx++) + back_and_forth_one (idx, tests[idx].buf, tests[idx].len); +} + + +static void +check_sscan (void) +{ + static struct { + const char *text; + gcry_error_t expected_err; + } values[] = { + /* Bug reported by Olivier L'Heureux 2003-10-07 */ + { "(7:sig-val(3:dsa" + "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" + "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" + "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" + "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))", + GPG_ERR_NO_ERROR }, + { "(7:sig-val(3:dsa" + "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" + "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" + "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" + "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))", + GPG_ERR_SEXP_UNMATCHED_PAREN }, + { "(7:sig-val(3:dsa" + "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64" + "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)" + "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d" + "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))", + GPG_ERR_SEXP_UNMATCHED_PAREN }, + { NULL, 0 } + }; + int idx; + gcry_error_t err; + gcry_sexp_t s; + + info ("checking gcry_sexp_sscan\n"); + for (idx=0; values[idx].text; idx++) + { + err = gcry_sexp_sscan (&s, NULL, + values[idx].text, + strlen (values[idx].text)); + if (gpg_err_code (err) != values[idx].expected_err) + fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err)); + gcry_sexp_release (s); + } +} + + + + +int +main (int argc, char **argv) +{ + if (argc > 1 && !strcmp (argv[1], "--verbose")) + verbose = 1; + + gcry_control (GCRYCTL_DISABLE_SECMEM_WARN); + gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0); + + basic (); + canon_len (); + back_and_forth (); + check_sscan (); + + return error_count? 1:0; +} diff --git a/plugins/MirOTR/libgcrypt-1.4.6/tests/version.c b/plugins/MirOTR/libgcrypt-1.4.6/tests/version.c new file mode 100644 index 0000000000..03259af7e7 --- /dev/null +++ b/plugins/MirOTR/libgcrypt-1.4.6/tests/version.c @@ -0,0 +1,58 @@ +/* version.c - This version test should be run first. + Copyright (C) 2007 Free Software Foundation, Inc. + + This file is part of Libgcrypt. + + Libgcrypt is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 2.1 of + the License, or (at your option) any later version. + + Libgcrypt is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, + USA. */ + +/* This test should be run first because due to a failing config.links + script or bad configure parameters the just build libgcrypt may + crash in case MPI function for specific CPU revisions have been + enabled. Running this test first will print out information so to + make it easier to figure out the problem. */ + + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <stdarg.h> + +#include "../src/gcrypt.h" + +#define PGM "version" + + +int +main (int argc, char **argv) +{ + (void)argc; + (void)argv; + + gcry_control (GCRYCTL_DISABLE_SECMEM, 0); + if (!gcry_check_version (GCRYPT_VERSION)) + { + fprintf (stderr, PGM ": version mismatch\n"); + exit (1); + } + + gcry_control (GCRYCTL_PRINT_CONFIG, NULL); + + return 0; +} + |