CFLAGS_POSIX = -fno-builtin
CPPFLAGS_POSIX = -I$(top_srcdir)/grub-core/lib/posix_wrap
-CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls $(CFLAGS_POSIX)
+CFLAGS_GCRY = -Wno-error -Wno-missing-field-initializers -Wno-redundant-decls -Wno-undef $(CFLAGS_POSIX)
CPPFLAGS_GCRY = -I$(top_srcdir)/grub-core/lib/libgcrypt_wrap $(CPPFLAGS_POSIX) -D_GCRYPT_IN_LIBGCRYPT=1 -I$(top_srcdir)/include/grub/gcrypt
CPPFLAGS_EFIEMU = -I$(top_srcdir)/grub-core/efiemu/runtime
#define __powerpc__ 1
#endif
+#define GCRYPT_NO_DEPRECATED 1
+
/* Define to 1 to enable disk cache statistics. */
#define DISK_CACHE_STATS @DISK_CACHE_STATS@
#define BOOT_TIME_STATS @BOOT_TIME_STATS@
--- /dev/null
+2011-12-01 Werner Koch <wk@g10code.com>
+
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
+
+2011-06-29 Werner Koch <wk@g10code.com>
+
+ * cipher.c (cipher_get_keylen): Return zero for an invalid algorithm.
+ (cipher_get_blocksize): Ditto.
+
+2011-06-13 Werner Koch <wk@g10code.com>
+
+ * dsa.c (selftest_sign_1024): Use the raw and not the pkcs1 flag.
+
+ * pubkey.c (gcry_pk_sign): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Parse "random-override" for pkcs1 encryption.
+ (pkcs1_encode_for_encryption): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (gcry_pk_encrypt): Special case output generation for PKCS1.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for raw encoding.
+
+2011-06-10 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Use format specifier '%M' to avoid
+ leading zeroes. Special case output generation for PSS.
+ (gcry_pk_encrypt): Special case output generation for OAEP.
+ (sexp_data_to_mpi): Use GCRYMPI_FMT_USG for PSS verify.
+
+2011-06-09 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Make use of octet_string_from_mpi.
+ (sexp_to_enc): Skip "random-override".
+
+ * pubkey.c (oaep_encode, pss_encode): Add args RANDOM_OVERRIDE and
+ RANDOM_OVERRIDE_LEN.
+ (sexp_data_to_mpi): Extract new random-override parameter.
+
+ * pubkey.c (pss_encode, pss_verify): Use VALUE verbatim for MHASH.
+ (octet_string_from_mpi): Add arg SPACE.
+
+2011-06-08 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pss_encode, pss_verify): Restructure and comment code
+ to match rfc-3447. Replace secure allocs by plain allocs and
+ wipememory. Use gcry_md_hash_buffer.
+ (octet_string_from_mpi): New.
+
+2011-06-03 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (oaep_decode): Add more comments and restructure to
+ match the description in RFC-3447.
+ (oaep_encode): Check for mgf1 error. s/dlen/hlen/.
+
+2011-05-31 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (mgf1): Optimize by using gcry_md_reset. Re-implement
+ for easier readability.
+ (oaep_encode): Add more comments and restructure to match the
+ description in RFC-3447.
+
+ * pubkey.c (pkcs1_encode_for_signature, oaep_decode): Change
+ return value from one MPI to a buffer.
+ (gcry_pk_decrypt): Adjust for this change.
+
+2011-05-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pkcs1_decode_for_encryption): Change handling of
+ leading zero byte.
+
+2011-05-27 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (gcry_pk_decrypt): Fix double-free when un-padding
+ invalid data. Thanks to Tom Ritter.
+
+2011-05-24 Daiki Ueno <ueno@unixuser.org>
+
+ * rsa.c (rsa_verify): Use CMP if given, to check the decrypted
+ sig.
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Factor out
+ CTX initialization to ...
+ (init_encoding_ctx): .. new.
+ (gcry_pk_verify): Pass verify func and the arg to pubkey_verify.
+ (pss_encode, pss_verify, pss_verify_cmp): New.
+
+2011-05-23 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (pkcs1_decode_for_encryption, oaep_decode): Fix memleak
+ when gcry_mpi_print fails.
+
+2011-05-18 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (pkcs1_encode_for_encryption): .. new,
+ (pkcs1_encode_for_signature): .. new.
+ (pkcs1_decode_for_encryption): New.
+ (gcry_pk_decrypt): Do un-padding for PKCS#1 as well as OAEP.
+ (sexp_to_enc): Abolish "unpad" flag, which is not necessary since
+ we can do un-padding implicitly when "pkcs1" or "oaep" is given.
+
+2011-05-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_to_enc, sexp_data_to_mpi): Set LABEL to NULL
+ after free.
+ (sexp_to_enc, sexp_data_to_mpi): Do not allow multiple encoding
+ flags.
+ (oaep_encode, oaep_decode, sexp_to_key, sexp_to_sig)
+ (sexp_to_enc, sexp_data_to_mpi, gcry_pk_encrypt, gcry_pk_sign)
+ (gcry_pk_genkey, _gcry_pk_get_elements): Replace access to ERRNO
+ by gpg_err_code_from_syserror.
+
+2011-05-11 Daiki Ueno <ueno@unixuser.org>
+
+ * pubkey.c (sexp_data_to_mpi): Factor some code out to ...
+ (get_hash_algo): .. new.
+ (mgf1, oaep_encode, oaep_decode): New.
+ (sexp_to_enc): Add arg CTX. Remove arg RET_WANT_PKCS1. Support
+ OAEP.
+ (sexp_data_to_mpi): Add arg CTX. Support OAEP.
+ (gcry_pk_encrypt): Pass a CTX to sexp_data_to_mpi.
+ (gcry_pk_decrypt): Pass a CTX tp sexp_to_enc and replace
+ WANT_PKCS1. Implement unpadding for OAEP.
+ (gcry_pk_sign): Pass NULL for CTX arg of sexp_data_to_mpi.
+ (gcry_pk_verify): Ditto.
+
+2011-04-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Replace gpg_err_code_from_errno by
+ gpg_err_code_from_syserror.
+
+2011-04-11 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Avoid double free of L2.
+
+ * cipher.c (_gcry_cipher_setctr): Clear unused lastiv info.
+ (gcry_cipher_ctl) <GCRYCTL_SET_CTR>: Implement by calling
+ _gcry_cipher_setctr.
+ (do_ctr_encrypt): Save last counter and reuse it.
+
+ * cipher.c (do_ctr_encrypt): Allow arbitrary length inputs to
+ match the 1.4 behaviour.
+
+2011-04-04 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Release L1 while parsing "curve".
+
+ * pubkey.c (gcry_pk_get_keygrip): Always release NAME and L2.
+ Reported by Ben Kibbey.
+
+2011-03-28 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_elg_prime): Make sure that PRIME is
+ NULL if the called func ever returns an error.
+
+ * pubkey.c (gcry_pk_decrypt): Remove unused var PUBKEY.
+
+2011-03-09 Werner Koch <wk@g10code.com>
+
+ * kdf.c: New.
+
+2011-02-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (aesni_cleanup_2_4): New.
+ (aesenc_xmm1_xmm0, do_aesni_ctr_4): New.
+ (_gcry_aes_ctr_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add CTR_ENC. Move field
+ CTR into an u_ctr union and adjust all users.
+ (gcry_cipher_open): Use _gcry_aes_ctr_enc.
+ (do_ctr_encrypt): Use bulk mode.
+
+2011-02-18 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (u32_a_t): New.
+ (do_encrypt_aligned, do_encrypt_aligned): Use the new type to
+ avoid problems with strict aliasing rules.
+
+2011-02-16 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_cfb) [USE_AESNI]: New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec) [USE_AESNI]: Use new fucntion.
+
+2011-02-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_aesni_enc_aligned, do_aesni_dec_aligned): Use
+ movdqa for the key but keep using movdqu for the data.
+ (do_aesni): Remove alignment detection. Don't burn the stack.
+ (aesni_prepare, aesni_cleanup): New macros.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use
+ these macros. Don't burn the stack in the USE_AESNI case.
+ (do_setkey): Add disabled code to use aeskeygenassist.
+
+2011-02-14 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (ATTR_ALIGNED_16): New
+ (do_aesni): Do not copy if already aligned.
+ (do_encrypt, do_decrypt): Ditto.
+ (rijndael_decrypt, rijndael_encrypt): Increase stack burning amount.
+
+ * rijndael.c (RIJNDAEL_context): Reorder fields. Change fieldname
+ ROUNDS to rounds. Move padlock_key into u1.
+ (keySched, keySched2): Rename macros to keyscherr and keyschdec
+ and change all users.
+ (padlockkey): New macro. Change all users of padlock_key.
+ * cipher.c (NEED_16BYTE_ALIGNED_CONTEXT): Always define if using gcc.
+ (struct gcry_cipher_handle): Align U_IV to at least 16 byte.
+
+2011-02-13 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_AESNI): New. Define for ia32 and gcc >= 4.
+ (m128i_t) [USE_AESNI]: New.
+ (RIJNDAEL_context) [USE_AESNI]: Add field use_aesni.
+ (do_setkey): Set USE_AESNI for all key lengths.
+ (prepare_decryption) [USE_AESNI]: Use aesimc instn if requested.
+ (do_aesni_enc_aligned, do_aesni_dec_aligned)
+ (do_aesni) [USE_AESNI]: New.
+ (rijndael_encrypt, _gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (rijndael_decrypt, _gcry_aes_cfb_dec)
+ (_gcry_aes_cbc_dec) [USE_AESNI]: Use do_aesni.
+
+2011-02-01 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_curve): New.
+ (sexp_to_key): Add arg OVERRIDE_ELEMS.
+ (sexp_elements_extract_ecc): Allow for params only.
+ (gcry_pk_get_param): New.
+ * ecc.c (ecc_get_curve): New.
+ (ecc_get_param_sexp): New.
+
+2011-01-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Hack to insert the used curve name.
+
+2011-01-27 Werner Koch <wk@g10code.com>
+
+ * ecc.c (fill_in_curve): Remove.
+ (generate_curve): Rename to ..
+ (fill_in_curve): this. Remove setting of NAME_OID.
+ (ecc_encrypt_raw): Change name of arg DATA to K for better
+ readability. Use ECC_public_key instead of ECC_secret_key.
+ Require a caller to pass a complete pkey array.
+ (ecc_decrypt_raw): Require a caller to pass a complete skey array.
+ (elliptic_curve_t): Add field NAME.
+ (fill_in_curve): Set field.
+ (generate_key): Add arg R_USED_CURVE.
+ (ecc_generate_ext): Return used curve name.
+
+2011-01-13 Andrey Jivsov <openpgp@brainhub.org> (wk)
+
+ * ecc.c (ec2os): Do not free passed parameters X and Y. Adjust
+ callers.
+ (ecc_encrypt_raw, ecc_decrypt_raw): New.
+ (ecdh_names, _gcry_pubkey_spec_ecdh): New.
+ * pubkey.c (pubkey_table): Support ECDH.
+
+2010-08-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Remove double release of the module.
+ Fixes bug#1263.
+
+2010-06-10 Jeff Johnson <n3npq@mac.com> (wk)
+
+ * ecc.c (ecc_generate_ext): Parse transient-key flag.
+ (generate_key): Add arg TRANSIENT_KEY and use it to set the random
+ level.
+
+2010-04-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ Spelling fixes.
+
+2010-03-26 Werner Koch <wk@g10code.com>
+
+ * tiger.c (asn): Unfetter the old TIGER from an OID.
+ (TIGER_CONTEXT): Add field VARIANT.
+ (tiger_init): Factor code out to ...
+ (do_init): New.
+ (tiger1_init, tiger2_init): New.
+ (_gcry_digest_spec_tiger1, _gcry_digest_spec_tiger2): New.
+ * md.c (digest_table): Add TIGER1 and TIGER2 variants.
+
+2009-12-11 Werner Koch <wk@g10code.com>
+
+ * sha256.c (Cho, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables
+
+ * sha512.c (ROTR, Ch, Maj, Sum0, Sum1): Turn macros into inline
+ functions.
+ (transform): Partly unroll to interweave the chain variables.
+ Suggested by Christian Grothoff.
+
+2009-12-10 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (o_flag_munging): New.
+ (tiger.o, tiger.lo): Use it.
+
+ * cipher.c (do_ctr_encrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Add check for valid inputlen. Wipe temporary
+ memory.
+ (do_ctr_decrypt): Likewise.
+ (do_cbc_encrypt, do_cbc_decrypt): Add arg OUTBUFLEN. Check for
+ suitable value. Move check for valid inputlen to here; change
+ returned error from INV_ARG to INV_LENGTH.
+ (do_ecb_encrypt, do_ecb_decrypt): Ditto.
+ (do_cfb_encrypt, do_cfb_decrypt): Ditto.
+ (do_ofb_encrypt, do_ofb_decrypt): Ditto.
+ (cipher_encrypt, cipher_encrypt): Adjust for above changes.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Simplify.
+
+2009-12-09 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Allow for GCRY_CIPHER_MODE_AESWRAP.
+ (cipher_encrypt, cipher_decrypt): Ditto.
+ (do_aeswrap_encrypt, do_aeswrap_decrypt): New.
+ (struct gcry_cipher_handle): Add field marks.
+ (cipher_setkey, cipher_setiv): Update marks flags.
+ (cipher_reset): Reset marks.
+ (cipher_encrypt, cipher_decrypt): Add new arg OUTBUFLEN.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Pass outbuflen to
+ cipher_encrypt. Replace GPG_ERR_TOO_SHORT by
+ GPG_ERR_BUFFER_TOO_SHORT.
+
+2009-08-21 Werner Koch <wk@g10code.com>
+
+ * dsa.c (dsa_generate_ext): Release retfactors array before
+ setting it to NULL. Reported by Daiko Ueno.
+
+2009-07-02 Werner Koch <wk@g10code.com>
+
+ * md.c (md_read): Fix incomplete check for NULL.
+ Reported by Fabian Kail.
+
+2009-03-31 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_check_secret_key): Return GPG_ERR_BAD_SECKEY and not
+ GPG_ERR_PUBKEY_ALGO.
+
+2009-02-16 Werner Koch <wk@g10code.com>
+
+ * rsa.c (generate_x931): Do not initialize TBL with automatic
+ variables.
+ * whirlpool.c, tiger.c, sha256.c, sha1.c, rmd160.c, md5.c
+ * md4.c, crc.c: Remove memory.h. This is garbage from gnupg.
+ Reported by Dan Fandrich.
+
+2009-01-22 Werner Koch <wk@g10code.com>
+
+ * ecc.c (compute_keygrip): Remove superfluous const.
+
+2009-01-06 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (oid_spec_rmd160): Add TeleTrust identifier.
+
+2008-12-10 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg DOMAIN and use it if specified.
+ (generate_fips186): Ditto.
+ (dsa_generate_ext): Parse and check the optional "domain"
+ parameter and pass them to the generate functions.
+
+ * rijndael.c (rijndael_names): Add "AES128" and "AES-128".
+ (rijndael192_names): Add "AES-192".
+ (rijndael256_names): Add "AES-256".
+
+2008-12-05 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add arg TRANSIENT_KEY and use it to detrmine
+ the RNG quality needed.
+ (dsa_generate_ext): Parse the transient-key flag und pass it to
+ generate.
+
+2008-11-28 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): Add arg DERIVEPARMS and use the seed
+ value if available.
+
+ * primegen.c (_gcry_generate_fips186_2_prime): Fix inner p loop.
+
+2008-11-26 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_fips186_3_prime): New.
+ * dsa.c (generate_fips186): Add arg USE_FIPS186_2.
+ (dsa_generate_ext): Parse new flag use-fips183-2.
+
+2008-11-25 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate_fips186): New.
+ (dsa_generate_ext): Use new function if derive-parms are given or
+ if in FIPS mode.
+ * primegen.c (_gcry_generate_fips186_2_prime): New.
+
+2008-11-24 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Insert code to output extrainfo.
+ (pubkey_generate): Add arg R_EXTRAINFO and pass it to the extended
+ key generation function.
+ * rsa.c (gen_x931_parm_xp, gen_x931_parm_xi): New.
+ (generate_x931): Generate params if not given.
+ (rsa_generate_ext): Parse use-x931 flag. Return p-q-swapped
+ indicator.
+ * dsa.c (dsa_generate_ext): Put RETFACTORS into R_EXTRAINFO if
+ possible.
+
+ * pubkey.c (gcry_pk_genkey): Remove parsing of almost all
+ parameters and pass the parameter S-expression to pubkey_generate.
+ (pubkey_generate): Simplify by requitring modules to parse the
+ parameters. Remove the special cases for Elgamal and ECC.
+ (sexp_elements_extract_ecc): Add arg EXTRASPEC and use it. Fix
+ small memory leak.
+ (sexp_to_key): Pass EXTRASPEC to sexp_elements_extract_ecc.
+ (pubkey_table) [USE_ELGAMAL]: Add real extraspec.
+ * rsa.c (rsa_generate_ext): Adjust for new calling convention.
+ * dsa.c (dsa_generate_ext): Ditto.
+ * elgamal.c (_gcry_elg_generate): Ditto. Rename to elg_generate_ext.
+ (elg_generate): New.
+ (_gcry_elg_generate_using_x): Remove after merging code with
+ elg_generate_ext.
+ (_gcry_pubkey_extraspec_elg): New.
+ (_gcry_elg_check_secret_key, _gcry_elg_encrypt, _gcry_elg_sign)
+ (_gcry_elg_verify, _gcry_elg_get_nbits): Make static and remove
+ _gcry_ prefix.
+ * ecc.c (_gcry_ecc_generate): Rename to ecc_generate_ext and
+ adjust for new calling convention.
+ (_gcry_ecc_get_param): Rename to ecc_get_param and make static.
+ (_gcry_pubkey_extraspec_ecdsa): Add ecc_generate_ext and
+ ecc_get_param.
+
+2008-11-20 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg DERIVEPARMS.
+ (gcry_pk_genkey): Parse derive-parms and pass it to above.
+ * rsa.c (generate_x931): New.
+ (rsa_generate_ext): Add arg DERIVEPARMS and call new function in
+ fips mode or if DERIVEPARMS is given.
+ * primegen.c (_gcry_derive_x931_prime, find_x931_prime): New.
+
+2008-11-19 Werner Koch <wk@g10code.com>
+
+ * rsa.c (rsa_decrypt): Use gcry_create_nonce for blinding.
+ (generate): Rename to generate_std.
+
+2008-11-05 Werner Koch <wk@g10code.com>
+
+ * md.c (md_open): Use a switch to set the Bsize.
+ (prepare_macpads): Fix long key case for SHA384 and SHA512.
+
+ * cipher.c (gcry_cipher_handle): Add field EXTRASPEC.
+ (gcry_cipher_open): Set it.
+ (gcry_cipher_ctl): Add private control code to disable weak key
+ detection and to return the current input block.
+ * des.c (_tripledes_ctx): Add field FLAGS.
+ (do_tripledes_set_extra_info): New.
+ (_gcry_cipher_extraspec_tripledes): Add new function.
+ (do_tripledes_setkey): Disable weak key detection.
+
+2008-10-24 Werner Koch <wk@g10code.com>
+
+ * md.c (digest_table): Allow MD5 in fips mode.
+ (md_register_default): Take special action for MD5.
+ (md_enable, gcry_md_hash_buffer): Ditto.
+
+2008-09-30 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (do_setkey): Properly align "t" and "tk".
+ (prepare_decryption): Properly align "w". Fixes bug #936.
+
+2008-09-18 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Parse domain parameter.
+ (pubkey_generate): Add new arg DOMAIN and remove special case for
+ DSA with qbits.
+ * rsa.c (rsa_generate): Add dummy args QBITS, NAME and DOMAIN and
+ rename to rsa_generate_ext. Change caller.
+ (_gcry_rsa_generate, _gcry_rsa_check_secret_key)
+ (_gcry_rsa_encrypt, _gcry_rsa_decrypt, _gcry_rsa_sign)
+ (_gcry_rsa_verify, _gcry_rsa_get_nbits): Make static and remove
+ _gcry_ prefix.
+ (_gcry_pubkey_spec_rsa, _gcry_pubkey_extraspec_rsa): Adjust names.
+ * dsa.c (dsa_generate_ext): New.
+ (_gcry_dsa_generate): Replace code by a call to dsa_generate.
+ (_gcry_dsa_check_secret_key, _gcry_dsa_sign, _gcry_dsa_verify)
+ (_gcry_dsa_get_nbits): Make static and remove _gcry prefix.
+ (_gcry_dsa_generate2): Remove.
+ (_gcry_pubkey_spec_dsa): Adjust to name changes.
+ (_gcry_pubkey_extraspec_rsa): Add dsa_generate_ext.
+
+2008-09-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (run_selftests): Add arg EXTENDED.
+
+2008-09-12 Werner Koch <wk@g10code.com>
+
+ * rsa.c (test_keys): Do a bad case signature check.
+ * dsa.c (test_keys): Do a bad case check.
+
+ * cipher.c (_gcry_cipher_selftest): Add arg EXTENDED and pass it
+ to the called tests.
+ * md.c (_gcry_md_selftest): Ditto.
+ * pubkey.c (_gcry_pk_selftest): Ditto.
+ * rijndael.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftest_fips_128): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftest_fips_192): Add dummy arg EXTENDED.
+ (selftest_fips_256): Ditto.
+ * hmac-tests.c (_gcry_hmac_selftest): Ditto.
+ (run_selftests): Ditto.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha224, selftests_sha256): Ditto.
+ (selftests_sha384, selftests_sha512): Ditto.
+ * sha1.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftests_sha1): Add arg EXTENDED and run only one test
+ non-extended mode.
+ * sha256.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha224): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha256): Ditto.
+ * sha512.c (run_selftests): Add arg EXTENDED and pass it to the
+ called tests.
+ (selftests_sha384): Add arg EXTENDED and run only one test
+ non-extended mode.
+ (selftests_sha512): Ditto.
+ * des.c (run_selftests): Add arg EXTENDED and pass it to the
+ called test.
+ (selftest_fips): Add dummy arg EXTENDED.
+ * rsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * dsa.c (run_selftests): Add dummy arg EXTENDED.
+
+ * rsa.c (extract_a_from_sexp): New.
+ (selftest_encr_1024): Check that the ciphertext does not match the
+ plaintext.
+ (test_keys): Improve tests and return an error status.
+ (generate): Return an error if test_keys fails.
+ * dsa.c (test_keys): Add comments and return an error status.
+ (generate): Return an error if test_keys failed.
+
+2008-09-11 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Return an error instead of calling
+ BUG in case of a practically impossible condition.
+ (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024, selftest_encr_1024): New.
+ (selftests_rsa): Implement tests.
+ * dsa.c (sample_secret_key, sample_public_key): New.
+ (selftest_sign_1024): New.
+ (selftests_dsa): Implement tests.
+
+2008-09-09 Werner Koch <wk@g10code.com>
+
+ * hmac-tests.c (selftests_sha1): Add tests.
+ (selftests_sha224, selftests_sha384, selftests_sha512): Make up tests.
+
+ * hash-common.c, hash-common.h: New.
+ * sha1.c (selftests_sha1): Add 3 tests.
+ * sha256.c (selftests_sha256, selftests_sha224): Ditto.
+ * sha512.c (selftests_sha512, selftests_sha384): Ditto.
+
+2008-08-29 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Remove the special case for RSA
+ and check whether a custom computation function has been setup.
+ * rsa.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_rsa): Setup this function.
+ * ecc.c (compute_keygrip): New.
+ (_gcry_pubkey_extraspec_ecdsa): Setup this function.
+
+2008-08-28 Werner Koch <wk@g10code.com>
+
+ * cipher.c (cipher_decrypt, cipher_encrypt): Return an error if
+ mode NONE is used.
+ (gcry_cipher_open): Allow mode NONE only with a debug flag set and
+ if not in FIPS mode.
+
+2008-08-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_generate): Add arg KEYGEN_FLAGS.
+ (gcry_pk_genkey): Implement new parameter "transient-key" and
+ pass it as flags to pubkey_generate.
+ (pubkey_generate): Make use of an ext_generate function.
+ * rsa.c (generate): Add new arg transient_key and pass appropriate
+ args to the prime generator.
+ (_gcry_rsa_generate): Factor all code out to ...
+ (rsa_generate): .. new func with extra arg KEYGEN_FLAGS.
+ (_gcry_pubkey_extraspec_ecdsa): Setup rsa_generate.
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Add new arg RANDOM_LEVEL.
+
+2008-08-21 Werner Koch <wk@g10code.com>
+
+ * primegen.c (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Use a constant macro for the random
+ level.
+
+2008-08-19 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_elements_extract_ecc) [!USE_ECC]: Do not allow
+ allow "curve" parameter.
+
+2008-08-15 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (_gcry_pk_selftest): New.
+ * dsa.c (selftests_dsa, run_selftests): New.
+ * rsa.c (selftests_rsa, run_selftests): New.
+ * ecc.c (selftests_ecdsa, run_selftests): New.
+
+ * md.c (_gcry_md_selftest): New.
+ * sha1.c (run_selftests, selftests_sha1): New.
+ * sha256.c (selftests_sha224, selftests_sha256, run_selftests): New.
+ * sha512.c (selftests_sha384, selftests_sha512, run_selftests): New.
+
+ * des.c (selftest): Remove static variable form selftest.
+ (des_setkey): No on-the-fly self test in fips mode.
+ (tripledes_set3keys): Ditto.
+
+ * cipher.c (_gcry_cipher_setkey, _gcry_cipher_setiv):
+
+ * dsa.c (generate): Bail out in fips mode if NBITS is less than 1024.
+ * rsa.c (generate): Return an error code if the the requested size
+ is less than 1024 and we are in fpis mode.
+ (_gcry_rsa_generate): Take care of that error code.
+
+ * ecc.c (generate_curve): In fips mode enable only NIST curves.
+
+ * cipher.c (_gcry_cipher_selftest): New.
+
+ * sha512.c (_gcry_digest_extraspec_sha384)
+ (_gcry_digest_extraspec_sha512): New.
+ * sha256.c (_gcry_digest_extraspec_sha224)
+ (_gcry_digest_extraspec_sha256): New.
+ * sha1.c (_gcry_digest_extraspec_sha1): New.
+ * ecc.c (_gcry_pubkey_extraspec_ecdsa): New.
+ * dsa.c (_gcry_pubkey_extraspec_dsa): New.
+ * rsa.c (_gcry_pubkey_extraspec_rsa): New.
+ * rijndael.c (_gcry_cipher_extraspec_aes)
+ (_gcry_cipher_extraspec_aes192, _gcry_cipher_extraspec_aes256): New.
+ * des.c (_gcry_cipher_extraspec_tripledes): New.
+
+ * cipher.c (gcry_cipher_register): Rename to _gcry_cipher_register.
+ Add arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (cipher_table_entry): Add extraspec field.
+ * md.c (_gcry_md_register): Rename to _gcry_md_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (digest_table_entry): Add extraspec field.
+ * pubkey.c (gcry_pk_register): Rename to _gcry_pk_register. Add
+ arg EXTRASPEC.
+ (dummy_extra_spec): New.
+ (pubkey_table_entry): Add extraspec field.
+
+ * ac.c: Let most public functions return GPG_ERR_UNSUPPORTED in
+ fips mode.
+
+ * pubkey.c (pubkey_table_entry): Add field FIPS_ALLOWED and mark
+ appropriate algorithms.
+ (dummy_generate, dummy_check_secret_key, dummy_encrypt)
+ (dummy_decrypt, dummy_sign, dummy_verify, dummy_get_nbits): Signal
+ a fips error when used.
+ (gcry_pk_register): In fips mode do not allow to register new
+ algorithms.
+
+ * md.c (digest_table): Add field FIPS_ALLOWED and mark appropriate
+ algorithms.
+ (md_register_default): In fips mode register only fips algorithms.
+ (gcry_md_register): In fips mode do not allow to register new
+ algorithms.
+ (gcry_md_get): Signal a fips error if called.
+ (gcry_md_hash_buffer): Do not allow rmd160 when not in fips mode.
+ (md_start_debug): Disable in fips_mode.
+
+ * md.c (gcry_md_register_default): Rename to ..
+ (md_register_default): .. this.
+ (md_digest): Remove this commented fucntion.
+ * pubkey.c (gcry_pk_register_default): Rename to ..
+ (pk_register_default): .. this.
+
+ * cipher.c (cipher_table_entry): Add field FIPS_ALLOWED.
+ (gcry_cipher_register_default): Register only fips approved
+ algorithms.
+ (gcry_cipher_register): Do not allow to register new ciphers.
+ (cipher_setiv): Signal fips error.
+
+ * cipher (gcry_cipher_register_default): Rename to ..
+ (cipher_register_default): .. this.
+ (REGISTER_DEFAULT_CIPHERS): Adjust for that change.
+
+2008-07-05 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c, random.h, rndhw.c, rndunix.c, rand-internal.h
+ * random.c, rndegd.c, rndlinux.c, rndw32.c: Move to ../cipher.
+ * Makefile.am: Remove random stuff.
+
+2008-06-24 Szakats Istvan <szaki.ms@gmail.com> (wk)
+
+ * ac.c (_gcry_ac_key_destroy, _gcry_ac_key_pair_generate): Relase
+ some more memory.
+
+2008-04-22 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc, _gcry_aes_cbc_enc)
+ (_gcry_aes_cfb_dec, _gcry_aes_cbc_dec): Use Padlock if possible.
+
+2008-04-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c (transform_aligned): Remove. That is will obviosuly not
+ work because we need a scratch working area and our internal API
+ does not allow to modify the buffers.
+
+ * rijndael.c: Factor tables out to ..
+ * rijndael-tables.h: .. new.
+
+ * ac.c (ac_data_extract): Make static.
+
+ * camellia.h [HAVE_CONFIG_H]: Include config.h.
+
+ * rndw32.c (registry_poll): Only print the performance data
+ problem warning once. Suggested by Simon Josefsson.
+
+2008-03-19 Werner Koch <wk@g10code.com>
+
+ * cipher.c (gcry_cipher_open) [USE_AES]: Init bulk encryption only
+ if requested. Suggested by Dirk Stoecker.
+
+2008-03-18 Werner Koch <wk@g10code.com>
+
+ * sha1.c: Include stdint.h.
+ (transform): Add arg NBLOCKS so that we can work on more than one
+ block and avoid updates of the chaining variables. Changed all
+ callers to use 1.
+ (sha1_write): Replace loop around transform.
+ (transform_aligned) [WORDS_BIGENDIAN]: New.
+ (TRANSFORM): New macro to replace all direct calls of transform.
+
+2008-03-17 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_dec): New.
+ (do_encrypt): Factor code out to ..
+ (do_encrypt_aligned): .. New.
+ (_gcry_aes_cfb_enc, _gcry_aes_cfb_dec): Use new function.
+ (do_decrypt): Factor code out to ..
+ (do_decrypt_aligned): .. new.
+ (_gcry_aes_cbc_enc, _gcry_aes_cbc_dec): New.
+ * cipher.c (struct gcry_cipher_handle): Put field IV into new
+ union U_IV to enforce proper alignment. Change all users.
+ (do_cfb_decrypt): Optimize.
+ (do_cbc_encrypt, do_cbc_decrypt): Optimize.
+
+2008-03-15 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (_gcry_aes_cfb_enc): New.
+ * cipher.c (struct gcry_cipher_handle): Add field ALGO and BULK.
+ (gcry_cipher_open): Set ALGO and BULK.
+ (do_cfb_encrypt): Optimize.
+
+2008-02-18 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_verify) [IS_DEVELOPMENT_VERSION]: Print
+ intermediate results.
+
+2008-01-08 Werner Koch <wk@g10code.com>
+
+ * random.c (add_randomness): Do not just increment
+ POOL_FILLED_COUNTER but update it by the actual amount of data.
+
+2007-12-13 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Support SHA-224.
+
+2007-12-05 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Depend on ENABLE_PADLOCK_SUPPORT.
+ * rndhw.c (USE_PADLOCK): Ditto
+
+ * rsa.c (secret): Fixed condition test for using CRT. Reported by
+ Dean Scarff. Fixes bug#864.
+ (_gcry_rsa_check_secret_key): Return an erro if the optional
+ parameters are missing.
+ * pubkey.c (sexp_elements_extract): Add arg ALGO_NAME. Changed all
+ callers to pass NULL. Add hack to allow for optional RSA
+ parameters.
+ (sexp_to_key): Pass algo name to sexp_elements_extract.
+
+2007-12-03 Werner Koch <wk@g10code.com>
+
+ * random.c (gcry_random_add_bytes): Implement it.
+ * rand-internal.h (RANDOM_ORIGIN_EXTERNAL): New.
+
+2007-11-30 Werner Koch <wk@g10code.com>
+
+ * rndhw.c: New.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Try to read 50%
+ directly from the hwrng.
+ * random.c (do_fast_random_poll): Also run the hw rng fast poll.
+ (_gcry_random_dump_stats): Tell whether the hw rng failed.
+
+2007-11-29 Werner Koch <wk@g10code.com>
+
+ * rijndael.c (USE_PADLOCK): Define new macro used for ia32.
+ (RIJNDAEL_context) [USE_PADLOCK]: Add fields USE_PADLOCK and
+ PADLOCK_KEY.
+ (do_setkey) [USE_PADLOCK]: Enable padlock if available for 128 bit
+ AES.
+ (do_padlock) [USE_PADLOCK]: New.
+ (rijndael_encrypt, rijndael_decrypt) [USE_PADLOCK]: Divert to
+ do_padlock.
+ * cipher.c (cipher_context_alignment_t): New. Use it in this
+ module in place of PROPERLY_ALIGNED_TYPE.
+ (NEED_16BYTE_ALIGNED_CONTEXT): Define macro for ia32.
+ (struct gcry_cipher_handle): Add field HANDLE_OFFSET.
+ (gcry_cipher_open): Take care of increased alignment requirements.
+ (gcry_cipher_close): Ditto.
+
+2007-11-28 Werner Koch <wk@g10code.com>
+
+ * sha256.c (asn224): Fixed wrong template. It happened due to a
+ bug in RFC4880. SHA-224 is not in the stable version of libgcrypt
+ so the consequences are limited to users of this devel version.
+
+2007-10-31 Werner Koch <wk@g10code.com>
+
+ * ac.c (gcry_ac_data_new): Remove due to the visibility wrapper.
+ (gcry_ac_data_destroy, gcry_ac_data_copy, gcry_ac_data_length)
+ (gcry_ac_data_set, gcry_ac_data_get_name, gcry_ac_data_get_index)
+ (gcry_ac_data_to_sexp, gcry_ac_data_from_sexp)
+ (gcry_ac_data_clear, gcry_ac_io_init, gcry_ac_open)
+ (gcry_ac_close, gcry_ac_key_init, gcry_ac_key_pair_generate)
+ (gcry_ac_key_pair_extract, gcry_ac_key_destroy)
+ (gcry_ac_key_pair_destroy, gcry_ac_key_data_get)
+ (gcry_ac_key_test, gcry_ac_key_get_nbits, gcry_ac_key_get_grip)
+ (gcry_ac_data_encrypt, gcry_ac_data_decrypt, gcry_ac_data_sign)
+ (gcry_ac_data_verify, gcry_ac_data_encode, gcry_ac_data_decode)
+ (gcry_ac_mpi_to_os, gcry_ac_mpi_to_os_alloc, gcry_ac_os_to_mpi)
+ (gcry_ac_data_encrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (gcry_ac_data_sign_scheme, gcry_ac_data_verify_scheme)
+ (gcry_ac_io_init_va): Ditto.
+ (gcry_ac_id_to_name, gcry_ac_name_to_id): Remove as these
+ deprecated functions are now implemented by visibility.c.
+
+2007-10-26 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Disable debug flag.
+
+2007-10-25 Werner Koch <wk@g10code.com>
+
+ * rndw32.c: Updated from current cryptlib snapshot and modified
+ for our use. Removed support from pre NT systems.
+ (slow_gatherer_windows95): Remove.
+ (_gcry_rndw32_gather_random): Require an NT platform.
+ (init_system_rng, read_system_rng, read_mbm_data): New.
+ (slow_gatherer_windowsNT): Rename to ...
+ (slow_gatherer): .. this. Read system RNG and MBM.
+ (registry_poll): New with code factored out from slow_gatherer.
+
+2007-08-23 Werner Koch <wk@g10code.com>
+
+ * random.c (pool_filled_counter): New.
+ (add_randomness): Use it.
+
+2007-08-22 Werner Koch <wk@g10code.com>
+
+ * rndw32.c, rndunix.c: Switched to LGPL.
+
+2007-05-30 Werner Koch <wk@g10code.com>
+
+ * camellia.h, camellia.c: Replace by new LGPL version and adjusted
+ camellia.h.
+
+2007-05-09 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (_gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read):
+ Adjust users of gcry_ac_io_t because union is not anonymous
+ anymore.
+
+2007-05-02 Werner Koch <wk@g10code.com>
+
+ * camellia-glue.c (camellia_setkey, camellia_encrypt)
+ (camellia_decrypt): Recalculated used stack size in called
+ functions.
+ * camellia.h: Redefine external symbols.
+
+2007-05-02 David Shaw <dshaw@jabberwocky.com>
+
+ * Makefile.am, cipher.c: Add Camellia.
+
+ * camellia-glue.c: New. The necessary glue to interface libgcrypt
+ to the stock NTT Camellia distribution.
+
+ * camellia.h, camellia.c: The stock NTT Camellia distribution
+ (GPL).
+
+2007-04-30 David Shaw <dshaw@jabberwocky.com>
+
+ * cipher.c: Use #if instead of #ifdef as configure defines the
+ USE_cipher defines as 0 for disabled.
+
+2007-04-30 Werner Koch <wk@g10code.com>
+
+ * rndegd.c (_gcry_rndegd_set_socket_name): New.
+
+2007-04-30 Marcus Brinkmann <marcus@g10code.de>
+
+ * ecc.c (ec2os): Fix relocation of short numbers.
+
+ * ecc.c (generate_key): Do not allocate D, which will be allocated
+ by GEN_K. Remove G. Fix test if g_x, g_y resp. q_x, q_y are
+ requested.
+ (_gcry_ecc_generate): Release unneeded members of SK.
+ * pubkey.c (sexp_to_key): Release NAME.
+
+2007-04-28 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (gcry_ac_mpi): Remove member NAME_PROVIDED.
+ (ac_data_mpi_copy, _gcry_ac_data_set, _gcry_ac_data_get_name)
+ (_gcry_ac_data_get_index, ac_data_construct): Adjust handling of
+ NAME accordingly.
+
+2007-04-20 Werner Koch <wk@g10code.com>
+
+ * ecc.c (domain_parms): Add standard brainpool curves.
+
+2007-04-18 Werner Koch <wk@g10code.com>
+
+ * ecc.c (generate_curve): Implement alias mechanism.
+
+ * pubkey.c (sexp_elements_extract_ecc): New.
+ (sexp_to_key): Add special case for ecc.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_genkey): Replace
+ name_terminated stuff by a call to _gcry_sexp_nth_string.
+ (gcry_pk_get_keygrip): Ditto.
+
+2007-04-16 Werner Koch <wk@g10code.com>
+
+ * ecc.c (_gcry_ecc_generate): Renamed DUMMY to CURVE and use it.
+
+2007-04-13 Marcus Brinkmann <marcus@g10code.de>
+
+ * ac.c (ac_data_construct): Cast const away to suppress compiler
+ warning.
+
+ * ecc.c (ecc_generate): Avoid compiler warning for unused argument
+ DUMMY.
+ (ecc_verify): Avoid compiler warning for unused arguments CMP and
+ OPAQUEV.
+
+2007-04-06 Werner Koch <wk@g10code.com>
+
+ * sha1.c (oid_spec_sha1): Add another oid from X9.62.
+
+2007-03-28 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Do not issue misc-key-info if it is
+ empty.
+ (gcry_pk_genkey): New parameter "curve".
+
+ * ecc.c: Entirely rewritten with only a few traces of the old
+ code left.
+ (_gcry_ecc_generate): New.
+ (generate_key) New arg NAME.
+ (generate_curve): Ditto. Return actual number of NBITS.
+
+2007-03-26 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Increase size of SKEY array and add a
+ runtime bounds check.
+
+2007-03-23 Werner Koch <wk@g10code.com>
+
+ * ecc.c (ecc_ctx_init, ecc_ctx_free, ecc_mod, ecc_mulm): New.
+ (duplicate_point, sum_points, escalar_mult): Don't use a
+ copy of base->p. Replaced all mpi_mulm by ecc_mulm so that we can
+ experiment with different algorithms.
+ (generate_key, check_secret_key, sign, verify): Initialize a
+ computation context for use by ecc_mulm.
+
+2007-03-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (pubkey_table): Initialize ECC.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add ecc.c.
+ * ecc.c: New. Heavily reformatted and changed for use in libgcrypt.
+ (point_init): New.
+ (escalar_mult): Make arg R the first arg to be similar to the mpi
+ functions.
+ (duplicate_point): Ditto
+ (sum_points): Ditto
+ (sign, verify): Remove unneeded copy operations.
+ (sum_points): Removed memory leaks and optimized some compares.
+ (verify): Simplified input check.
+
+2007-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (MASK_LEVEL): Removed macro as it was used only at one
+ place. Open coded it there.
+ (gcry_randomize, _gcry_update_random_seed_file)
+ (_gcry_fast_random_poll): Factor lock code out to ..
+ (lock_pool, unlock_pool): .. new.
+ (initialize): Look the pool while allocating.
+ (read_random_source, do_fast_random_poll): Moved intialization to ...
+ (initialize): .. here.
+ (_gcry_enable_quick_random_gen): No more need for initialization.
+ (is_initialized): Moved this global flag to ..
+ (initialize): .. here and changed all users to unconditionally call
+ initialize.
+ (add_randomness): Remove initalization here. It simply can't
+ happen.
+
+ * random.c (enum random_origins): Moved to ..
+ * rand-internal.h: .. here.
+ * rndunix.c (_gcry_rndunix_gather_random): Use enum in prototype
+ for ORIGIN and renamed REQUESTOR to ORIGIN.
+ * rndegd.c (_gcry_rndegd_gather_random): Ditto.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Ditto.
+ * rndw32.c (_gcry_rndw32_gather_random): Ditto.
+ (_gcry_rndw32_gather_random_fast): Ditto.
+
+2007-03-13 Werner Koch <wk@g10code.com>
+
+ * random.c (enum random_origins): New.
+ (add_randomness): Renamed arg SOURCE to ORIGIN.
+ (read_random_source): Renamed arg REQUESTOR to ORIGIN.
+ (getfnc_gather_random): Removed static variable because this
+ function is only called one and thus we don't need this
+ optimization.
+ (_gcry_quick_random_gen): Removed and replaced by..
+ (_gcry_enable_quick_random_gen): .. this. It is onlyu used to
+ enable it and it does not make sense to disable it later. Changed
+ the only one caller too.
+ (get_random_bytes): Removed.
+ (gcry_random_bytes, gcry_random_bytes_secure): Implement in terms
+ of gcry_randomize.
+ * random-daemon.c (_gcry_daemon_get_random_bytes): Removed.
+
+2007-02-23 Werner Koch <wk@g10code.com>
+
+ * elgamal.c (generate): Removed unused variable TEMP.
+ (test_keys): New arg NODIE.
+ (generate_using_x, _gcry_elg_generate_using_x): New.
+ * pubkey.c (pubkey_generate): New arg XVALUE and direct call to
+ the new elgamal generate fucntion.
+ (gcry_pk_genkey): Parse the new "xvalue" tag.
+
+2007-02-22 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Handle dynamically allocated
+ algorithms. Suggested by Neil Dunbar. Fixes bug#596.
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): Make it return void.
+
+ * cipher.c (gcry_cipher_algo_name): Simplified.
+
+ * random.c: Use the daemon only if compiled with USE_RANDOM_DAEMON.
+
+ * Makefile.am (libcipher_la_SOURCES): Build random-daemon support
+ only if requested.
+
+2007-02-21 Werner Koch <wk@g10code.com>
+
+ * random.c (rndpool, keypool): Make unsigned.
+ (mix_pool): Change char* variables to unsigned char*.
+ (gcry_randomize): Make arg BUFFER a void*.
+ (gcry_create_nonce): Ditto.
+
+ * rmd160.c (gcry_rmd160_mixblock): Make BUFFER a void*.
+ (_gcry_rmd160_hash_buffer): Make OUTBUF and BUFFER void*.
+ * sha1.c (_gcry_sha1_hash_buffer): Ditto.
+
+ * cipher.c (gcry_cipher_encrypt, cry_cipher_decrypt): Change
+ buffer args to void*.
+ (gcry_cipher_register): Make ALGORITHM_ID a int *.
+
+ * md.c (md_start_debug): Make SUFFIX a const char*. Use snprintf.
+ (gcry_md_debug): New.
+ (gcry_md_ctl): Changed arg BUFFER from unsigned char*.
+
+ * md.c (md_write): Make INBUF a const void*.
+ (gcry_md_write): Remove needless cast.
+ * crc.c (crc32_write): Make INBUF a const void*
+ (update_crc32, crc24rfc2440_write): Ditto.
+ * sha512.c (sha512_write, transform): Ditto.
+ * sha256.c (sha256_write, transform): Ditto.
+ * rmd160.c (rmd160_write, transform): Ditto.
+ * md5.c (md5_write, transform): Ditto.
+ * md4.c (md4_write, transform): Ditto.
+ * sha1.c (sha1_write, transform): Ditto.
+
+ * tiger.c (tiger_write, transform): Ditto.
+ * whirlpool.c (whirlpool_write, whirlpool_add, transform): Ditto.
+
+ * elgamal.c (elg_names): Change to a const*.
+ * dsa.c (dsa_names): Ditto.
+ * rsa.c (rsa_names): Ditto.
+ * pubkey.c (gcry_pk_lookup_func_name): Make ALIASES a const.
+
+2007-02-20 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (open_device): Remove unsused arg MINOR.
+
+2007-01-30 Werner Koch <wk@g10code.com>
+
+ * sha256.c (oid_spec_sha256): Add alias from pkcs#1.
+ * sha512.c (oid_spec_sha512): Ditto.
+ (oid_spec_sha384): Ditto.
+
+2006-12-18 Werner Koch <wk@g10code.com>
+
+ * rndlinux.c (set_cloexec_flag): New.
+ (open_device): Set close-on-exit flags. Suggested by Max
+ Kellermann. Fixes Debian#403613.
+
+ * Makefile.am (AM_CPPFLAGS, AM_CFLAGS): Splitted and merged
+ Moritz' changes.
+ (INCLUDES): Removed.
+
+2006-11-30 Werner Koch <wk@g10code.com>
+
+ * serpent.c (byte_swap_32): Remove trailing semicolon.
+
+2006-11-15 Werner Koch <wk@g10code.com>
+
+ * Makefile.am (INCLUDES): Include ../src/
+
+2006-11-03 Werner Koch <wk@g10code.com>
+
+ * random.c [HAVE_GETTIMEOFDAY]: Included sys/time.h and not
+ sys/times.h. Reported by Rafaël Carré.
+
+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-25 Werner Koch <wk@g10code.com>
+
+ * primegen.c (prime_generate_internal): Tweaked use of secure
+ memory and entropy use. Safe unused primes from the pool. Allocate
+ at least a pool of 30.
+ (save_pool_prime, get_pool_prime): New.
+
+2006-10-23 Werner Koch <wk@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Reset sexp_tmp for failsafe
+ means. Release sexp_cur if needed. Reported by Dirk Stoecker.
+
+ * pubkey.c (pubkeys_registered_lock): Intialized it. It is not
+ realy needed because this is a mere initialization to 0 anyway.
+ Noted by Victor Stinner.
+
+2006-10-17 Werner Koch <wk@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate2): New.
+ (generate): New arg QBITS. Add sanity checks for reasonable qbits
+ and nbits.
+ * pubkey.c (gcry_pk_genkey): Parse an qbits element.
+ (pubkey_generate): New arg QBITS. Pass it to the DSA generation.
+
+2006-10-05 Werner Koch <wk@g10code.com>
+
+ * md.c (gcry_md_algo_info) <get_asnoid>: Check that the algo is
+ available.
+
+2006-10-04 David Shaw <dshaw@jabberwocky.com> (wk)
+
+ * tiger.c (round): Rename to tiger_round as gcc 4 has a built-in
+ round function that this conflicts with.
+
+2006-09-11 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (slow_gatherer_windowsNT): While adding data use the
+ size of the diskPerformance and not its address. Has been fixed in
+ GnuPG more than a year ago. Noted by Lee Fisher.
+
+2006-08-30 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (sexp_data_to_mpi): Need to allow "ripemd160" here as
+ this is the canonical name.
+
+2006-08-29 Hye-Shik Chang <perky@FreeBSD.org> (wk)
+
+ * seed.c: New.
+
+2006-08-03 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): Don't
+ initialize the socket. Remove arg SOCKETNAME.
+ (connect_to_socket): Make sure that daemon is set to -1 on error.
+ (call_daemon): Initialize the socket on the first call.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): New arg SOCKETNAME.
+ * random.c (initialize): Call new daemon initializator.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Pass socket
+ name to daemon call and reset allow_daemon on failure.
+
+2006-07-26 Werner Koch <wk@g10code.com>
+
+ * rmd160.c (_gcry_rmd160_mixblock): Add cast to transform call.
+
+ * blowfish.c (selftest): Cast string to usnigned char*.
+
+ * primegen.c (prime_generate_internal): Cast unsigned/char*
+ mismatch in calling m_out_of_n.
+ (is_prime): Changed COUNT to unsigned int *.
+
+ * ac.c (_gcry_ac_data_copy): Initialize DATA_MPIS.
+
+ * random.c (gcry_create_nonce): Update the pid after a fork.
+ Reported by Uoti Urpala.
+
+2006-07-04 Marcus Brinkmann <marcus@g10code.de>
+
+ * sha512.c: Fix typo in copyright notice.
+
+2006-06-21 Werner Koch <wk@g10code.com>
+
+ * rsa.c (_gcry_rsa_generate): Replace xcalloc by calloc.
+ * pubkey.c (gcry_pk_encrypt, gcry_pk_sign): Ditto.
+ (sexp_to_key, sexp_to_sig, sexp_to_enc, gcry_pk_encrypt)
+ (gcry_pk_sign, gcry_pk_genkey, gcry_pk_get_keygrip): Ditto.
+ * md.c (md_copy): Ditto.
+
+2006-04-22 Moritz Schulte <moritz@g10code.com>
+
+ * random-daemon.c (_gcry_daemon_initialize_basics): New argument:
+ SOCKETNAME. Passing on to connect_to_socket() if non-NULL.
+ (connect_to_socket, writen, readn, call_daemon): New functions.
+ (_gcry_daemon_randomize, _gcry_daemon_get_random_bytes)
+ (_gcry_daemon_create_nonce): Call call_daemon().
+ (RANDOM_DAEMON_SOCKET): New symbol.
+ (daemon_socket): New static variable.
+
+ * random.h (_gcry_daemon_initialize_basics): New parameter:
+ SOCKETNAME.
+ (_gcry_set_random_daemon_socket): New declaration.
+
+ * random.c (initialize_basics): Pass DAEMON_SOCKET_NAME to
+ _gcry_daemon_initialize_basics.
+ (_gcry_set_random_daemon_socket): New function, setting
+ DAEMON_SOCKET_NAME.
+
+2006-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (eme_pkcs_v1_5_encode): Use KEY_SIZE directly, no need to
+ call gcry_ac_key_get_nbits.
+ (eme_pkcs_v1_5_decode): Likewise.
+ (ac_es_dencode_prepare_pkcs_v1_5): Fill options_em structure with
+ key_size.
+ (_gcry_ac_data_dump, gcry_ac_data_dump): New functions.
+ (_gcry_ac_data_to_sexp, _gcry_ac_data_from_sexp): More or less
+ rewritten; changed S-Expression format so that it matches the one
+ used in pubkey.c.
+
+2006-03-15 Werner Koch <wk@g10code.com>
+
+ * random-daemon.c: New.
+ * random.c (_gcry_use_random_daemon): New.
+ (get_random_bytes, gcry_randomize, gcry_create_nonce): Try
+ diverting to the daemon functions.
+
+2006-03-14 Werner Koch <wk@g10code.com>
+
+ * random.c (lock_seed_file): New.
+ (read_seed_file, _gcry_update_random_seed_file): Use it.
+
+ * random.c (gcry_create_nonce): Detect a fork and re-seed.
+ (read_pool): Fixed the fork detection; it used to work only for
+ multi-threaded processes.
+
+2006-03-12 Brad Hards <bradh@frogmouth.net> (wk)
+
+ * md.c (md_open): Use new variable macpads_Bsize instead of
+ hardwiring the block size. Changed at all places.
+
+2006-03-10 Brad Hards <bradh@frogmouth.net> (wk, patch 2005-04-22)
+
+ * md.c, sha256.c: Add support for SHA-224.
+ (sha224_init): New.
+
+2006-01-18 Brad Hards <bradh@frogmouth.net> (wk 2006-03-07)
+
+ * cipher.c (cipher_encrypt, cipher_decrypt, do_ofb_encrypt)
+ (do_ofb_decrypt, gcry_cipher_open): Implement Output Feedback Mode.
+
+2005-11-02 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_name): Return "?" instead of NULL for
+ unknown algorithm IDs.
+ * cipher.c (cipher_algo_to_string): Likewise.
+
+2005-11-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_algo_info): Don't forget to break after switch
+ case.
+
+2005-09-19 Werner Koch <wk@g10code.com>
+
+ * dsa.c (generate): Add preliminary support for 2 and 4 keys.
+ Return an error code if the key size is not supported.
+ (_gcry_dsa_generate): Return an error.
+
+2005-08-22 Werner Koch <wk@g10code.com>
+
+ * primegen.c (check_prime): New arg RM_ROUNDS.
+ (prime_generate_internal): Call it here with 5 rounds as used
+ before.
+ (gcry_prime_check): But here with 64 rounds.
+ (is_prime): Make sure never to use less than 5 rounds.
+
+2005-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_init): New function.
+
+2005-04-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_io_write, _gcry_ac_io_read): Initialize err to
+ make the compiler happy.
+ Always use errno, now that gcry_malloc() is guaranteed to set
+ errno on failure.
+ (_gcry_ac_data_to_sexp): Don't forget to goto out after error in
+ loop.
+ (_gcry_ac_data_to_sexp): Remove unused variable: mpi_list;
+ (_gcry_ac_data_to_sexp): Always deallocate sexp_buffer.
+ (_gcry_ac_data_from_sexp): Don't forget to initialize data_set_new.
+ (_gcry_ac_data_from_sexp): Handle special case, which is
+ necessary, since gcry_sexp_nth() does not distinguish between
+ "element does not exist" and "element is the empty list".
+ (_gcry_ac_io_init_va): Use assert to make sure that mode and type
+ are correct.
+ Use gcry_error_t types where gcry_err_code_t types have been used
+ before.
+
+2005-04-11 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_sign_scheme): Don't forget to initialize
+ buffer.
+
+ * whirlpool.c: New file.
+ * md.c (digest_table): Add whirlpool.
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Added: whirlpool.c.
+
+2005-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (_gcry_ac_data_from_sexp): Use length of SEXP_CUR, not
+ length of SEXP; do not forget to set SEXP_TMP to NULL after it has
+ been released.
+
+ (struct gcry_ac_mpi): New member: name_provided.
+ (_gcry_ac_data_set): Rename variable `name_final' to `name_cp';
+ remove const qualifier; change code to not cast away const
+ qualifiers; use name_provided member as well.
+ (_gcry_ac_data_set, _gcry_ac_data_get_name): Use name_provided
+ member of named mpi structure.
+
+ (gcry_ac_name_to_id): Do not forget to initialize err.
+ (_gcry_ac_data_get_index): Do not forget to initialize mpi_return;
+ use gcry_free() instead of free(); remove unnecessary cast; rename
+ mpi_return and name_return to mpi_cp and name_cp; adjust code.
+ (ac_data_mpi_copy): Do not cast away const qualifier.
+ (ac_data_values_destroy): Likewise.
+ (ac_data_construct): Likewise.
+
+ (ac_data_mpi_copy): Initialize flags to GCRY_AC_FLAG_DEALLOC.
+ (ac_data_extract): Use GCRY_AC_FLAG_DEALLOC instead of
+ GCRY_AC_FLAG_COPY.
+
+ (_gcry_ac_io_init_va, _gcry_ac_io_init, gcry_ac_io_init)
+ (gcry_ac_io_init_va, _gcry_ac_io_write, _gcry_ac_io_read)
+ (_gcry_ac_io_read_all, _gcry_ac_io_process): New functions.
+ (gry_ac_em_dencode_t): Use gcry_ac_io_t in prototype instead of
+ memroy strings directly; adjust encode/decode functions to use io
+ objects.
+ (emsa_pkcs_v1_5_encode_data_cb): New function ...
+ (emsa_pkcs_v1_5_encode): ... use it here.
+ (ac_data_dencode): Use io objects.
+ (_gcry_ac_data_encode, _gcry_ac_data_decode, gcry_ac_data_encode)
+ (gcry_ac_data_decode): Likewise.
+ (_gcry_ac_data_encrypt_scheme, gcry_ac_data_encrypt_scheme)
+ (_gcry_ac_data_decrypt_scheme, gcry_ac_data_decrypt_scheme)
+ (_gcry_ac_data_sign_scheme, gcry_ac_data_sign_scheme)
+ (_gcry_ac_data_verify_scheme, gcry_ac_data_verify_scheme):
+ Likewise.
+
+2005-03-23 Werner Koch <wk@g10code.com>
+
+ * rndw32.c (_gcry_rndw32_gather_random_fast): While adding data
+ use the size of the object and not the one of its address. Bug
+ reported by Sascha Kiefer.
+
+2005-03-19 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (do_cbc_encrypt): Be careful to not overwrite data,
+ which is to be used later on. This happend, in case CTS is
+ enabled and OUTBUF is equal to INBUF.
+
+2005-02-25 Werner Koch <wk@g10code.com>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow for shadowed-private-key.
+
+2005-02-13 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Updated from 1.2 branch:
+
+ s/u32_t/u32/ and s/byte_t/byte/. Too match what we have always
+ used and are using in all other files too
+ (serpent_test): Moved prototype out of a fucntion.
+
+2005-02-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Major parts rewritten.
+ * pubkey.c (_gcry_pk_get_elements): New function.
+
+2004-12-09 Werner Koch <wk@g10code.com>
+
+ * serpent.c (serpent_setkey): Moved prototype of serpent_test to
+ outer scope.
+
+2004-09-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (pubkey_table): Added an alias entry for GCRY_PK_ELG_E.
+
+2004-08-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Do not include <assert.h>.
+ * rndegd.c: Likewise.
+ * sha1.c: Likewise.
+ * rndunix.c: Likewise.
+ * rndlinux.c: Likewise.
+ * rmd160.c: Likewise.
+ * md5.c: Likewise.
+ * md4.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * pubkey.c (dummy_generate, dummy_check_secret_key)
+ (dummy_encrypt, dummy_decrypt, dummy_sign, dummy_verify): Return
+ err code GPG_ERR_NOT_IMPLEMENTED instead of aborting through
+ log_bug().
+ (dummy_get_nbits): Return 0 instead of aborting though log_bug().
+
+2004-08-19 Werner Koch <wk@g10code.de>
+
+ * pubkey.c (sexp_data_to_mpi): Changed the zero random byte
+ substituting code to actually do clever things. Thanks to
+ Matthias Urlichs for noting the implementation problem.
+
+2004-08-09 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_sign): Fixed memory leak; fix provided by
+ Modestas Vainius.
+
+2004-07-16 Werner Koch <wk@gnupg.org>
+
+ * rijndael.c (do_encrypt): Fix alignment problem. Bugs found by
+ Matthias Urlichs.
+ (do_decrypt): Ditto.
+ (keySched, keySched2): Use 2 macros along with unions in the key
+ schedule context.
+
+2004-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_decrypt): Don't forget to free "a". Thanks to
+ Nikos Mavroyanopoulos.
+
+2004-05-09 Werner Koch <wk@gnupg.org>
+
+ * random.c (read_pool): Mix the PID in to better protect after a
+ fork.
+
+2004-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * serpent.c: Use "u32_t" instead of "unsigned long", do not
+ declare S-Box variables as "register". Fixes failure on
+ OpenBSD/sparc64, reported by Nikolay Sturm.
+
+2004-05-07 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Factored out some code to ..
+ (initialize_basics): .. new function.
+ (_gcry_random_initialize): Just call initialize_basics unless the
+ new arg FULL is set to TRUE.
+ (_gcry_fast_random_poll): Don't do anything unless the random
+ system has been really initialized.
+
+2004-05-07 Moritz Schulte <moritz@g10code.de>
+
+ * ac.c (gcry_ac_open): Do not dereference NULL pointer. Reported
+ by Umberto Salsi.
+
+2004-02-20 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (check_prime): New args CB_FUNC and CB_ARG; call them
+ at different stages. Pass these arguments through all callers.
+
+2004-02-06 Werner Koch <wk@gnupg.org>
+
+ * des.c: Add a new OID as used by pkcs#12.
+
+ * rfc2268.c: New. Taken from libgcrypt.
+ * cipher.c: Setup the rfc2268 algorithm.
+
+2004-01-25 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (prime_generate_internal): Do not forget to free
+ `q_factor'; fixed by Brieuc Jeunhomme.
+ (prime_generate_internal): Do not forget to free `prime'.
+
+2004-01-14 Moritz Schulte <mo@g10code.com>
+
+ * ac.c (gcry_ac_data_set): New argument: flags; slightly
+ rewritten.
+ (gcry_ac_data_get_name, gcry_ac_data_get_index): Likewise.
+ (gcry_ac_key_pair_generate): New argument: misc_data; modified
+ order of arguments.
+ (gcry_ac_key_test): New argument: handle.
+ (gcry_ac_key_get_nbits, gcry_ac_key_get_grip): Likewise.
+ Use GCRY_AC_FLAG_NO_BLINDING instead of
+ GCRY_AC_DATA_FLAG_NO_BLINDING.
+ (gcry_ac_mpi): New member: flags.
+ (gcry_ac_data_search, gcry_ac_data_add): Removed functions.
+
+2003-12-22 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (is_prime): Release A2.
+
+2003-12-19 Werner Koch <wk@gnupg.org>
+
+ * md.c: Moved a couple of functions down below the data structure
+ definitions.
+ (struct gcry_md_context): New field ACTUAL_HANDLE_SIZE.
+ (md_open): Set it here.
+ (strcut gcry_md_list): New field ACTUAL_STRUCT_SIZE.
+ (md_enable): Set it here.
+ (md_close): Wipe the context memory.
+ secure memory.
+ * cipher.c (struct gcry_cipher_handle): New field ACTUAL_HANDLE_SIZE.
+ (gcry_cipher_open): Set it here.
+ (gcry_cipher_close): Use it to always wipe out the handle data.
+
+ * ac.c (gcry_ac_open): Make sure HANDLE gets initialized even when
+ the function is not successful.
+ (gcry_ac_close): Allow a NULL handle.
+ (gcry_ac_key_destroy, gcry_ac_key_pair_destroy): Ditto.
+ (gcry_ac_key_get_grip): Return INV_OBJ on error.
+
+ * primegen.c (prime_generate_internal): Fixed error code for
+ failed malloc. Replaced the !err if chain by gotos.
+ (gcry_prime_group_generator): Remove the extra sanity check.
+
+ * md.c: Minor code and comment cleanups.
+
+2003-12-16 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Doc fix. Thanks to Newton Hammet.
+
+2003-12-11 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (slow_poll): Don't use #warning but #error.
+
+ * rndegd.c: Changed indentation.
+ (my_make_filename): Removd the var_arg cruft becuase we
+ don't need it here. Changed caller.
+
+ * rndlinux.c: Changed indentation.
+ (open_device): Remove the superfluous stat call and clarify
+ comment.
+
+ * rsa.c: Changed indentation.
+ (secret): Use the standard algorithm if p, q and u are not
+ available.
+ (rsa_blind, rsa_unblind): Renamed from _gcry_rsa_blind,
+ _gcry_rsa_unblind and moved more to the top.
+
+ * md4.c: Changed indentation. Removed unnecessary casts.
+ * md5.c, rmd160.c, sha1.c, tiger.c: Ditto.
+ * rijndael.c, twofish.c: Ditto.
+ * serpent.c: Removed unnecessary casts.
+ * sha256.c, sha512.c: Ditto.
+
+2003-12-09 Werner Koch <wk@gnupg.org>
+
+ * dsa.c: Unified indentation style.
+ * elgamal.c: Ditto.
+ * des.c (des_key_schedule): Code beautifications.
+ * blowfish.c: Changed indentation style.
+ * cast5.c (do_cast_setkey): Ditto.
+
+ * pubkey.c (gcry_pk_encrypt): Replaced the chain of if(!err) tests
+ by straightforward gotos. Other cleanups.
+ (gcry_pk_decrypt): Ditto.
+ (gcry_pk_sign): Ditto.
+ (gcry_pk_verify): Ditto.
+ (gcry_pk_genkey): Ditto. Use strtoul instead of strtol.
+ (gcry_pk_ctl): Use GPG_ERR_INV_ARG to indicate bad arguments.
+
+2003-12-07 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_register_default): Undef the helper macro.
+ (gcry_pk_map_name): Allow NULL for string.
+ (sexp_to_key): Use memcpy and not strncpy. Use gcry_free and not
+ free.
+ (sexp_to_sig): Ditto.
+ (sexp_to_enc): Ditto. Replaced the chain of if(!err) tests by
+ straightforward gotos.
+
+2003-12-05 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Documentation cleanups.
+ (gcry_cipher_mode_from_oid): Allow NULL for STRING.
+
+2003-12-03 Werner Koch <wk@gnupg.org>
+
+ * elgamal.c (sign, do_encrypt, gen_k): Make sure that a small K is
+ only used for encryption.
+
+2003-11-18 Werner Koch <wk@gnupg.org>
+
+ * random.h (rndw32_set_dll_name): Removed unused prototype.
+
+ * Makefile.am (EXTRA_DIST): Added Manifest.
+
+2003-11-11 Werner Koch <wk@gnupg.org>
+
+ * Manifest: New.
+
+2003-11-04 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Use shortcut for SHA1
+ * sha1.c (_gcry_sha1_hash_buffer): New.
+
+ * random.c: Reformatted most functions.
+ (mix_pool): Moved the failsafe_digest from global
+ scope to here.
+ (do_fast_random_poll): Use the generic fucntions even if a fast
+ gathering function has been used.
+ (read_pool): Detect a fork and retry.
+ (gcry_randomize, get_random_bytes): Don't distinguish anymore
+ between weak and strong random.
+ (gcry_create_nonce): New.
+
+2003-10-31 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (slow_gatherer_windowsNT): Use a plain buffer for the
+ disk performance values and not the W32 API structure.
+
+ * dsa.c (verify): s/exp/ex/ due to shadowing of a builtin.
+ * elgamal.c (verify): Ditto.
+
+ * ac.c (gcry_ac_data_get_index): s/index/idx/
+ (gcry_ac_data_copy_internal): Remove the cast in _gcry_malloc.
+ (gcry_ac_data_add): Must use gcry_realloc instead of realloc.
+ * pubkey.c (sexp_elements_extract): s/index/idx/ as tribute to the
+ forehackers.
+ (gcry_pk_encrypt): Removed shadowed definition of I. Reordered
+ arguments to malloc for clarity.
+ (gcry_pk_sign, gcry_pk_genkey): Ditto.
+ * primegen.c (prime_generate_internal): s/random/randomlevel/.
+
+2003-10-27 Moritz Schulte <mo@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Don't forget to deallocate pkey.
+
+2003-10-27 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Return if buflen is zero to
+ avoid gcc warning about unsed parameter.
+ (MASK_LEVEL): Simplified; does now work for signed and unsigned
+ w/o warnings.
+
+ * md.c (md_start_debug): Removed the const from SUFFIX, because
+ this function is called from the control fucntion which does not
+ require const.
+
+ Prefixed all (pubkey,digest,cipher}_spec_* globale variables with
+ _gcry_.
+
+ * ac.c (ac_key_identifiers): Made static.
+
+ * random.c (getfnc_gather_random,getfnc_fast_random_poll): Move
+ prototypes to ..
+ * rand-internal.h: .. here
+ * random.c (getfnc_gather_random): Include rndw32 gatherer.
+ * rndunix.c, rndw32.c, rndegd.c: Include them here.
+ * rndlinux.c (_gcry_rndlinux_gather_random): Prepend the _gcry_
+ prefix. Changed all callers.
+ * rndegd.c (_gcry_rndegd_gather_random): Likewise.
+ (_gcry_rndegd_connect_socket): Likewise.
+ * rndunix.c (_gcry_rndunix_gather_random): Likewise.
+ (waitpid): Made static.
+ * rndw32.c: Removed the old and unused winseed.dll cruft.
+ (_gcry_rndw32_gather_random_fast): Renamed from
+ gather_random_fast.
+ (_gcry_rndw32_gather_random): Renamed from gather_random. Note,
+ that the changes 2003-04-08 somehow got lost.
+
+ * sha512.c (sha512_init, sha384_init): Made static.
+
+ * cipher.c (do_ctr_decrypt): Removed "return" from this void
+ function.
+
+2003-10-24 Moritz Schulte <mo@g10code.com>
+
+ * serpent.c: Fix an issue on big-endian systems.
+
+ * rndw32.c: Removed IS_MODULE -cruft.
+ * rndlinux.c (rndlinux_gather_random): Likewise.
+
+2003-10-10 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Bail out if NBITS is less than 16.
+ (prime_generate_internal): Initialize prime variable to suppress
+ compiler warning. Check pbits, initialize qbits when passed as
+ zero.
+
+ * primegen.c (prime_generate_internal): New arg
+ ALL_FACTORS. Changed all callers.
+ (gcry_prime_generate): Make the factors arg optional. Request
+ all_factors. Make sure PRIME is set to NULL even on error.
+ (gcry_prime_group_generator): New.
+ (gcry_prime_release_factors): New.
+
+2003-10-06 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): Assert that NBITS is never zero, it
+ would cause a segv.
+
+2003-09-28 Moritz Schulte <mo@g10code.com>
+
+ * ac.c: Include "cipher.h".
+
+2003-09-27 Moritz Schulte <mo@g10code.com>
+
+ * rndegd.c (do_read): Return nread instead of nbytes; thanks to
+ Michael Caerwyn.
+
+2003-09-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (_gcry_pk_aliased_algo_name): New.
+ * ac.c (gcry_ac_open): Use it here.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Add serpent.c
+
+2003-09-02 Moritz Schulte <mo@g10code.com>
+
+ * primegen.c (gcry_prime_check, gcry_prime_generate): New
+ functions.
+ (prime_generate_internal): New function, based on
+ _gcry_generate_elg_prime.
+ (_gcry_generate_elg_prime): Rewritten as a wrapper for
+ prime_generate_internal.
+
+2003-08-28 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Don't include the flags list in the
+ return value. This does not make sense and breaks any programs
+ parsing the output strictly (e.g. current gpgsm).
+ (gcry_pk_encrypt): If aliases for the algorithm name exists, take
+ the first one instead of the regular name to adhere to SPKI
+ conventions.
+ (gcry_pk_genkey): Ditto.
+ (gcry_pk_sign): Ditto. Removed unused KEY_ALGO_NAME.
+
+2003-08-19 Moritz Schulte <mo@g10code.com>
+
+ * cipher.c: Add support for Serpent
+ * serpent.c: New file.
+
+2003-08-10 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind, _gcry_rsa_unblind): Declare static.
+
+2003-08-09 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (getfnc_gather_random): Don't check NAME_OF_DEV_RANDOM
+ two times, but also the NAME_OF_DEV_URANDOM device.
+
+2003-08-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_enc): Fixed extraction of S-Expression: do not
+ fail if no `flags' sub S-Expression is found.
+
+2003-07-27 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_lookup_func_oid): Allow for empty OID lists.
+
+2003-07-23 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_construct): New argument: include_flags, only
+ include `flags' S-expression, if include_flags is true. Adjust
+ callers. Thanks for triggering a bug caused by `flags'
+ sub-S-expression where they are not expected to Ralf Schneider.
+
+2003-07-21 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_lookup_func_name): Use new member name
+ `aliases' instead of `sexp_names'.
+
+ * ac.c (gcry_ac_key_data_get): New function.
+
+ * cipher.c (gcry_cipher_lookup_func_name): Fix return value.
+
+2003-07-20 Moritz Schulte <moritz@g10code.com>
+
+ * blowfish.c: Adjusted for new gcry_cipher_spec_t structure.
+ * cast5.c: Likewise.
+ * twofish.c: Likewise.
+ * arcfour.c: Likewise.
+ * rijndael.c (rijndael_oids, rijndael192_oids, rijndael256_oids):
+ New variables, adjust for new gcry_cipher_spec_t structure.
+ * des.c (oids_tripledes): New variable, adjust for new
+ gcry_cipher_spec_t structure.
+
+ * md.c (oid_table): Removed.
+
+ * tiger.c (oid_spec_tiger): New variable.
+ (digest_spec_tiger): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha512): New variable.
+ (digest_spec_sha512): Adjusted for new gry_md_spec_t structure.
+
+ * sha512.c (oid_spec_sha384): New variable.
+ (digest_spec_sha384): Adjusted for new gry_md_spec_t structure.
+
+ * sha256.c (oid_spec_sha256): New variable.
+ (digest_spec_sha256): Adjusted for new gry_md_spec_t structure.
+
+ * sha1.c (oid_spec_sha1): New variable.
+ (digest_spec_sha1): Adjusted for new gry_md_spec_t structure.
+
+ * rmd160.c (oid_spec_rmd160): New variable.
+ (digest_spec_rnd160): Adjusted for new gry_md_spec_t structure.
+
+ * md5.c (oid_spec_md5): New variable.
+ (digest_spec_md5): Adjusted for new gry_md_spec_t structure.
+
+ * md4.c (oid_spec_md4): New variable.
+ (digest_spec_md4): Adjusted for new gry_md_spec_t structure.
+
+ * crc.c (digest_spec_crc32, digest_spec_crc32_rfc1510,
+ digest_spec_crc32_rfc2440): Adjusted for new gry_md_spec_t
+ structure.
+
+2003-07-19 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_lookup_func_oid): New function.
+ (search_oid): New function, copied from cipher.c.
+ (gcry_md_map_name): Adjust for new search_oid_interface.
+
+ * cipher.c (oid_table): Removed table.
+ (gcry_cipher_lookup_func_oid): New function.
+ (search_oid): Rewritten to use the module functions.
+ (gcry_cipher_map_name): Adjust for new search_oid interface.
+ (gcry_cipher_mode_from_oid): Likewise.
+
+2003-07-18 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Convert ERR to gpg_error_t in
+ gpg_strerror.
+
+2003-07-14 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_lookup_func_name): Also check the cipher
+ name aliases, not just the primary name.
+ (gcry_cipher_map_name): Remove kludge for aliasing Rijndael to
+ AES.
+
+ * arcfour.c, blowfish.c, cast5.c, des.c, twofish.c: Adjust cipher
+ specification structures.
+
+ * rijndael.c (rijndael_names, rijndael192_names,
+ rijndael256_names): New variables, use them in the cipher
+ specifications.
+
+ * rmd160test.c: Removed file.
+
+ * ac.c, arcfour.c, blowfish.c, cast5.c, cipher.c, des.c, dsa.c,
+ elgamal.c, md.c, pubkey.c, random.c, rijndael.c, rsa.c, twofish.c:
+ Used gcry_err* wrappers for libgpg symbols.
+
+ * primegen.c (gen_prime): Correct the order arguments to
+ extra_check.
+
+2003-07-12 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: Replaced all public occurences of gpg_error_t with
+ gcry_error_t.
+ * cipher.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * random.c: Likewise.
+
+ * cipher.c: Added support for TWOFISH128.
+
+2003-07-08 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_copy_internal): New function, based on
+ gcry_ac_data_copy.
+ (gcry_ac_data_copy): Made public, use gcry_ac_data_copy_internal.
+ (gcry_ac_key_init): Use gcry_ac_data_copy_internal.
+
+2003-07-07 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c (gcry_ac_data_set): Only release old MPI value if it is
+ different from the new value. Bug reported by Simon Josefsson
+ <jas@extundo.com>.
+
+ * pubkey.c (gcry_pk_list): New function.
+ * md.c (gcry_md_list): New function.
+
+ * ac.c (gcry_ac_key_pair_generate): Fix calculation of format
+ string size.
+
+2003-07-05 Moritz Schulte <moritz@g10code.com>
+
+ * md.c: Named struct of digest_table `digest_table_entry'.
+ (digest_table_entry): New member: algorithm; filled in.
+ (digest_table_entry): Removed unused member: flags.
+ (gcry_md_register): New argument: algorithm_id, filled in.
+ (gcry_md_register_default): Used algorithm ID from module
+ structure.
+ (gcry_md_map_name): Likewise.
+ (md_enable): Likewise.
+ (md_read): Likewise.
+ (gcry_md_info): Likewise.
+
+ * pubkey.c: Named truct for pubkey_table `pubkey_table_entry'.
+ (pubkey_table_entry): New member: algorithm; filled in.
+ (gcry_pk_register_default): Used algorithm ID from pubkey_table.
+ (gcry_pk_register): New argument: algorithm_id, filled in.
+ (gcry_pk_map_name): Used algorithm ID from module structure.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (sexp_to_key): Removed unused variable: algo.
+ (sexp_to_sig): Likewise.
+
+ * cipher.c: Named struct for cipher_table `cipher_table_entry'.
+ (cipher_table_entry): New member: algorithm; filled in.
+ (gcry_cipher_register_default): Used algorithm ID from
+ cipher_table.
+ (gcry_cipher_register): New argument: algorithm_id, filled in.
+ (gcry_cipher_map_name): Used algorithm ID from module structure.
+
+ * arcfour.c (cipher_spec_arcfour): Removed algorithm ID.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+ * cast5.c (cipher_spec_cast5): Likewise.
+ * crc.c (digest_spec_crc32): Likewise.
+ * crc.c (digest_spec_crc32_rfc1510): Likewise.
+ * crc.c (digest_spec_crc32_rfc2440): Likewise.
+ * des.c (cipher_spec_des): Likewise.
+ * des.c (cipher_spec_tripledes): Likewise.
+ * dsa.c (pubkey_spec_dsa): Likewise.
+ * elgamal.c (pubkey_spec_elg): Likewise.
+ * md4.c (digest_spec_md4): Likewise.
+ * md5.c (digest_spec_md5): Likewise.
+ * aes.c (cipher_spec_aes): Likewise.
+ * aes.c (cipher_spec_aes192): Likewise.
+ * aes.c (cipher_spec_aes256): Likewise.
+ * rsa.c (pubkey_spec_rsa): Likewise.
+ * sha1.c (digest_spec_sha1): Likewise.
+ * sha256.c (digest_spec_sha256): Likewise.
+ * sha512.c (digest_spec_sha512): Likewise.
+ * tiger.c (digest_spec_tiger): Likewise.
+ * twofish.c (cipher_spec_twofish): Likewise.
+ * twofish.c (cipher_spec_twofish128): Likewise.
+
+ * Makefile.am (EXTRA_libcipher_la_SOURCES): Fix list of source
+ files; reported by Simon Josefsson <jas@extundo.com>.
+
+ * pubkey.c: Replaced all occurences of `id' with `algorithm',
+ since `id' is a keyword in obj-c.
+ * md.c: Likewise.
+ * cipher.c: Likewise.
+
+ * crc.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, tiger.c:
+ Replaced all occurences of gcry_digest_spec_t with gcry_md_spec_t.
+
+ * dsa.c, rsa.c, elgamal.c: Replaced all occurencens of
+ gcry_pubkey_spec_t with gcry_pk_spec_t.
+
+ * md.c: Replaced all occurences of gcry_digest_spec_t with
+ gcry_md_spec_t.
+ (gcry_digest_register_default): Renamed to ...
+ (gcry_md_register_default): ... this; adjusted callers.
+ (gcry_digest_lookup_func_name): Renamed to ...
+ (gcry_md_lookup_func_name): ... this; adjusted callers.
+ (gcry_digest_lookup_name): Renamed to ...
+ (gcry_md_lookup_name): ... this; adjusted callers.
+ (gcry_digest_register): Renamed to ...
+ (gcry_md_register): ... this.
+ (gcry_digest_unregister): Renamed to ...
+ (gcry_md_unregister): ... this.
+
+ * pubkey.c (gcry_pubkey_register): Renamed to ...
+ (gcry_pk_register): ... this.
+ (gcry_pubkey_unregister): Renamed to ...
+ (gcry_pk_unregister): ... this.
+ Replaced all occurences of gcry_pubkey_spec_t with gcry_pk_spec_t.
+ (gcry_pubkey_register_default): Renamed to ...
+ (gcry_pk_register_default): ... this; adjusted callers.
+ (gcry_pubkey_lookup_func_name): Renamed to ...
+ (gcry_pk_lookup_func_name): ... this; adjusted callers.
+ (gcry_pubkey_lookup_name): Renamed to ...
+ (gcry_pk_lookup_name): ... this; adjusted callers.
+
+ * md.c (gcry_md_hash_buffer): Fix error checking. Thanks to Simon
+ Josefsson <jas@extunde.com>.
+
+2003-07-04 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_list): New function.
+
+2003-07-01 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_sig): Accept a `flags' S-expression to be more
+ consistent with sexp_to_enc.
+
+2003-06-30 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Added: ac.c.
+
+ * pubkey.c (_gcry_pk_module_lookup): New function.
+ (_gcry_pk_module_release): New function.
+
+2003-06-29 Moritz Schulte <moritz@g10code.com>
+
+ * ac.c: New file.
+
+2003-06-26 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Trigger BUG correcly with new API.
+
+2003-06-19 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_is_enabled): Fixed.
+
+2003-06-18 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_get_algo_keylen): New.
+ (gcry_cipher_get_algo_blklen): New.
+
+2003-06-18 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, cipher.c, blowfish.c, md.c, cast5.c, pubkey.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, random.c, rijndael.c,
+ rmd160.c, rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c:
+ Replaced older types GcryDigestSpec, GcryCipherSpec and
+ GcryPubkeySpec with newer types: gcry_digest_spec_t,
+ gcry_cipher_spec_t and gcry_pubkey_spec_t.
+
+ * md.c (gcry_digest_id_new): Removed function.
+ (gcry_digest_register): Removed code for generating a new module
+ ID.
+
+ * pubkey.c (gcry_pubkey_id_new): Removed function.
+ (gcry_pubkey_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c, md.c, pubkey.c: Replace old type GcryModule with newer
+ one: gcry_module_t.
+ (gcry_cipher_id_new): Removed function.
+ (gcry_cipher_register): Removed code for generating a new module
+ ID.
+
+ * cipher.c (gcry_cipher_register): Adjust call to
+ _gcry_module_add.
+ (gcry_cipher_register_default): Likewise.
+ * pubkey.c (gcry_pubkey_register_default): Likewise.
+ (gcry_pubkey_register): Likewise.
+ * md.c (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+
+ * md.c (gcry_digest_lookup_func_id): Removed function.
+ (gcry_digest_lookup_id): Likewise.
+ (gcry_digest_id_new): Use _gcry_module_lookup_id instead of
+ gcry_digest_lookup_id.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+ * pubkey.c (gcry_pubkey_lookup_id): Removed function.
+ (gcry_pubkey_lookup_func_id): Likewise.
+ (gcry_pubkey_id_new): Use _gcry_module_lookup_id instead of
+ gcry_pubkey_id_new.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_lookup_func_id): Removed function.
+ (gcry_cipher_lookup_id): Likewise.
+ (cipher_algo_to_string): use _gcry_module_lookup_id instead of
+ gcry_cipher_lookup_id.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (gcry_cipher_id_new): Likewise.
+
+2003-06-17 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (GCRYPT_MODULES): Set to @GCRYPT_CIPHERS@,
+ @GCRYPT_PUBKEY_CIPHERS@, @GCRYPT_DIGESTS@ and @GCRYPT_RANDOM@.
+ (libcipher_la_DEPENDENCIES): Set to $(GCRYPT_MODULES).
+ (libcipher_la_LIBADD): Likewise.
+ (AM_CFLAGS): Added: @GPG_ERROR_CFLAGS@.
+ (EXTRA_libcipher_la_SOURCES): Added all conditional sources.
+
+ * md.c (md_open): Use _gcry_fast_random_poll instead of
+ fast_random_poll.
+ * cipher.c (gcry_cipher_open): Likewise.
+
+ * random.h (fast_random_poll): Removed macro.
+
+ * blowfish.c, md4.c, md5.c, rmd160.c, sha1.c, sha256.c, sha512.c,
+ tiger.c: Use Autoconf's WORDS_BIGENDIAN instead of our own
+ BIG_ENDIAN_HOST.
+
+2003-06-16 Moritz Schulte <moritz@g10code.com>
+
+ * random.c (getfnc_gather_random): Do not special-case
+ USE_ALL_RANDOM_MODULES, make it the default.
+
+ * dsa.c: Replace last occurences of old type names with newer
+ names (i.e. replace MPI with gcry_mpi_t).
+ * elgamal.c: Likewise.
+ * primegen.c: Likewise.
+ * pubkey.c: Likewise.
+ * rsa.c: Likewise.
+
+2003-06-14 Moritz Schulte <moritz@g10code.com>
+
+ * des.c (des_setkey): Add selftest check.
+ (tripledes_set3keys): Likewise.
+ (do_tripledes_setkey): Remove selftest check.
+ (do_des_setkey): Likewise.
+
+2003-06-11 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (_gcry_md_init): New function.
+ * cipher.c (_gcry_cipher_init): New function.
+ * pubkey.c (_gcry_pk_init): New function.
+
+2003-06-13 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_get_algo): Reverted to old API. This is a
+ convenience function anyway and error checking is not approriate.
+ (gcry_md_is_secure): New.
+ (gcry_md_is_enabled): New.
+
+2003-06-12 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_open): Make sure HANDLE is set to NULL on
+ error.
+
+2003-06-11 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_open): Make sure H receives either NULL or an
+ valid handle.
+ (gcry_md_copy): Swapped arguments so that it is more in lione with
+ md_open and most other API fucntions like memcpy (destination
+ comes first). Make sure HANDLE is set to NULL on error.
+
+ * rijndael.c (do_encrypt): Hack to force correct alignment. It
+ seems not to be not sufficient, though. We should rework this
+ fucntions and remove all these ugly casts. Let the compiler
+ optimize or have an assembler implementation.
+
+2003-06-09 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Removed rules serpent, since that is not commited
+ yet.
+
+2003-06-08 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Improve calculation for size of the
+ format string.
+
+2003-06-07 Moritz Schulte <moritz@g10code.com>
+
+ * arcfour.c, bithelp.h, blowfish.c, cast5.c, cipher.c, crc.c,
+ des.c, dsa.c, elgamal.c, md4.c, md5.c, md.c, primegen.c, pubkey.c,
+ rand-internal.h, random.c, random.h, rijndael.c, rmd160.c,
+ rmd160test.c, rmd.h, rndeged.c, rndlinux.c, rndunix.c, rndw32.c,
+ rsa.c, sha1.c, sha256.c, sha512.c, tiger.c, twofish.c: Edited all
+ preprocessor instructions to remove whitespace before the '#'.
+ This is not required by C89, but there are some compilers out
+ there that don't like it. Replaced any occurence of the now
+ deprecated type names with the new ones.
+
+2003-06-04 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_encrypt): Construct an arg_list and use
+ gcry_sexp_build_array instead of gcry_sexp_build.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_genkey): Likewise.
+
+2003-06-01 Moritz Schulte <moritz@g10code.com>
+
+ * dsa.c (_gcry_dsa_generate): Do not check wether the algorithm ID
+ does indeed belong to DSA.
+ (_gcry_dsa_sign): Likewise.
+ (_gcry_dsa_verify): Likewise.
+ (_gcry_dsa_get_nbits): Likewise.
+
+ * elgamal.c (_gcry_elg_check_secret_key): Do not check wether the
+ algorithm ID does indeed belong to ElGamal.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ (_gcry_elg_get_nbits): Likewise.
+ (_gcry_elg_generate): Likewise.
+
+ * rsa.c (_gcry_rsa_generate): Do not check wether the algorithm ID
+ does indeed belong to RSA.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ (_gcry_rsa_get_nbits): Likewise.
+
+2003-05-30 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_get_algo): Return zero in case to algorithm is enabled.
+
+ * md.c (gcry_md_info): Adjusted for new no-errno-API.
+ (md_final): Likewise.
+ (gcry_md_get_algo): Likewise.
+ * pubkey.c (gcry_pk_get_keygrip): Likewise.
+ (gcry_pk_ctl): Likewise.
+ (gcry_pk_algo_info): Likewise.
+ * des.c (selftest): Likewise.
+
+2003-05-29 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Do not forget to release module on error.
+ (gcry_md_open): Adjusted for new no-errno-API.
+ (md_open): Likewise.
+ (md_copy): Likewise.
+ (gcry_md_copy): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_algo_info): Likewise.
+
+ * cipher.c (gcry_cipher_open): Adjusted for new no-errno-API and
+ also fixed a locking bug.
+ (gcry_cipher_encrypt): Adjusted for new no-errno-API.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+
+2003-05-28 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (md_enable): Adjusted for libgpg-error.
+ (gcry_md_enable): Likewise.
+ (gcry_digest_register_default): Likewise.
+ (gcry_digest_register): Likewise.
+ (check_digest_algo): Likewise.
+ (prepare_macpads): Likewise.
+ (gcry_md_setkey): Likewise.
+ (gcry_md_ctl): Likewise.
+ (gcry_md_get): Likewise.
+ (gcry_md_algo_info): Likewise.
+ (gcry_md_info): Likewise.
+ * dsa.c (_gcry_dsa_generate): Likewise.
+ (_gcry_dsa_check_secret_key): Likewise.
+ (_gcry_dsa_sign): Likewie.
+ (_gcry_dsa_verify): Likewise.
+ * twofish.c (do_twofish_setkey): Likewise.
+ (twofish_setkey): Likewise.
+ * cipher.c (gcry_cipher_register): Likewise.
+
+2003-05-25 Moritz Schulte <moritz@g10code.com>
+
+ * rijndael.c (do_setkey): Adjusted for libgpg-error.
+ (rijndael_setkey): Likewise.
+ * random.c (gcry_random_add_bytes): Likewise.
+ * elgamal.c (_gcry_elg_generate): Likewise.
+ (_gcry_elg_check_secret_key): Likewise.
+ (_gcry_elg_encrypt): Likewise.
+ (_gcry_elg_decrypt): Likewise.
+ (_gcry_elg_sign): Likewise.
+ (_gcry_elg_verify): Likewise.
+ * rsa.c (_gcry_rsa_generate): Likewise.
+ (_gcry_rsa_check_secret_key): Likewise.
+ (_gcry_rsa_encrypt): Likewise.
+ (_gcry_rsa_decrypt): Likewise.
+ (_gcry_rsa_sign): Likewise.
+ (_gcry_rsa_verify): Likewise.
+ * pubkey.c (dummy_generate, dummy_check_secret_key, dummy_encrypt,
+ dummy_decrypt, dummy_sign, dummy_verify): Likewise.
+ (gcry_pubkey_register): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (sexp_elements_extract): Likewise.
+ (sexp_to_key): Likewise.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+ (sexp_data_to_mpi): Likewise.
+ (gcry_pk_encrypt): Likewise.
+ (gcry_pk_decrypt): Likewise.
+ (gcry_pk_sign): Likewise.
+ (gcry_pk_verify): Likewise.
+ (gcry_pk_testkey): Likewise.
+ (gcry_pk_genkey): Likewise.
+ (gcry_pk_ctl): Likewise.
+ * cipher.c (dummy_setkey): Likewise.
+ (check_cipher_algo): Likewise.
+ (gcry_cipher_open): Likewise.
+ (cipher_setkey): Likewise.
+ (gcry_cipher_ctl): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (gcry_cipher_info): Likewise.
+ (gcry_cipher_algo_info): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (do_cast_setkey): Likewise.
+ * arcfour.c (arcfour_setkey): Likewise.
+ (do_arcfour_setkey): Likewise.
+ * blowfish.c (do_bf_setkey): Likewise.
+ (bf_setkey): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_tripledes_setkey): Likewise.
+
+2003-05-22 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c: Merged code ussing the U64_C macro from GnuPG.
+
+ * sha512.c: Likewise.
+
+2003-05-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Fix type: acquire a lock, instead of
+ releasing it.
+
+2003-05-11 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_testkey): Call REGISTER_DEFAULT_CIPHERS.
+ (gcry_pk_ctl): Likewise.
+
+2003-04-27 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (gcry_pk_genkey): Release sexp after extracted data has
+ been used.
+
+ * md.c (gcry_md_get_algo_dlen): Simplified, simply call
+ md_digest_length to do the job.
+
+ * des.c (do_des_setkey): Check for selftest failure not only
+ during initialization.
+ (do_tripledes_setkey): Include check for selftest failure.
+
+ * pubkey.c (gcry_pubkey_register_default): New macro
+ `pubkey_use_dummy', use it.
+
+ * elgamal.c (elg_names): New variable.
+ (pubkey_spec_elg): Include elg_names.
+
+ * dsa.c (dsa_names): New variable.
+ (pubkey_spec_dsa): Include dsa_names.
+
+ * rsa.c (rsa_names): New variable.
+ (pubkey_spec_rsa): Include rsa_names.
+
+ * pubkey.c (gcry_pubkey_lookup_func_name): Compare name also with
+ the names listed in `sexp_names'.
+
+2003-04-24 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_to_key): New variables: module, pubkey. Adjusted
+ to new module interface.
+ (sexp_to_key): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers. Removed argument:
+ r_algotblidx.
+ (sexp_to_sig): Changend type of argument `retalgo' from `int *' to
+ `GcryModule **'. Adjusted all callers.
+ (sexp_to_enc): Likewise.
+
+ (pubkey_get_npkey, pubkey_get_nskey, pubkey_get_nsig,
+ pubkey_get_nenc): Use strlen to find out the number.
+
+ * rsa.c: Adjust pubkey_spec_rsa to new internal interface.
+ * dsa.c: Likewise.
+ * elgamal.c: Likewise.
+
+2003-04-17 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c (sexp_elements_extract): New function.
+ * pubkey.c (sexp_to_key): Removed variable `idx', added `err', use
+ sexp_elements_extract.
+ (sexp_to_sig): Likewise.
+ (sexp_to_enc): Likewise.
+
+ * pubkey.c: Terminate list correctly.
+ * md.c: Include sha512/sha384 in digest_table.
+
+2003-04-16 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am: Include support for sha512.c.
+
+ * sha512.c: New file, merged from GnuPG, with few modifications
+ for libgcrypt.
+
+ * rand-internal.h: Removed declarations for constructor functions.
+
+ * md.c (md_copy): Call _gcry_module_use for incrementing the usage
+ counter of the digest modules.
+
+ * rsa.c: Do not include "rsa.h".
+ * dsa.c: Do not include "dsa.h".
+ * elgamal.c: Do not include "elgamal.h".
+ * des.c: Do not include "des.h".
+ * cast5.c: Do not include "cast5.h".
+ * blowfish.c: Do not include "blowfish.h".
+ * arcfour.c: Do not include "arcfour.h".
+
+ * Makefile.am (libcipher_la_DEPENDENCIES): Removed.
+ (libcipher_la_LIBADD): Removed.
+ Use Automake conditionals for conditional compilation.
+
+2003-04-13 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (gcry_cipher_open): Call REGISTER_DEFAULT_CIPHERS.
+
+ * md.c (gcry_md_list): New member: module.
+ (md_enable): New variable: module, changed use of module and
+ digest.
+ (md_enable): Initialize member: module.
+ (md_close): Call _gcry_module_release.
+
+ * cipher.c (gcry_cipher_open): New variable: module, changed use of
+ module and cipher.
+ (struct gcry_cipher_handle): New member: module.
+ (gcry_cipher_open): Initialize member: module.
+ (gcry_cipher_close): Call _gcry_module_release.
+
+2003-04-09 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Include "ath.h".
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+
+ * cipher.c (ciphers_registered_lock): New variable.
+ * md.c (digests_registered_lock): New variable.
+ * pubkey.c (pubkeys_registered_lock): New variable.
+
+ * rndlinux.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndlinux_constructor): Removed function.
+
+ * rndegd.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndegd_constructor): Removed function.
+
+ * rndunix.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndunix_constructor): Removed function.
+
+ * rndw32.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rndw32_constructor): Removed function.
+
+ * rndegd.c (rndegd_connect_socket): Simplify code for creating the
+ egd socket address.
+ (rndegd_connect_socket): Call log_fatal use instead of
+ g10_log_fatal.
+ (egd_gather_random): Renamed to ...
+ (rndegd_gather_random): ... here.
+
+2003-04-08 Moritz Schulte <moritz@g10code.com>
+
+ * rndlinux.c: Do not include "dynload.h".
+ * rndunix.c: Likewise.
+ * rndw32.c: Likewise.
+
+ * rndegd.c (rndegd_connect_socket): Factored out from ...
+ (egd_gather_random): here; call it.
+ (egd_socket): New variable.
+ (egd_gather_random): Initialize fd with egd_socket, do not declare
+ fd static.
+ (do_read): Merged few changes from GnuPG. FIXME - not finished?
+ Do not include "dynload.h".
+
+ * rndw32.c (gather_random): Renamed to rndw32_gather_random, do
+ not declare static.
+ (gather_random_fast): Renamed to rndw32_gather_random_fast, do not
+ declare static.
+
+ * rndunix.c (gather_random): Renamed to rndunix_gather_random, do
+ not declare static.
+ * rndegd.c (gather_random): Renamed to rndegd_gather_random, do
+ not declare static.
+ * rndlinux.c (gather_random): Renamed to rndlinux_gather_random,
+ do not declare static.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * Makefile.am (libcipher_la_SOURCES): Removed construct.c.
+ (libcipher_la_SOURCES): Added sha1.c, sha256.c, rmd160.c, md4.c,
+ md5.c, tiger.c and crc.c
+ (EXTRA_PROGRAMS): Removed sha1, sha256, rmd160, md4, md5, tiger
+ and crc. Removed definitions: EXTRA_md4_SOURCES,
+ EXTRA_md5_SOURCES, EXTRA_rmd160_SOURCES, EXTRA_sha1_SOURCES,
+ EXTRA_sha256_SOURCES, EXTRA_tiger_SOURCES and EXTRA_crc_SOURCES,
+ BUILT_SOURCES, DISTCLEANFILES.
+
+ * pubkey.c: Do not include "elgamal.h", "dsa.h" and "rsa.h".
+
+ * Makefile.am (libcipher_la_SOURCES): Removed rsa.h, elgamal.h,
+ dsa.h, des.h, cast5.h, arcfour.h and blowfish.h.
+
+ * rsa.h: Removed file.
+ * elgamal.h: Removed file.
+ * dsa.h: Removed file.
+ * des.h: Removed file.
+ * cast5.h: Removed file.
+ * arcfour.h: Removed file.
+ * blowfish.h: Removed file.
+
+ * Makefile.am (libcipher_la_SOURCES): Removed dynload.c and
+ dynload.h.
+
+ * rsa.c (pubkey_spec_rsa): New variable.
+ * dsa.c (pubkey_spec_rsa): New variable.
+ * elgamal.c (pubkey_spec_elg): New variable.
+
+ * rsa.c (_gcry_rsa_get_info): Removed function.
+ * elgamal.c (_gcry_elg_get_info): Removed function.
+ * dsa.c (_gcry_dsa_get_info): Removed function.
+
+ * tiger.c (tiger_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_tiger_constructor): Removed function.
+
+ * sha1.c (sha1_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha1_constructor): Removed function.
+
+ * sha256.c (sha256_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_sha256_constructor): Removed function.
+
+ * rmd160.c (rmd160_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_rmd160_constructor): Removed function.
+
+ * md5.c (md5_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md5_constructor): Removed function.
+
+ * md4.c (md4_get_info): Removed function.
+ (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func): Removed function.
+ (_gcry_md4_constructor): Removed function.
+
+ * crc.c (crc_get_info): Removed function.
+
+ * arcfour.c (do_arcfour_setkey): Changed type of context argument
+ to `void *', added local variable for cast, adjusted callers.
+ (arcfour_setkey): Likewise.
+ (encrypt_stream): Likewise.
+ * cast5.c (cast_setkey): Likewise.
+ (encrypt_block): Likewise.
+ * rijndael.c (rijndael_setkey): Likewise.
+ (rijndael_encrypt): Likewise.
+ (rijndael_decrypt): Likewise.
+ * twofish.c (twofish_setkey): Likewise.
+ (twofish_encrypt): Likewise.
+ (twofish_decrypt): Likewise.
+ * des.c (do_des_setkey): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_des_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ * blowfish.c (bf_setkey: Likewise.
+ (encrypt_block): Likewise.
+ (decrypt_block): Likewise.
+
+ * arcfour.c (encrypt_stream): Likewise.
+
+ * rijndael.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * twofish.c (gnupgext_version, func_table): Removed definitions.
+ (gnupgext_enum_func) Removed function.
+
+ * cast5.c (CIPHER_ALGO_CAST5): Removed.
+
+ * blowfish.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+ (CIPHER_ALGO_BLOWFISH): Removed symbol.
+ * cast5.c (FNCCAST_SETKEY, FNCCAST_CRYPT): Likewise.
+ * des.c (selftest_failed): Removed.
+ (initialized): New variable.
+ (do_des_setkey): Run selftest, if not yet done.
+ (FNCCAST_SETKEY, FNCCAST_CRYPT): Removed macros.
+
+ * arcfour.c (_gcry_arcfour_get_info): Removed function.
+ * blowfish.c (_gcry_blowfish_get_info): Removed function.
+ * cast5.c (_gcry_cast5_get_info): Removed function.
+ * des.c (_gcry_des_get_info): Removed function.
+ * rijndael.c (_gcry_rijndael_get_info): Removed function.
+ * twofish.c (_gcry_twofish_get_info): Removed function.
+
+ * arcfour.c (cipher_spec_arcfour): New variable.
+ * twofish.c (cipher_spec_twofish, cipher_spec_twofish128): New
+ variables.
+ * rijndael.c (cipher_spec_aes, cipher_spec_aes192,
+ cipher_spec256): New variables.
+ * des.c (cipher_spec_des, cipher_spec_tripledes): New variables.
+ * cast5.c (cipher_spec_cast5): New variable.
+ * blowfish.c (cipher_spec_blowfish): Likewise.
+
+ * twofish.c: Do not include "dynload.h".
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+ * cipher.c: Likewise.
+ * crc.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * md.c: Likewise.
+ * pubkey.c: Likewise.
+ * rijndael.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+
+ * arcfour.c: Include "cipher.h".
+ * twofish.c: Likewise.
+ * rijndael.c: Likewise.
+ * des.c: Likewise.
+ * cast5.c: Likewise.
+ * blowfish.c: Likewise.
+
+ * twofish.c (twofish_setkey): Declared argument `key' const.
+ (twofish_encrypt): Declared argument `inbuf' const.
+ (twofish_decrypt): Likewise.
+
+ * rijndael.c (rijndael_setkey): Declared argument `key' const.
+ (rijndael_encrypt): Declared argument `inbuf' const.
+ (rijndael_decrypt): Likewise.
+
+ * des.c (do_des_setkey): Declared argument `key' const.
+ (do_tripledes_setkey): Likewise.
+ (do_des_encrypt): Declared argument `inbuf' const.
+ (do_des_decrypt): Likewise.
+ (do_tripledes_encrypt): Likewise.
+ (do_tripledes_decrypt): Likewise.
+
+ * cast5.c (encrypt_block): Declared argument `inbuf' const.
+ (decrypt_block): Likewise.
+ (cast_setkey): Declared argument `key' const.
+
+ * blowfish.c (do_bf_setkey): Declared argument `key' const.
+ (encrypt_block): Declared argument `inbuf' const.
+ (encrypt_block): Likewise.
+
+
+
+ * cipher.c: Remove CIPHER_ALGO_DUMMY related code.
+ Removed struct cipher_table_s.
+ Changed definition of cipher_table.
+ Removed definition of disabled_algos.
+ (ciphers_registered, default_ciphers_registered): New variables.
+ (REGISTER_DEFAULT_CIPHERS): New macro.
+ (dummy_setkey): Declared argument `key' const.
+ (dummy_encrypt_block): Declared argument `inbuf' const.
+ (dummy_encrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_setkey): Use `unsigned char' instead of `byte'.
+ (dummy_encrypt_block): Likewise.
+ (dummy_decrypt_block): Likewise.
+ (dummy_encrypt_stream): Likewise.
+ (dummy_decrypt_stream): Likewise.
+ (gcry_cipher_register_default): New function.
+ (gcry_cipher_lookup_func_id): New function.
+ (gcry_cipher_lookup_func_name): New function.
+ (gcry_cipher_lookup_id): New function.
+ (gcry_cipher_lookup_name): New function.
+ (gcry_cipher_id_new): New function.
+ (gcry_cipher_register): New function.
+ (gcry_cipher_unregister): New function.
+ (setup_cipher_table): Removed function.
+ (load_cipher_modules): Removed function.
+ (gcry_cipher_map_name): Adjusted to use new module management.
+ (cipher_algo_to_string): Likewise.
+ (disable_cipher_algo): Likewise.
+ (check_cipher_algo): Likewise.
+ (cipher_get_keylen): Likewise.
+ (cipher_get_blocksize): Likewise.
+ (gcry_cipher_open): Likewise.
+ (struct gcry_cipher_handle): Replaced members algo, algo_index,
+ blocksize, setkey, encrypt, decrypt, stencrypt, stdecrypt with one
+ member: cipher.
+ (gcry_cipher_open): Adjusted code for new handle structure.
+ (cipher_setkey): Likewise.
+ (cipher_setiv): Likewise.
+ (cipher_reset): Likewise.
+ (do_ecb_encrypt): Likewise.
+ (do_ecb_decrypt): Likewise.
+ (do_cbc_encrypt): Likewise.
+ (do_cbc_decrypt): Likewise.
+ (do_cfb_encrypt): Likewise.
+ (do_cfb_decrypt): Likewise.
+ (do_ctr_encrypt): Likewise.
+ (cipher_encrypt): Likewise.
+ (gcry_cipher_encrypt): Likewise.
+ (cipher_decrypt): Likewise.
+ (gcry_cipher_decrypt): Likewise.
+ (cipher_sync): Likewise.
+ (gcry_cipher_ctl): Likewise.
+
+ * pubkey.c: Removed struct pubkey_table_s.
+ Changed definition of pubkey_table.
+ Removed definition of disabled_algos.
+ (pubkeys_registered, default_pubkeys_registered): New variables.
+ (REGISTER_DEFAULT_PUBKEYS): New macro.
+ (setup_pubkey_table): Removed function.
+ (load_pubkey_modules): Removed function.
+ (gcry_pubkey_register_default): New function.
+ (gcry_pubkey_lookup_func_id): New function.
+ (gcry_pubkey_lookup_func_name): New function.
+ (gcry_pubkey_lookup_id): New function.
+ (gcry_pubkey_lookup_name): New function.
+ (gcry_pubkey_id_new): New function.
+ (gcry_pubkey_register): New function.
+ (gcry_pubkey_unregister): New function.
+ (gcry_pk_map_name): Adjusted to use new module management.
+ (gcry_pk_algo_name): Likewise.
+ (disable_pubkey_algo): Likewise.
+ (check_pubkey_algo): Likewise.
+ (pubkey_get_npkey): Likewise.
+ (pubkey_get_nskey): Likewise.
+ (pubkey_get_nsig): Likewise.
+ (pubkey_get_nenc): Likewise.
+ (pubkey_generate): Likewise.
+ (pubkey_check_secret_key): Likewise.
+ (pubkey_encrypt): Likewise.
+ (pubkey_decrypt): Likewise.
+ (pubkey_sign): Likewise.
+ (pubkey_verify): Likewise.
+ (gcry_pk_get_nbits): Likewise.
+ (gcry_pk_algo_info): Likewise.
+
+ * md.c: Removed struct md_digest_list_s.
+ (digest_list): Changed definition.
+ (digests_registered, default_digests_registered): New variables.
+ (REGISTER_DEFAULT_DIGESTS): New macro.
+ (new_list_item): Removed function.
+ (setup_md_table): Removed function.
+ (load_digest_module): Removed function.
+ (gcry_digest_register_default): New function.
+ (gcry_digest_lookup_func_id): New function.
+ (gcry_digest_lookup_func_name): New function.
+ (gcry_digest_lookup_id): New function.
+ (gcry_digest_lookup_name): New function.
+ (gcry_digest_id_new): New function.
+ (gcry_digest_register): New function.
+ (gcry_digest_unregister): New function.
+ (GcryDigestEntry): New type.
+ (struct gcry_md_context): Adjusted type of `list'.
+ (gcry_md_map_name): Adjusted to use new module management.
+ (digest_algo_to_string): Likewise.
+ (check_digest_algo): Likewise.
+ (md_enable): Likewise.
+ (md_digest_length): Likewise.
+ (md_asn_oid): Likewise.
+
+2003-04-07 Moritz Schulte <moritz@g10code.com>
+
+ * pubkey.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA,
+ PUBKEY_ALGO_RSA with GCRY_PK_RSA and PUBKEY_ALGO_ELGAMAL with
+ GCRY_PK_ELG.
+
+ * dsa.c: Replaced PUBKEY_ALGO_DSA with GCRY_PK_DSA.
+
+2003-04-01 Moritz Schulte <moritz@g10code.com>
+
+ * des.c: Removed checks for GCRY_CIPHER_3DES and GCRY_CIPHER_DES.
+
+2003-03-31 Moritz Schulte <moritz@g10code.com>
+
+ * tiger.c (tiger_get_info): Do not declare static.
+ * sha256.c (sha256_get_info): Likewise.
+ * sha1.c (sha1_get_info): Likewise.
+ * rmd160.c (rmd160_get_info): Likewise.
+ * md5.c (md5_get_info): Likewise.
+ * md4.c (md4_get_info): Likewise.
+ * crc.c (crc_get_info): Likewise.
+
+ * md.c (load_digest_module): Call setup_md_table during
+ initialization.
+ (new_list_item): Link new element into digest_list.
+
+ * cipher.c (do_ctr_decrypt): Made do_ctr_encrypt act as a wrapper
+ for do_ctr_encrypt, since these functions are identical.
+
+2003-03-30 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (struct gcry_cipher_handle): Add counter field.
+ (gcry_cipher_open): Add CTR.
+ (cipher_reset): Clear counter field.
+ (do_ctr_encrypt, do_ctr_decrypt): New functions.
+ (cipher_encrypt, cipher_decrypt): Call CTR functions.
+ (gcry_cipher_ctl): Add SET_CTR to set counter.
+
+2003-03-30 Moritz Schulte <moritz@g10code.com>
+
+ * rsa.c (_gcry_rsa_blind): New function.
+ (_gcry_rsa_unblind): New function.
+ (_gcry_rsa_decrypt): Use _gcry_rsa_blind and _gcry_rsa_decrypt.
+
+2003-03-26 Moritz Schulte <moritz@g10code.com>
+
+ * dynload.c (_gcry_enum_gnupgext_pubkeys): Adjust `encrypt' and
+ `decrypt' function arguments.
+ (_gcry_enum_gnupgext_pubkeys): Likewise.
+ * dynload.h: Likewise.
+
+ * pubkey.c (dummy_decrypt): Add argument: int flags.
+ (dummy_encrypt): Likewise.
+
+ * elgamal.c (_gcry_elg_encrypt): Add argument: int flags.
+ (_gcry_elg_decrypt): Likewise.
+
+ * rsa.c (_gcry_rsa_encrypt): Add argument: int flags.
+ (_gcry_rsa_decrypt): Likewise.
+
+ * pubkey.c: Add `flags' argument to members `encrypt' and
+ `decrypt' of struct `pubkey_table_s'.
+
+ * rsa.h: Add `flags' argument to function declarations.
+ * elgamal.h: Likewise.
+
+ * pubkey.c (sexp_data_to_mpi): New variable: int parsed_flags.
+ (sexp_data_to_mpi): Set `parsed_flags'.
+ (sexp_data_to_mpi): New argument: int *flags.
+ (gcry_pk_encrypt): New variable: int flags.
+ (gcry_pk_encrypt): Pass `flags' to pubkey_encrypt.
+ (pubkey_encrypt): New variable: int flags.
+ (pubkey_encrypt): Pass `flags' to pubkey encrypt function.
+ (pubkey_decrypt): Likewise.
+ (pubkey_decrypt): Pass `flags' to pubkey encrypt function.
+ (gcry_pk_encrypt): Include `flags' s-exp in return list.
+ (sexp_to_enc): New argument: int *flags.
+ (gcry_pk_decrypt): New variable: int flags.
+ (gcry_pk_decrypt): Pass `flags' to pubkey_decrypt.
+ (sexp_to_enc): New variable: int parsed_flags.
+ (sexp_to_enc): Set `parsed_flags'.
+
+2003-03-22 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open, do_cbc_encrypt)
+ (gcry_cipher_encrypt): Support GCRY_CIPHER_CBC_MAC.
+ (gcry_cipher_ctl): Support GCRYCTL_SET_CBC_MAC.
+
+2003-03-19 Werner Koch <wk@gnupg.org>
+
+ * primegen.c (gen_prime): New args EXTRA_CHECK and EXTRA_CHECK_ARG
+ to allow for a user callback. Changed all callers.
+ (_gcry_generate_secret_prime)
+ (_gcry_generate_public_prime): Ditto, pass them to gen_prime.
+ * rsa.c (check_exponent): New.
+ (generate): Use a callback to ensure that a given exponent is
+ actually generated.
+
+2003-03-12 Moritz Schulte <moritz@g10code.com>
+
+ * primegen.c: Initialize `no_of_small_prime_numbers' statically.
+ (gen_prime): Remove calculation of `no_of_small_prime_numbers'.
+
+2003-03-03 Moritz Schulte <moritz@g10code.com>
+
+ * md.c (gcry_md_ctl): Rewritten to use same style like the other
+ functions dispatchers.
+
+2003-03-02 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c (struct gcry_cipher_handle): New member: algo_index.
+ (gcry_cipher_open): Allocate memory for two cipher contexts.
+ Initialize algo_index.
+ (cipher_setkey): Duplicate context into reserved memory.
+ (cipher_reset): New function, which resets the context and clear
+ the IV.
+ (gcry_cipher_ctl): Call cipher_reset.
+
+2003-02-23 Moritz Schulte <moritz@g10code.com>
+
+ * cipher.c: Remove (bogus) `digitp' macro definition.
+ * md.c: Likewise.
+
+ * blowfish.c (burn_stack): Removed.
+ * arcfour.c (burn_stack): Likewise.
+ * cast5.c (burn_stack): Likewise.
+ * des.c (burn_stack): Likewise.
+ * md4.c (burn_stack): Likewise.
+ * md5.c (burn_stack): Likewise.
+ * random.c (burn_stack): Likewise.
+ * rijndael.c (burn_stack): Likewise.
+ * rmd160.c (burn_stack): Likewise.
+ * sha1.c (burn_stack): Likewise.
+ * sha256.c (burn_stack): Likewise.
+ * tiger.c (burn_stack): Likewise.
+ * twofish.c (burn_stack): Likewise.
+
+ * blowfish.c: Changed all occurences of burn_stack to
+ _gcry_burn_stack.
+ * arcfour.c: Likewise.
+ * cast5.c: Likewise.
+ * des.c: Likewise.
+ * md4.c: Likewise.
+ * md5.c: Likewise.
+ * random.c: Likewise.
+ * rijndael.c: Likewise.
+ * rmd160.c: Likewise.
+ * sha1.c: Likewise.
+ * sha256.c: Likewise.
+ * tiger.c: Likewise.
+ * twofish.c: Likewise.
+
+ * arcfour.c (_gcry_arcfour_get_info): Use GCRY_CIPHER_ARCFOUR
+ instead of hard-coded value `301'.
+
+2003-01-24 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_register_random_progress): New.
+ (_gcry_random_progress): New.
+
+ * rndlinux.c (gather_random): Call the random progress function.
+
+2003-01-23 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): New arg USE_E to request a specific public
+ exponent.
+ (_gcry_rsa_generate): Ditto.
+ * elgamal.c (_gcry_elg_generate): Must add an dummy argument
+ instead of USE_E.
+ * dsa.c (_gcry_dsa_generate): Ditto.
+ * pubkey.c (dummy_generate): Ditto.
+ (pubkey_generate): Add USE_E arg and pass it down.
+ (gcry_pk_genkey): Detect "rsa-use-e" parameter and pass it to generate.
+
+ * pubkey.c (sexp_to_enc): New arg RET_MODERN.
+ (gcry_pk_decrypt): Make use of it to return a real S-expression.
+ Return better error codes.
+ (gcry_pk_verify): Return better error codes.
+
+2003-01-21 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_add_bytes): Add QUALITY argument, let
+ function return an error code and disable its core for now.
+
+2003-01-21 Timo Schulz <twoaday@freakmail.de>
+
+ * random.c (gcry_random_add_bytes): New. Function to add external
+ random to the pool.
+
+2003-01-20 Simon Josefsson <jas@extundo.com>
+
+ * crc.c: New.
+ * Makefile.am (EXTRA_PROGRAMS, EXTRA_crc_SOURCES): Add crc.c.
+ * md.c (gcry_md_get_algo_dlen): Add values for CRC.
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * sha256.c: New.
+ * bithelp.h (ror): New.
+ * Makfile.am: Add sha256.c.
+ * md.c (oid_table): Add values for SHA256 et al.
+ (gcry_md_get_algo_dlen): Likewise
+
+2003-01-20 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Implemented keygrips for DSA
+ and ElGamal.
+
+2003-01-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_encrypt): Reworked so that the output will
+ never contain the plaintext even if the caller did not checked the
+ return value.
+
+ * md.c (gcry_md_get_algo): Changed error code to GCRYERR_GENERAL
+ because we don't have an invalid md algo but no algorithm enabled.
+
+ * pubkey.c (gcry_pk_genkey): Changed error code for bounds check
+ of table parameters to GCRYERR_INTERNAL.
+
+ * md.c (gcry_md_open): Partly reverted Timo's change from
+ 2002-10-10 by removing the check for the algorithm. An algorithm
+ of 0 is allowed and anyway we should not double check it or check
+ it using a different function. Also fixed the flags check.
+
+ * pubkey.c (gcry_pk_encrypt): Make sure that R_CIPH points to NULL
+ on error.
+ (gcry_pk_decrypt): Ditto for R_PLAIN.
+ (gcry_pk_sign): Ditto for R_SIG.
+ (gcry_pk_genkey): Ditto for R_KEY.
+
+2003-01-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_write): Changed 2nd argument type to void*.
+ (gcry_md_hash_buffer): Changed type of boths buffers to void*.
+ (gcry_md_setkey): Changed 2nd argument type to void*.
+
+2003-01-15 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (sexp_data_to_mpi): New. This handles pkcs1 padding.
+ (gcry_pk_sign, gcry_pk_verify): Use it here.
+ (gcry_pk_encrypt): And here.
+ (pubkey_verify): Add debug code.
+ (sexp_to_enc): Handle flags in the input and return the pkcs1 flag
+ in a new parameter.
+ (gcry_pk_decrypt): Prepare for future pkcs1 handling.
+
+2002-12-19 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_random_initialize): New.
+
+2002-12-16 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added a Teletrust specific OID for 3DES.
+
+2002-12-12 Werner Koch <wk@gnupg.org>
+
+ * md.c: Added another oddball OIW OID (sha-1WithRSAEncryption).
+
+2002-11-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (load_digest_module): Enlarged checked_algos bitmap.
+ * md4.c (func_table): Fixed entry for md4.
+ Both by Simon Josephson.
+ (transform): Copy data to get the alignment straight. Tested only
+ on i386.
+
+2002-11-10 Simon Josefsson <jas@extundo.com>
+
+ * cipher.c (gcry_cipher_open): Don't reject CTS flag.
+ (do_cbc_encrypt, do_cbc_decrypt, cipher_encrypt)
+ (gcry_cipher_encrypt, cipher_decrypt)
+ (gcry_cipher_decrypt): Support CTS flag.
+ (gcry_cipher_ctl): Toggle CTS flag.
+
+2002-11-10 Werner Koch <wk@gnupg.org>
+
+ * md4.c: New. By Simon Josefsson.
+ * Makefile.am (EXTRA_PROGRAMS): Add md4.c.
+ * md.c (oid_table,gcry_md_get_algo_dlen): MD4 support.
+
+2002-10-14 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Don't use increment op when
+ assigning to the same variable.
+
+2002-10-10 Timo Schulz <ts@winpt.org>
+
+ * pubkey.c (gcry_pk_genkey): Check boundaries.
+
+ * md.c (gcry_md_open): Check that algo is available and only
+ valid flag values are used.
+ (gcry_md_get_algo): Add error handling.
+
+2002-09-26 Werner Koch <wk@gnupg.org>
+
+ * md.c: Include an OID for TIGER.
+ * tiger.c (tiger_get_info): Use a regular OID.
+
+2002-09-17 Werner Koch <wk@gnupg.org>
+
+ * random.c: Replaced mutex.h by the new ath.h. Changed all calls.
+
+2002-09-16 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c (do_encrypt_stream): Use register modifier and modulo.
+ According to Nikos Mavroyanopoulos this increases perfromace on
+ i386 system noticable. And I always tought gcc is clever enough.
+ * md5.c (transform): Use register modifier.
+ * rmd160.c (transform): Ditto.
+ * sha1.c (transform): Ditto. We hope that there are 6 free registers.
+ * random.c (gcry_randomize): Rewrote to avoid malloc calls.
+
+ * rndlinux.c (gather_random): Replaced remaining fprintfs by log_*.
+ * arcfour.c (do_arcfour_setkey): Ditto.
+ * twofish.c (do_twofish_setkey): Ditto.
+ * rndegd.c (gather_random): Ditto.
+ * rijndael.c (do_setkey): Ditto.
+ * random.c (_gcry_random_dump_stats): Ditto.
+ * primegen.c (_gcry_generate_elg_prime): Ditto.
+ * des.c (_gcry_des_get_info): Ditto.
+ * cast5.c (do_cast_setkey): Ditto.
+ * blowfish.c (do_bf_setkey): Ditto.
+
+2002-08-26 Werner Koch <wk@gnupg.org>
+
+ * des.c (weak_keys): Fixed one entry in the table and compared
+ all entries against the literature.
+ (selftest): Checksum the weak key table.
+
+2002-08-21 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Enable keygrip calculation for "openpgp-rsa".
+
+2002-08-17 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (setup_cipher_table): Don't overwrite the DES entry
+ with the entry for DUMMY.
+
+2002-08-14 Werner Koch <wk@gnupg.org>
+
+ * des.c (do_des_setkey,do_des_encrypt, do_des_decrypt): New.
+ (_gcry_des_get_info): Support plain old DES.
+ * cipher.c (setup_cipher_table): Put DES into the table.
+
+2002-07-25 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (_gcry_rndunix_constructor): Prefixed with _gcry_.
+ Noted by Stephan Austermuehle.
+
+2002-07-08 Timo Schulz <ts@winpt.org>
+
+ * rndw32.c: Replaced the m_ memory functions with the real
+ gcry_ functions. Renamed all g10_ prefixed functions to log_.
+
+2002-06-12 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Use e = 65537 for now.
+
+2002-06-11 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): Allow a "protected-private-key".
+
+2002-06-05 Timo Schulz <ts@winpt.org>
+
+ * cipher.c (gcry_cipher_encrypt, gcry_cipher_decrypt):
+ Check that the input size is a multiple of the blocksize.
+
+2002-05-23 Werner Koch <wk@gnupg.org>
+
+ * md.c (oid_table): Add an rsadsi OID for MD5.
+
+2002-05-21 Werner Koch <wk@gnupg.org>
+
+ * primegen.c, elgamal.c, dsa.c (progress): Do not print anything
+ by default. Pass an extra identifying string to the callback and
+ reserved 2 argumenst for current and total counters. Changed the
+ register function prototype.
+
+2002-05-17 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (rndegd_constructor): Fixed name of register function
+ and prefixed the function name with _gcry_.
+ * rndw32.c (rndw32_constructor): Ditto.
+ * tiger.c (tiger_constructor): Ditto.
+
+ * Makefile.am: Removed all dynamic loading stuff.
+ * dynload.c: Ditto. Now only used for the constructor system.
+
+2002-05-15 Werner Koch <wk@gnupg.org>
+
+ * random.c (gcry_random_bytes,gcry_random_bytes_secure)
+ (gcry_randomize): Make sure we are initialized.
+
+2002-05-14 Werner Koch <wk@gnupg.org>
+
+ Changed license of most files to the LGPL.
+
+2002-05-02 Werner Koch <wk@gnupg.org>
+
+ * random.c (_gcry_fast_random_poll): Initialize the module so the
+ mutex can be used.
+
+ * primegen.c (small_prime_numbers): Moved table from smallprime.c
+ * smallprime.c: File removed.
+
+ * des.c (leftkey_swap, rightkey_swap, working_memcmp): Made static.
+
+ * cipher.c (gcry_cipher_map_name): Map "RIJNDAEL" to "AES".
+ * rijndael.c (rijndael_get_info): We do only support a 128 bit
+ blocksize so it makes sense to change the algorithm strings to
+ AES.
+
+ * tiger.c (tiger_final): Removed superfluous token pasting operators.
+ * md5.c (md5_final): Ditto.
+
+2002-04-30 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Fixed list of copyright years.
+
+2002-03-18 Werner Koch <wk@gnupg.org>
+
+ * random.c (initialize): Initialize the new pool lock mutex.
+ (_gcry_fast_random_poll): Add locking and moved main
+ code out to...
+ (do_fast_random_poll): new function.
+ (read_pool): Use the new function here.
+ (get_random_bytes): Add locking.
+ (_gcry_update_random_seed_file): Ditto.
+
+2002-03-11 Werner Koch <wk@gnupg.org>
+
+ * md.c: Add rsaSignatureWithripemd160 to OID table.
+
+2002-02-20 Werner Koch <wk@gnupg.org>
+
+ * sha1.c: Removed a left over comment note. The code has been
+ rewritten from scratch in 1998. Thanks to Niels Möller for
+ reporting this misleading comment.
+
+2002-02-18 Werner Koch <wk@gnupg.org>
+
+ * rndunix.c (rndunix_constructor): Use the the new prefixed
+ function name. Reported by Jordi Mallach.
+
+2002-02-10 Werner Koch <wk@gnupg.org>
+
+ * random.c (mix_pool): Carry an extra failsafe_digest buffer
+ around to make the function more robust.
+
+2002-02-08 Werner Koch <wk@gnupg.org>
+
+ * random.c (add_randomness): Xor new data into the pool and not
+ just copy it. This avoids any choosen input attacks which are not
+ serious in our setting because an outsider won't be able to mix
+ data in and even then we keep going with a PRNG. Thanks to Stefan
+ Keller for pointing this out.
+
+2002-01-04 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_genkey): Do not release skey - it is static.
+
+ * primegen.c (gen_prime): Of course we should use set_bit
+ and not set_highbit to set the second high bit.
+
+2001-12-18 Werner Koch <wk@gnupg.org>
+
+ * rsa.c (generate): Loop until we find the exact modulus size.
+ Changed the exponent to 41.
+ (rsa_get_info): s/usage/r_usage/ to avoid shadow warnings.
+ * primegen.c (gen_prime): Set 2 high order bits for secret primes.
+
+ * Makefile.am (DISTCLEANFILES): Include construct.c.
+
+2001-12-17 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_get_keygrip): New - experimental.
+
+2001-12-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c: Added OIDs for AES.
+ (gcry_cipher_mode_from_oid): New.
+ (gcry_cipher_map_name): Moved OID search code to ..
+ (search_oid): .. new function.
+
+2001-12-10 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (gcry_pk_encrypt): Find the signature algorithm by name
+ and not by number.
+
+ * pubkey.c (gcry_pk_encrypt,gcry_pk_decrypt,gcry_pk_sign)
+ (gcry_pk_verify,gcry_pk_testkey, gcry_pk_genkey)
+ (gcry_pk_get_nbits): Release the arrays. Noted by Nikos
+ Mavroyanopoulos.
+
+2001-12-06 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (gcry_cipher_map_name): Look also for OIDs prefixed
+ with "oid." or "OID.".
+
+2001-12-05 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c (algo_info_table): Fixed entry for openpgp-rsa.
+
+2001-11-24 Werner Koch <wk@gnupg.org>
+
+ * pubkey.c: Added the rsaEncryption OID to the tables.
+ (sexp_to_key): Add an arg to return the index of the algorithm,
+ changed all callers.
+ (gcry_pk_sign): Find the signature algorithm by name and not by
+ number.
+ (gcry_pk_get_nbits): Fixed so that we can now really pass a secret
+ key to get the result.
+
+ * md.c (gcry_md_map_name): Look also for OIDs prefixed with "oid."
+ or "OID." so that an OID string can be used as an S-Exp token.
+
+2001-11-20 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_map_name): Lookup by OID if the the name begins
+ with a digit.
+ (oid_table): New.
+
+2001-11-16 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_info): New operator GCRYCTL_IS_ALGO_ENABLED.
+
+2001-11-07 Werner Koch <wk@gnupg.org>
+
+ * md.c (gcry_md_hash_buffer): Close the handle which was left open
+ for algorithms other than rmd160.
+
+2001-08-08 Werner Koch <wk@gnupg.org>
+
+ * rndw32.c (gather_random): Use toolhelp in addition to the NT
+ gatherer for Windows2000. Suggested by Sami Tolvanen.
+
+ * random.c (read_pool): Fixed length check, this used to be one
+ byte to strict. Made an assert out of it because the caller has
+ already made sure that only poolsize bytes are requested.
+ Reported by Marcus Brinkmann.
+
+2001-08-03 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt, cipher_decrypt): Prepare to return
+ errors. We have to change the interface to all ciphers to make
+ this really work but we should do so to prepare for hardware
+ encryption modules.
+ (gcry_cipher_encrypt, gcry_cipher_decrypt): Return the error and
+ set lasterr.
+ (gcry_cipher_ctl): Make sure that errors from setkey are returned.
+
+2001-08-02 Werner Koch <wk@gnupg.org>
+
+ * rndlinux.c (gather_random): casted a size_t arg to int so that
+ the format string is correct. Casting is okay here and avoids
+ translation changes.
+
+ * random.c (fast_random_poll): Do not check the return code of
+ getrusage.
+
+ * rndunix.c: Add a signal.h header to avoid warnings on Solaris 7
+ and 8.
+
+ * tiger.c (print_abc,print_data): Removed.
+
+ * rijndael.c, des.c, blowfish.c, twofish.c, cast5.c, arcfour.c
+ (burn_stack): New. Add wrappers for most functions to be able to
+ call burn_stack after the function invocation. This methods seems
+ to be the most portable way to zeroise the stack used. It does
+ only work on stack frame based machines but it is highly portable
+ and has no side effects. Just setting the automatic variables at
+ the end of a function to zero does not work well because the
+ compiler will optimize them away - marking them as volatile would
+ be bad for performance.
+ * md5.c, sha1.c, rmd160.c, tiger.c (burn_stack): Likewise.
+ * random.c (burn_stack): New.
+ (mix_pool): Use it here to burn the stack of the mixblock function.
+
+ * primegen.c (_gcry_generate_elg_prime): Freed q at 3 places.
+ Thanks to Tommi Komulainen.
+
+ * arcfour.c (arcfour_setkey): Check the minimim keylength against
+ bytes and not bits.
+ (selftest): Must reset the key before decryption.
+
+2001-05-31 Werner Koch <wk@gnupg.org>
+
+ * sha1.c (sha1_init): Made static.
+
+ Changed all g10_ prefixed function names as well as some mpi_
+ function names to cope with the introduced naming changes.
+
+ * md.c (prepare_macpads): Made key const.
+
+2001-05-28 Werner Koch <wk@gnupg.org>
+
+ * rndegd.c (gather_random): Removed the use of tty_printf.
+
+2001-03-29 Werner Koch <wk@gnupg.org>
+
+ * md5.c (md5_final): Fixed calculation of hashed length. Thanks
+ to disastry@saiknes.lv for pointing out that it was horrible wrong
+ for more than 512MB of input.
+ * sha1.c (sha1_final): Ditto.
+ * rmd160.c (rmd160_final): Ditto.
+ * tiger.c (tiger_final): Ditto.
+
+ * blowfish.c (encrypt,do_encrypt): Changed name to do_encrypt to
+ avoid name clashes with an encrypt function in stdlib.h of
+ Dynix/PIX. Thanks to Gene Carter.
+ * elgamal.c (encrypt,do_encrypt): Ditto.
+
+ * twofish.c (gnupgext_enum_func): Use only when when compiled as a
+ module.
+ * rijndael.c (gnupgext_enum_func): Ditto.
+
+ * tiger.c (tiger_get_info): Return "TIGER192" and not just
+ "TIGER". By Edwin Woudt.
+
+ * random.c: Always include time.h - standard requirement. Thanks
+ to James Troup.
+
+ * rndw32.c: Fixes to the macros.
+
+2001-01-11 Werner Koch <wk@gnupg.org>
+
+ * cipher.c (cipher_encrypt,gcry_cipher_encrypt): Use blocksize and
+ not 8.
+
+2000-12-19 Werner Koch <wk@gnupg.org>
+
+ Major change:
+ Removed all GnuPG stuff and renamed this piece of software
+ to gcrypt.
+
+2000-11-14 Werner Koch <wk@gnupg.org>
+
+ * dsa.c (test_keys): Replaced mpi_alloc by gcry_mpi_new and
+ mpi_free by gcry_mpi_release.
+ * elgamal.c (test_keys,generate): Ditto, also for mpi_alloc_secure.
+ * rsa.c (test_keys,generate,rsa_verify): Ditto.
+ * primegen.c (generate_elg_prime): Ditto.
+ (gen_prime): Ditto and removed nlimbs.
+
+ * rsa.c (generate): Allocate 2 more vars in secure memory.
+
+ * Makefile.am (OMIT_DEPENDENCIES): Hack to work around dependency
+ problems.
+
+2000-10-09 Werner Koch <wk@gnupg.org>
+
+ * arcfour.c, arcfour.h: New.
+ * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode.
+ (setup_cipher_table): Add Arcfour.
+ (gcry_cipher_open): Kludge to allow stream mode.
+
+Wed Oct 4 13:16:18 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sha1.c (transform): Use rol() macro. Actually this is not needed
+ for a newer gcc but there are still aoter compilers.
+
+ * rsa.c (test_keys): Use new random function.
+
+ * md.c (gcry_md_setkey): New function to overcome problems with
+ const conflics.
+ (gcry_md_ctl): Pass set key to the new functions.
+
+ * rijndael.c: New.
+ * cipher.c: Add Rijndael support.
+
+Mon Sep 18 16:35:45 CEST 2000 Werner Koch <wk@openit.de>
+
+ * rndlinux.c (open_device): Loose random device checking.
+ By Nils Ellmenreich.
+
+ * random.c (fast_random_poll): Check ENOSYS for getrusage.
+ * rndunix.c: Add 2 sources for QNX. By Sam Roberts.
+
+ * pubkey.c (gcry_pk_algo_info): Add GCRYCTL_GET_ALGO_USAGE.
+
+ * rsa.c: Changed the comment about the patent.
+ (secret): Speed up by using the CRT. For a 2k keys this
+ is about 3 times faster.
+ (stronger_key_check): New but unused code to check the secret key.
+ * Makefile.am: Included rsa.[ch].
+ * pubkey.c: Enabled RSA support.
+ (pubkey_get_npkey): Removed RSA workaround.
+
+Mon Jul 31 10:04:47 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c: Replaced all gcry_sexp_{car,cdr}_{data,mpi} by the new
+ gcry_sexp_nth_{data,mpi} functions.
+
+Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
+
+ * pubkey.c (exp_to_key,sexp_to_sig,sexp_to_enc,gcry_pk_encrypt,
+ gcry_pk_decrypt,gcry_pk_sign,gcry_pk_genkey): Changed to work with
+ the new S-Exp interface.
+
+Mon Jul 17 16:35:47 CEST 2000 Werner Koch <wk@>
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2) again.
+
+Fri Jul 14 19:38:23 CEST 2000 Werner Koch <wk@>
+
+ * md.c (gcry_md_ctl): Support GCRYCTL_{START,STOP}_DUMP.
+
+ * Makefile.am: Never compile mingw32 as module.
+
+ * Makefile.am: Tweaked module build and removed libtool
+
+ * Makefile.am: Replaced -O1 by -O. Suggested by Alec Habig.
+
+ * elgamal.c (sign): Removed inactive code.
+
+ * rsa.c, rsa.h: New based on the old module version (only in CVS for now).
+ * pubkey.c (setup_pubkey_table): Added commented support for RSA.
+
+ * rndunix.c (waitpid): New. For UTS 2.1. All by Dave Dykstra.
+ (my_popen): Do the FD_CLOEXEC only if it is available
+ (start_gatherer): Cope with missing _SC_OPEN_MAX
+
+ * rndunix.c: Add some more headers for QNX. By Sam Roberts.
+
+ * rndegd.c (gather_random): Shortcut level 0.
+ * rndunix.c (gather_random): Ditto.
+ * rndw32.c (gather_random): Ditto.
+
+ * rndw32.c: Replaced with code from Cryptlib and commented the old stuff.
+ * rndw32.c: Add some debuging code enabled by an environment variable.
+
+ * random.c (read_seed_file): Binary open for DOSish system
+ (update_random_seed_file): Ditto.
+ * random.c [MINGW32]: Include process.h for getpid.
+ * random.c (fast_random_poll): Add clock_gettime() as fallback for
+ system which support this POSIX.4 fucntion. By Sam Roberts.
+
+ * random.c (read_seed_file): Removed the S_ISLNK test becuase it
+ is already covered by !S_ISREG and is not defined in Unixware.
+ Reported by Dave Dykstra.
+ (update_random_seed_file): Silently ignore update request when pool
+ is not filled.
+
+ * random.c (read_seed_file): New.
+ (set_random_seed_file): New.
+ (read_pool): Try to read the seeding file.
+ (update_random_seed_file): New.
+
+ (read_pool): Do an initial extra seeding when level 2 quality random
+ is requested the first time. This requestes at least POOLSIZE/2 bytes
+ of entropy. Compined with the seeding file this should make normal
+ random bytes cheaper and increase the quality of the random bytes
+ used for key generation.
+
+ * random.c (read_pool): Print a more friendly error message in
+ cases when too much random is requested in one call.
+
+ * random.c (fast_random_poll): Check whether RUSAGE_SELF is defined;
+ this is not the case for some ESIX and Unixware, although they have
+ getrusage().
+
+ * primegen.c (generate_elg_prime): All primes are now generated with
+ the lowest random quality level. Because they are public anyway we
+ don't need stronger random and by this we do not drain the systems
+ entropy so much.
+
+ * primegen.c (register_primegen_progress): New.
+ * dsa.c (register_pk_dsa_progress): New.
+ * elgamal.c (register_pk_elg_progress): New.
+
+ * elgamal.c (wiener_map): New.
+ (gen_k): Use a much smaller k.
+ (generate): Calculate the qbits using the wiener map and
+ choose an x at a size comparable to the one choosen in gen_k
+
+ * rmd160.c (rmd160_get_info): Moved casting to the left side due to a
+ problem with UTS4.3. Suggested by Dave Dykstra.
+ * sha1.c (sha1_get_info): Ditto.
+ * tiger.c (tiger_get_info): Ditto.
+ * md5.c (md5_get_info): Ditto
+ * des.c (des_get_info): Ditto.
+ * blowfish.c (blowfish_get_info): Ditto.
+ * cast5.c (cast5_get_info): Ditto.
+ * twofish.c (twofish_get_info): Ditto.
+
+Fri Mar 24 11:25:45 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (md_open): Add hmac arg and allocate space for the pads.
+ (md_finalize): Add HMAC support.
+ (md_copy): Ditto.
+ (md_close): Ditto.
+ (gcry_md_reset): Ditto.
+ (gcry_md_ctl): Ditto.
+ (prepare_macpdas): New.
+
+Mon Mar 13 19:22:46 CET 2000 Werner Koch <wk@openit.de>
+
+ * md.c (gcry_md_hash_buffer): Add support for the other algorithms.
+
+Mon Jan 31 16:37:34 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * genprime.c (generate_elg_prime): Fixed returned factors which never
+ worked for non-DSA keys.
+
+Thu Jan 27 18:00:44 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (sexp_to_key): Fixed mem leaks in case of errors.
+
+Mon Jan 24 22:24:38 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (gcry_pk_decrypt): Implemented.
+ (gcry_pk_encrypt): Implemented.
+ (gcry_pk_testkey): New.
+ (gcry_pk_genkey): New.
+ (pubkey_decrypt): Made static.
+ (pubkey_encrypt): Ditto.
+ (pubkey_check_secret_key): Ditto.
+ (pubkey_generate): Ditto.
+
+Mon Jan 24 13:04:28 CET 2000 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (pubkey_nbits): Removed and replaced by ...
+ (gcry_pk_get_nbits): this new one.
+
+Wed Dec 8 21:58:32 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dsa.c: s/mpi_powm/gcry_mpi_powm/g
+ * elgamal.c: Ditto.
+ * primegen.c: Ditto.
+
+ * : Replaced g10_opt_verbose by g10_log_verbosity().
+
+ * Makefile.am (INCLUDES): removed intl, add ../gcrypt
+
+Fri Nov 19 17:15:20 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * dynload.c (cmp_filenames): New to replaced compare_filename() in
+ module.
+ (register_cipher_extension): Removed the tilde expansion stuff.
+ * rndeg.c (my_make_filename): New.
+
+ * : Replaced header util.h by g10lib.h
+
+ * random.c (gather_faked): Replaced make_timestamp by time(2).
+ Disabled wrning printed with tty_printf.
+ * rndlinux.c (gather_random): Always use fprintf instead of tty_xxx;
+ this should be replaced by a callback function.
+
+ * primegen.c (gen_prime): Use gcry_mpi_randomize.
+ (is_prime): Ditto.
+ * elgamal.c (test_keys): Ditto.
+ * dsa.c (test_keys): Ditto.
+
+ * cipher.c (gcry_cipher_close): Die on invalid handle.
+
+Mon Nov 15 21:36:02 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (gen_k): Use the new random API.
+ (generate): Ditto.
+ * dsa.c (gen_k): Ditto.
+ (generate): Ditto.
+
+Sat Nov 13 17:44:23 CET 1999 Werner Koch <wk@gnupg.de>
+
+ * pubkey.c (disable_pubkey_algo): Made static.
+ (gcry_pk_ctl): New.
+
+ * random.c (get_random_bits): Renamed to ...
+ (get_random_bytes): ... this and made static.
+ (gcry_random_bytes): New.
+ (gcry_random_bytes_secure): New.
+ (randomize_buffer): Renamed to ...
+ (gcry_randomize): ...this.
+
+ * md.c (gcry_md_hash_buffer): New.
+
+ * pubkey.c (gcry_pk_algo_info): 4 new commands.
+ (pubkey_get_npkey): Made static.
+ (pubkey_get_nskey): Made static.
+ (pubkey_get_nsig): Made static.
+ (pubkey_get_nenc): Made static.
+
+ * pubkey.c: Removed all G10ERR_xxx.
+ * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO.
+ * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO.
+ * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx.
+ * blowfish.c: Ditto.
+ * des.c: Ditto.
+ * twofish.c: Ditto.
+ * dsa.c: Ditto.
+ * elgamal.c: Ditto.
+
+ * g10c.c: Removed
+
+ * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL
+ if we are out of core.
+ * dynload.c: Replaced all memory allocation functions.
+ * md.c: Ditto.
+ * primegen.c: Ditto.
+ * pubkey.c: Ditto.
+ * random.c: Ditto.
+ * rndw32.c: Ditto.
+ * elgamal.c: Ditto.
+ * dsa.c: Ditto.
+
+Tue Oct 26 14:10:21 CEST 1999 Werner Koch <wk@gnupg.de>
+
+ * elgamal.c (sign): Hugh found strange code here. Replaced by BUG().
+
+ * cipher.c: Merged with gcrypt/symapi.c.
+
+ * pubkey.c (string_to_pubkey_algo): Renamed function to ...
+ (gcry_pk_map_name): ... this.
+ (pubkey_algo_to_string): Renamed function to ...
+ (gcry_pk_algo_name): ... this.
+ (gcry_pk_algo_info): New.
+ * pubkey.c: Merged with gcrypt/pkapi.c.
+
+ * md.c (md_reset): Clear finalized; thanks to Ulf Moeller for
+ fixing this bug.
+
+ * md.c: Merged with gcrypt/mdapi.c
+
+Wed Sep 15 14:39:59 CEST 1999 Michael Roth <mroth@nessie.de>
+
+ * des.c: Various speed improvements: One bit pre rotation
+ trick after initial permutation (Richard Outerbridge).
+ Finished test of SSLeay Tripple-DES patterns.
+
+Wed Sep 15 16:22:17 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndw32.c: New.
+
+Mon Sep 13 10:51:29 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * bithelp.h: New.
+ * rmd160.h, sha1.h, md5.h: Use the rol macro from bithelp.h
+
+Tue Sep 7 16:23:36 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Fixed seds for latest egcc. By Ollivier Robert.
+
+Mon Sep 6 19:59:08 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (selftest): Add some testpattern
+
+Mon Aug 30 20:38:33 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (do_cbc_encrypt): Fixed serious bug occuring when not using
+ in place encryption. Pointed out by Frank Stajano.
+
+Mon Jul 26 09:34:46 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md5.c (md5_final): Fix for a SCO cpp bug.
+
+Thu Jul 15 10:15:35 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * elgamal.c (elg_check_secret_key,elg_encrypt
+ elg_decrypt,elg_sign,elg_verify): Sanity check on the args.
+ * dsa.c (dsa_check_secret_key,dsa_sign,dsa_verify): Ditto.
+
+ * pubkey.c (disable_pubkey_algo): New.
+ (check_pubkey_algo2): Look at disabled algo table.
+ * cipher.c (disable_cipher_algo): New.
+ (check_cipher_algo): Look at disabled algo table.
+
+Wed Jul 7 13:08:40 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Support for libtool.
+
+Fri Jul 2 11:45:54 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dsa.c (gen_k): Changed algorithm to consume less random bytes
+ * elgamal.c (gen_k): Ditto.
+
+ * random.c (random_dump_stats): New.
+
+Thu Jul 1 12:47:31 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c, elgamal.c, dsa.c (progess): New and replaced all
+ fputc with a call to this function.
+
+Sat Jun 26 12:15:59 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_write): s/ssize_t/int/ due to SunOS 4.1 probs.
+
+ * cipher.c (do_cbc_encrypt, do_cbc_decrypt): New.
+
+ * dynload.c (HAVE_DL_SHL_LOAD): Map hpux API to dlopen (Dave Dykstra).
+ * Makefile.am (install-exec-hook): Removed.
+
+Sun May 23 14:20:22 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (setup_cipher_table): Enable Twofish
+
+ * random.c (fast_random_poll): Disable use of times() for mingw32.
+
+Mon May 17 21:54:43 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (register_internal_cipher_extension): Minor init fix.
+
+Tue May 4 15:47:53 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * primegen.c (gen_prime): Readded the Fermat test. Fixed the bug
+ that we didn't correct for step when passing the prime to the
+ Rabin-Miller test which led to bad performance (Stefan Keller).
+ (check_prime): Add a first Fermat test.
+
+Sun Apr 18 10:11:28 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_setiv): Add ivlen arg, changed all callers.
+
+ * random.c (randomize_buffer): alway use secure memory because
+ we can't use m_is_secure() on a statically allocated buffer.
+
+ * twofish.c: Replaced some macros by a loop to reduce text size.
+ * Makefile.am (twofish): No more need for sed editing.
+
+Fri Apr 9 12:26:25 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (cipher_open): Reversed the changes for AUTO_CFB.
+
+ * blowfish.c: Dropped the Blowfish 160 mode.
+ * cipher.c (cipher_open): Ditto.
+ (setup_cipher_table): Ditto. And removed support of twofish128
+
+Wed Apr 7 20:51:39 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+ * twofish.c: Applied Matthew Skala's patches for 256 bit key.
+
+Tue Apr 6 19:58:12 CEST 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (get_random_bits): Can now handle requests > POOLSIZE
+
+ * cipher.c (cipher_open): Now uses standard CFB for automode if
+ the blocksize is gt 8 (according to rfc2440).
+
+Sat Mar 20 11:44:21 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndlinux.c (tty_printf) [IS_MODULE]: Removed.
+
+ * rndegd.c (gather_random): Some fixes.
+
+Wed Mar 17 13:09:03 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c (do_read): New.
+ (gather_random): Changed the implementation.
+
+Mon Mar 8 20:47:17 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (DLSYM_NEEDS_UNDERSCORE): Renamed.
+
+Fri Feb 26 17:55:41 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c: Nearly a total rewrote.
+
+Wed Feb 24 11:07:27 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * cipher.c (context): Fixed alignment
+ * md.c: Ditto.
+
+ * rndegd.c: New
+
+Mon Feb 22 20:04:00 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndegd.c: New.
+
+Wed Feb 10 17:15:39 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * Makefile.am: Modules are now figured out by configure
+ * construct.c: New. Generated by configure. Changed all modules
+ to work with that.
+ * sha1.h: Removed.
+ * md5.h: Removed.
+
+ * twofish.c: Changed interface to allow Twofish/256
+
+ * rndunix.c (start_gatherer): Die on SIGPIPE.
+
+Wed Jan 20 18:59:49 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): Fix to avoid infinite loop.
+
+Sun Jan 17 11:04:33 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * des.c (is_weak_key): Replace system memcmp due to bugs
+ in SunOS's memcmp.
+ (des_get_info): Return error on failed selftest.
+ * twofish.c (twofish_setkey): Return error on failed selftest or
+ invalid keylength.
+ * cast5.c (cast_setkey): Ditto.
+ * blowfish.c (bf_setkey): Return error on failed selftest.
+
+Tue Jan 12 11:17:18 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (random_is_faked): New.
+
+ * tiger.c: Only compile if we have the u64 type
+
+Sat Jan 9 16:02:23 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (gather_random): check for setuid.
+
+ * Makefile.am: Add a way to staically link random modules
+
+Thu Jan 7 18:00:58 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_stop_debug): Do a flush first.
+ (md_open): size of buffer now depends on the secure parameter
+
+Sun Jan 3 15:28:44 CET 1999 Werner Koch <wk@isil.d.shuttle.de>
+
+ * rndunix.c (start_gatherer): Fixed stupid ==/= bug
+
+1998-12-31 Geoff Keating <geoffk@ozemail.com.au>
+
+ * des.c (is_weak_key): Rewrite loop end condition.
+
+Tue Dec 29 14:41:47 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c: add unistd.h for getpid().
+ (RAND_MAX): Fallback value for Sun.
+
+Wed Dec 23 17:12:24 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * md.c (md_copy): Reset debug.
+
+Mon Dec 14 21:18:49 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * random.c (read_random_source): Changed the interface to the
+ random gathering function.
+ (gather_faked): Use new interface.
+ * dynload.c (dynload_getfnc_fast_random_poll): Ditto.
+ (dynload_getfnc_gather_random): Ditto.
+ * rndlinux.c (gather_random): Ditto.
+ * rndunix.c (gather_random): Ditto.
+
+Sat Dec 12 18:40:32 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (SYMBOL_VERSION): New to cope with system which needs
+ underscores.
+
+ * rndunix.c: Rewrote large parts
+
+Thu Dec 10 20:15:36 CET 1998 Werner Koch <wk@isil.d.shuttle.de>
+
+ * dynload.c (load_extension): increased needed verbosity level.
+
+ * random.c (fast_random_poll): Fallback to a default fast random
+ poll function.
+ (read_random_source): Always use the faked entroy gatherer if no
+ gather module is available.
+ * rndlinux.c (fast_poll): Removed.
+ * rndunix.c (fast_poll): Removed.
+
+
+Wed Nov 25 12:33:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-*.c: Removed.
+ * rndlinux.c : New.
+ * rndunix.c : New.
+ * random.c : Restructured the interface to the gather modules.
+ (intialize): Call constructor functions
+ (read_radnom_source): Moved to here.
+ * dynload.c (dynload_getfnc_gather_random): New.
+ (dynload_getfnc_fast_random_poll): New.
+ (register_internal_cipher_extension): New.
+ (register_cipher_extension): Support of internal modules.
+
+Sun Nov 8 17:44:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (read_random_source): Removed the assert.
+
+Mon Oct 19 18:34:30 1998 me,,, (wk@tobold)
+
+ * pubkey.c: Hack to allow us to give some info about RSA keys back.
+
+Thu Oct 15 11:47:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c: Support for DLD
+
+Wed Oct 14 12:13:07 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c: Now uses names from configure for /dev/random.
+
+1998-10-10 SL Baur <steve@altair.xemacs.org>
+
+ * Makefile.am: fix sed -O substitutions to catch -O6, etc.
+
+Tue Oct 6 10:06:32 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-unix.c (HAVE_GETTIMEOFDAY): Fixed (was ..GETTIMEOFTIME :-)
+ * rand-dummy.c (HAVE_GETTIMEOFDAY): Ditto.
+
+Mon Sep 28 13:23:09 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest): New.
+ (md_reset): New.
+
+Wed Sep 23 12:27:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (TIGER_CONTEXT): moved "buf", so that it is 64 bit aligned.
+
+Mon Sep 21 06:22:53 1998 Werner Koch (wk@(none))
+
+ * des.c: Some patches from Michael.
+
+Thu Sep 17 19:00:06 1998 Werner Koch (wk@(none))
+
+ * des.c : New file from Michael Roth <mroth@nessie.de>
+
+Mon Sep 14 11:10:55 1998 Werner Koch (wk@(none))
+
+ * blowfish.c (bf_setkey): Niklas Hernaeus patch to detect weak keys.
+
+Mon Sep 14 09:19:25 1998 Werner Koch (wk@(none))
+
+ * dynload.c (RTLD_NOW): Now defined to 1 if it is undefined.
+
+Mon Sep 7 17:04:33 1998 Werner Koch (wk@(none))
+
+ * Makefile.am: Fixes to allow a different build directory
+
+Thu Aug 6 17:25:38 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * random.c (get_random_byte): Removed and changed all callers
+ to use get_random_bits()
+
+Mon Jul 27 10:30:22 1998 Werner Koch (wk@(none))
+
+ * cipher.c : Support for other blocksizes
+ (cipher_get_blocksize): New.
+ * twofish.c: New.
+ * Makefile.am: Add twofish module.
+
+Mon Jul 13 21:30:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Simple alloc if secure_alloc is not set.
+ (get_random_bits): Ditto.
+
+Thu Jul 9 13:01:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dynload.c (load_extension): Function now nbails out if
+ the program is run setuid.
+
+Wed Jul 8 18:58:23 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_hash_buffer): New.
+
+Thu Jul 2 10:50:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_open): algos >=100 use standard CFB
+
+Thu Jun 25 11:18:25 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * Makefile.am: Support for extensions
+
+Thu Jun 18 12:09:38 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (mix_pool): simpler handling for level 0
+
+Mon Jun 15 14:40:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c: Removed from dist, will reappear as dynload module
+
+Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * pubkey.c: Major changes to allow extensions. Changed the inteface
+ of all public key ciphers and added the ability to load extensions
+ on demand.
+
+ * misc.c: Removed.
+
+Wed Jun 10 07:52:08 1998 Werner Koch,mobil,,, (wk@tobold)
+
+ * dynload.c: New.
+ * cipher.c: Major changes to allow extensions.
+
+Mon Jun 8 22:43:00 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Major internal chnages to support extensions.
+ * blowfish.c (blowfish_get_info): New and made all internal
+ functions static, changed heder.
+ * cast5.c (cast5_get_info): Likewise.
+
+Mon Jun 8 12:27:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c (transform): Fix for big endian
+
+ * cipher.c (do_cfb_decrypt): Big endian fix.
+
+Fri May 22 07:30:39 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_get_oid): Add a new one for TIGER.
+
+Thu May 21 13:24:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: Add support for a dummy cipher
+
+Thu May 14 15:40:36 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): fixed sigbus - I should better
+ add Christian von Roques's new implemenation of rmd160_write.
+
+Fri May 8 18:07:44 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rand-internal.h, rand-unix.c, rand-w32.c, rand_dummy.c: New
+ * random.c: Moved system specific functions to rand-****.c
+
+Fri May 8 14:01:17 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fast_random_poll): add call to gethrtime.
+
+Tue May 5 21:28:55 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): choosing x was not correct, could
+ yield 6 bytes which are not from the random pool, tsss, tsss..
+
+Tue May 5 14:09:06 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Add arg mode, changed all
+ callers and implemented mode 1.
+
+Mon Apr 27 14:41:58 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c (cipher_get_keylen): New.
+
+Sun Apr 26 14:44:52 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * tiger.c, tiger.h: New.
+
+Wed Apr 8 14:57:11 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (check_pubkey_algo2): New.
+
+Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cipher.c: New
+ * misc.c (check_cipher_algo): Moved to cipher.c
+ * cast5.c: Moved many functions to cipher.c
+ * blowfish.c: Likewise.
+
+Sat Apr 4 19:52:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * cast5.c: Implemented and tested.
+
+Wed Apr 1 16:38:27 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * elgamal.c (elg_generate): Faster generation of x in some cases.
+
+Thu Mar 19 13:54:48 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * blowfish.c (blowfish_decode_cfb): changed XOR operation
+ (blowfish_encode_cfb): Ditto.
+
+Thu Mar 12 14:04:05 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * sha1.c (transform): Rewrote
+
+ * blowfish.c (encrypt): Unrolled for rounds == 16
+ (decrypt): Ditto.
+
+Tue Mar 10 16:32:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (transform): Unrolled the loop.
+
+Tue Mar 10 13:05:14 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (read_pool): Add pool_balance stuff.
+ (get_random_bits): New.
+
+ * elgamal.c (elg_generate): Now uses get_random_bits to generate x.
+
+
+Tue Mar 10 11:33:51 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_digest_length): New.
+
+Tue Mar 10 11:27:41 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c (dsa_verify): Works.
+
+Mon Mar 9 12:59:08 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * dsa.c, dsa.h: Removed some unused code.
+
+Wed Mar 4 10:39:22 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_open): Add call to fast_random_poll.
+ blowfish.c (blowfish_setkey): Ditto.
+
+Tue Mar 3 13:32:54 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * rmd160.c (rmd160_mixblock): New.
+ * random.c: Restructured to start with a new RNG implementation.
+ * random.h: New.
+
+Mon Mar 2 19:21:46 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * gost.c, gost.h: Removed because they did only contain trash.
+
+Sun Mar 1 16:42:29 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * random.c (fill_buffer): removed error message if n == -1.
+
+Fri Feb 27 16:39:34 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c (md_enable): No init if called twice.
+
+Thu Feb 26 07:57:02 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * primegen.c (generate_elg_prime): Changed the progress printing.
+ (gen_prime): Ditto.
+
+Tue Feb 24 12:28:42 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md5.c, md.5 : Replaced by a modified version of md5.c from
+ GNU textutils 1.22.
+
+Wed Feb 18 14:08:30 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * md.c, md.h : New debugging support
+
+Mon Feb 16 10:08:47 1998 Werner Koch (wk@isil.d.shuttle.de)
+
+ * misc.c (cipher_algo_to_string): New
+ (pubkey_algo_to_string): New.
+ (digest_algo_to_string): New.
+
+
+ Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006
+ 2007, 2008, 2009, 2010, 2011 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.
# 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_CPPFLAGS = -I../src -I$(top_srcdir)/src
AM_CFLAGS = $(GPG_ERROR_CFLAGS)
libcipher_la_LIBADD = $(GCRYPT_MODULES)
libcipher_la_SOURCES = \
-cipher.c pubkey.c ac.c md.c \
+cipher.c pubkey.c ac.c md.c kdf.c \
hmac-tests.c \
bithelp.h \
primegen.c \
dsa.c \
elgamal.c \
ecc.c \
+idea.c \
md4.c \
md5.c \
rijndael.c rijndael-tables.h \
camellia.c camellia.h camellia-glue.c
if ENABLE_O_FLAG_MUNGING
-o_flag_munging = sed -e 's/-O[2-9s]*/-O1/g'
+o_flag_munging = sed -e 's/-O\([2-9s][2-9s]*\)/-O1/' -e 's/-Ofast/-O1/g'
else
o_flag_munging = cat
endif
/* ac.c - Alternative interface for asymmetric cryptography.
Copyright (C) 2003, 2004, 2005, 2006
2007, 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/>.
*/
\f
-/*
+/*
* Functions for working with data sets.
*/
ac_data_values_destroy (gcry_ac_data_t data)
{
unsigned int i;
-
+
for (i = 0; i < data->data_n; i++)
if (data->data[i].flags & GCRY_AC_FLAG_DEALLOC)
{
err = ac_data_mpi_copy (data->data, data->data_n, &data_mpis);
if (err)
goto out;
-
+
data_new->data_n = data->data_n;
data_new->data = data_mpis;
*data_cp = data_new;
i++;
}
identifiers_n = i;
-
+
if (! identifiers_n)
/* If there are NO identifiers, we still add surrounding braces so
that we have a list of named MPI value lists. Otherwise it
wouldn't be too much fun to process these lists. */
sexp_buffer_n += 2;
-
+
data_n = _gcry_ac_data_length (data);
for (i = 0; i < data_n; i++)
{
/* Identifier matches. Now we have to distinguish two
cases:
-
+
(i) we are at the last identifier:
leave loop
skip_name = 0;
/* Create data set from S-expression data. */
-
+
err = gcry_ac_data_new (&data_set_new);
if (err)
goto out;
gcry_sexp_release (sexp_tmp);
gcry_mpi_release (mpi);
gcry_free (string);
-
+
if (err)
gcry_ac_data_destroy (data_set_new);
unsigned int nread, unsigned char *buffer, size_t *buffer_n)
{
gcry_error_t err;
-
+
gcry_assert (ac_io->mode == GCRY_AC_IO_READABLE);
err = 0;
err = gcry_error_from_errno (errno);
break;
}
-
+
if (buffer_new != p)
buffer_new = p;
\f
-/*
+/*
* Functions for converting data between the native ac and the
* S-expression structure used by the pk interface.
*/
err = _gcry_pk_module_lookup (algorithm, &module);
if (err)
goto out;
-
+
/* Allocate. */
handle_new = gcry_malloc (sizeof (*handle_new));
if (! handle_new)
*handle = handle_new;
out:
-
+
/* Deallocate resources. */
if (err)
_gcry_pk_module_release (module);
\f
-/*
+/*
* Key management.
*/
out:
/* Deallocate resources. */
-
+
gcry_free (genkey_format);
gcry_free (arg_list);
gcry_sexp_release (genkey_sexp_request);
/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
gcry_ac_key_t
-_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+_gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
gcry_ac_key_type_t which)
{
gcry_ac_key_t key;
\f
-/*
+/*
* Functions performing cryptographic operations.
*/
for (i = 0; i < buffer_n; i++)
buffer[i] = 0;
-
+
do
{
/* Count zeros. */
unsigned int i;
(void)flags;
-
+
options = opts;
buffer = NULL;
md = NULL;
err = gcry_error_from_errno (errno);
goto out;
}
-
+
_gcry_ac_mpi_to_os (mpi, buffer, buffer_n);
*os = buffer;
*os_n = buffer_n;
gcry_mpi_t xi;
gcry_mpi_t x;
gcry_mpi_t a;
-
+
if (fips_mode ())
return;
gcry_mpi_add (x, x, xi);
gcry_mpi_mul_ui (a, a, 256);
}
-
+
gcry_mpi_release (xi);
gcry_mpi_release (a);
\f
-/*
+/*
* Implementation of Encryption Schemes (ES) and Signature Schemes
* with Appendix (SSA).
*/
err = gcry_error_from_errno (errno);
goto out;
}
-
+
err = (*scheme.dencode_prepare) (handle, key, opts, options_em);
if (err)
goto out;
goto out;
out:
-
+
_gcry_ac_data_destroy (data_encrypted);
gcry_mpi_release (mpi_encrypted);
gcry_mpi_release (mpi_decrypted);
gcry_mpi_release (mpi_signature);
mpi_signature = NULL;
-
+
err = _gcry_ac_data_verify (handle, key, mpi_data, data_signed);
out:
}
-/*
+/*
* General functions.
*/
register int i = ctx->idx_i;
register int j = ctx->idx_j;
register byte *sbox = ctx->sbox;
- register int t;
+ register int t;
while ( length-- )
{
t = sbox[i]; sbox[i] = sbox[j]; sbox[j] = t;
*outbuf++ = *inbuf++ ^ sbox[(sbox[i] + sbox[j]) & 255];
}
-
+
ctx->idx_i = i;
ctx->idx_j = j;
}
byte karr[256];
ARCFOUR_context *ctx = (ARCFOUR_context *) context;
- if (!initialized )
+ if (!initialized )
{
initialized = 1;
selftest_failed = selftest();
ctx->sbox[i] = i;
for (i=0; i < 256; i++ )
karr[i] = key[i%keylen];
- for (i=j=0; i < 256; i++ )
+ for (i=j=0; i < 256; i++ )
{
int t;
j = (j + ctx->sbox[i] + karr[i]) % 256;
t = ctx->sbox[i];
ctx->sbox[i] = ctx->sbox[j];
ctx->sbox[j] = t;
- }
+ }
memset( karr, 0, 256 );
return GPG_ERR_NO_ERROR;
selftest(void)
{
ARCFOUR_context ctx;
- byte scratch[16];
-
+ byte scratch[16];
+
/* Test vector from Cryptlib labeled there: "from the
State/Commerce Department". */
static byte key_1[] =
"ARCFOUR", NULL, NULL, 1, 128, sizeof (ARCFOUR_context),
arcfour_setkey, NULL, NULL, encrypt_stream, encrypt_stream,
};
-
static int initialized;
static const char *selftest_failed;
- if( !initialized )
+ if( !initialized )
{
initialized = 1;
selftest_failed = selftest();
for(i=0; i < BLOWFISH_ROUNDS+2; i++ )
c->p[i] = ps[i];
- for(i=0; i < 256; i++ )
+ for(i=0; i < 256; i++ )
{
c->s0[i] = ks0[i];
c->s1[i] = ks1[i];
c->s3[i] = ks3[i];
}
- for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
+ for(i=j=0; i < BLOWFISH_ROUNDS+2; i++ )
{
#ifdef WORDS_BIGENDIAN
((byte*)&data)[0] = key[j];
c->p[i] = datal;
c->p[i+1] = datar;
}
- for(i=0; i < 256; i += 2 )
+ for(i=0; i < 256; i += 2 )
{
do_encrypt( c, &datal, &datar );
c->s0[i] = datal;
* space of the library clean. The following macro is thus useful:
*
* #define CAMELLIA_EXT_SYM_PREFIX foo_
- *
+ *
* This prefixes all external symbols with "foo_".
*/
#ifdef HAVE_CONFIG_H
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
-#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
+#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
+(4+32)*sizeof(u32)+2*sizeof(void*) /* camellia_setup192 */
+0+sizeof(int)+2*sizeof(void*) /* Camellia_Ekeygen */
+3*2*sizeof(void*) /* Function calls. */
- );
+ );
return 0;
}
{
CAMELLIA_context ctx;
byte scratch[16];
-
+
/* These test vectors are from RFC-3713 */
const byte plaintext[]=
{
*/
/*
- * Algorithm Specification
+ * Algorithm Specification
* http://info.isl.ntt.co.jp/crypt/eng/camellia/specifications.html
*/
CamelliaSubkeyR(30) = CamelliaSubkeyL(30) ^ dw, CamelliaSubkeyL(30) = dw;
dw = CamelliaSubkeyL(31) ^ CamelliaSubkeyR(31), dw = CAMELLIA_RL8(dw);
CamelliaSubkeyR(31) = CamelliaSubkeyL(31) ^ dw,CamelliaSubkeyL(31) = dw;
-
+
return;
}
io[1] = io[3];
io[2] = t0;
io[3] = t1;
-
+
return;
}
void camellia_decrypt128(const u32 *subkey, u32 *io)
{
u32 il,ir,t0,t1; /* temporary valiables */
-
+
/* pre whitening but absorb kw2*/
io[0] ^= CamelliaSubkeyL(24);
io[1] ^= CamelliaSubkeyR(24);
/* pre whitening but absorb kw2*/
io[0] ^= CamelliaSubkeyL(32);
io[1] ^= CamelliaSubkeyR(32);
-
+
/* main iteration */
CAMELLIA_ROUNDSM(io[0],io[1],
CamelliaSubkeyL(31),CamelliaSubkeyR(31),
* API for compatibility
*/
-void Camellia_Ekeygen(const int keyBitLength,
- const unsigned char *rawKey,
+void Camellia_Ekeygen(const int keyBitLength,
+ const unsigned char *rawKey,
KEY_TABLE_TYPE keyTable)
{
switch(keyBitLength) {
}
-void Camellia_EncryptBlock(const int keyBitLength,
- const unsigned char *plaintext,
- const KEY_TABLE_TYPE keyTable,
+void Camellia_EncryptBlock(const int keyBitLength,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
unsigned char *ciphertext)
{
u32 tmp[4];
PUTU32(ciphertext + 12, tmp[3]);
}
-void Camellia_DecryptBlock(const int keyBitLength,
- const unsigned char *ciphertext,
- const KEY_TABLE_TYPE keyTable,
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *ciphertext,
+ const KEY_TABLE_TYPE keyTable,
unsigned char *plaintext)
{
u32 tmp[4];
* space of the library clean. The following macro is thus useful:
*
* #define CAMELLIA_EXT_SYM_PREFIX foo_
- *
+ *
* This prefixes all external symbols with "foo_".
*/
#ifdef HAVE_CONFIG_H
#define camellia_encrypt128 CAMELLIA_PREFIX(camellia_encrypt128)
#define camellia_encrypt256 CAMELLIA_PREFIX(camellia_encrypt256)
#define camellia_setup128 CAMELLIA_PREFIX(camellia_setup128)
-#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
+#define camellia_setup192 CAMELLIA_PREFIX(camellia_setup192)
#define camellia_setup256 CAMELLIA_PREFIX(camellia_setup256)
#endif /*CAMELLIA_EXT_SYM_PREFIX*/
void Camellia_Ekeygen(const int keyBitLength,
- const unsigned char *rawKey,
+ const unsigned char *rawKey,
KEY_TABLE_TYPE keyTable);
void Camellia_EncryptBlock(const int keyBitLength,
- const unsigned char *plaintext,
- const KEY_TABLE_TYPE keyTable,
+ const unsigned char *plaintext,
+ const KEY_TABLE_TYPE keyTable,
unsigned char *cipherText);
-void Camellia_DecryptBlock(const int keyBitLength,
- const unsigned char *cipherText,
- const KEY_TABLE_TYPE keyTable,
+void Camellia_DecryptBlock(const int keyBitLength,
+ const unsigned char *cipherText,
+ const KEY_TABLE_TYPE keyTable,
unsigned char *plaintext);
u32 z[4];
u32 k[16];
- if( !initialized )
+ if( !initialized )
{
initialized = 1;
selftest_failed = selftest();
/* cipher.c - cipher dispatcher
* Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003
- * 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+ * 2005, 2007, 2008, 2009, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
#define CTX_MAGIC_NORMAL 0x24091964
#define CTX_MAGIC_SECURE 0x46919042
+/* Try to use 16 byte aligned cipher context for better performance.
+ We use the aligned attribute, thus it is only possible to implement
+ this with gcc. */
#undef NEED_16BYTE_ALIGNED_CONTEXT
-#if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-#define NEED_16BYTE_ALIGNED_CONTEXT 1
+#if defined (__GNUC__)
+# define NEED_16BYTE_ALIGNED_CONTEXT 1
#endif
/* A dummy extraspec so that we do not need to tests the extraspec
&dummy_extra_spec, GCRY_CIPHER_BLOWFISH },
#endif
#if USE_DES
- { &_gcry_cipher_spec_des,
+ { &_gcry_cipher_spec_des,
&dummy_extra_spec, GCRY_CIPHER_DES },
{ &_gcry_cipher_spec_tripledes,
&_gcry_cipher_extraspec_tripledes, GCRY_CIPHER_3DES, 1 },
#endif
#if USE_ARCFOUR
- { &_gcry_cipher_spec_arcfour,
+ { &_gcry_cipher_spec_arcfour,
&dummy_extra_spec, GCRY_CIPHER_ARCFOUR },
#endif
#if USE_CAST5
- { &_gcry_cipher_spec_cast5,
+ { &_gcry_cipher_spec_cast5,
&dummy_extra_spec, GCRY_CIPHER_CAST5 },
#endif
#if USE_AES
- { &_gcry_cipher_spec_aes,
+ { &_gcry_cipher_spec_aes,
&_gcry_cipher_extraspec_aes, GCRY_CIPHER_AES, 1 },
- { &_gcry_cipher_spec_aes192,
+ { &_gcry_cipher_spec_aes192,
&_gcry_cipher_extraspec_aes192, GCRY_CIPHER_AES192, 1 },
- { &_gcry_cipher_spec_aes256,
+ { &_gcry_cipher_spec_aes256,
&_gcry_cipher_extraspec_aes256, GCRY_CIPHER_AES256, 1 },
#endif
#if USE_TWOFISH
{ &_gcry_cipher_spec_twofish,
&dummy_extra_spec, GCRY_CIPHER_TWOFISH },
- { &_gcry_cipher_spec_twofish128,
+ { &_gcry_cipher_spec_twofish128,
&dummy_extra_spec, GCRY_CIPHER_TWOFISH128 },
#endif
#if USE_SERPENT
- { &_gcry_cipher_spec_serpent128,
+ { &_gcry_cipher_spec_serpent128,
&dummy_extra_spec, GCRY_CIPHER_SERPENT128 },
{ &_gcry_cipher_spec_serpent192,
&dummy_extra_spec, GCRY_CIPHER_SERPENT192 },
- { &_gcry_cipher_spec_serpent256,
+ { &_gcry_cipher_spec_serpent256,
&dummy_extra_spec, GCRY_CIPHER_SERPENT256 },
#endif
#if USE_RFC2268
&dummy_extra_spec, GCRY_CIPHER_RFC2268_40 },
#endif
#if USE_SEED
- { &_gcry_cipher_spec_seed,
+ { &_gcry_cipher_spec_seed,
&dummy_extra_spec, GCRY_CIPHER_SEED },
#endif
#if USE_CAMELLIA
{ &_gcry_cipher_spec_camellia128,
&dummy_extra_spec, GCRY_CIPHER_CAMELLIA128 },
- { &_gcry_cipher_spec_camellia192,
+ { &_gcry_cipher_spec_camellia192,
&dummy_extra_spec, GCRY_CIPHER_CAMELLIA192 },
{ &_gcry_cipher_spec_camellia256,
&dummy_extra_spec, GCRY_CIPHER_CAMELLIA256 },
+#endif
+#ifdef USE_IDEA
+ { &_gcry_cipher_spec_idea,
+ &dummy_extra_spec, GCRY_CIPHER_IDEA },
#endif
{ NULL }
};
while (0)
-/* A VIA processor with the Padlock engine requires an alignment of
- most data on a 16 byte boundary. Because we trick out the compiler
- while allocating the context, the align attribute as used in
- rijndael.c does not work on its own. Thus we need to make sure
- that the entire context structure is a aligned on that boundary.
- We achieve this by defining a new type and use that instead of our
- usual alignment type. */
-typedef union
+/* A VIA processor with the Padlock engine as well as the Intel AES_NI
+ instructions require an alignment of most data on a 16 byte
+ boundary. Because we trick out the compiler while allocating the
+ context, the align attribute as used in rijndael.c does not work on
+ its own. Thus we need to make sure that the entire context
+ structure is a aligned on that boundary. We achieve this by
+ defining a new type and use that instead of our usual alignment
+ type. */
+typedef union
{
PROPERLY_ALIGNED_TYPE foo;
#ifdef NEED_16BYTE_ALIGNED_CONTEXT
char bar[16] __attribute__ ((aligned (16)));
-#endif
+#endif
char c[1];
} cipher_context_alignment_t;
/* The algorithm id. This is a hack required because the module
interface does not easily allow to retrieve this value. */
- int algo;
+ int algo;
/* A structure with function pointers for bulk operations. Due to
limitations of the module system (we don't want to change the
open function intializes them and the actual encryption routines
use them if they are not NULL. */
struct {
- void (*cfb_enc)(void *context, unsigned char *iv,
+ void (*cfb_enc)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks);
- void (*cfb_dec)(void *context, unsigned char *iv,
+ void (*cfb_dec)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks);
- void (*cbc_enc)(void *context, unsigned char *iv,
+ void (*cbc_enc)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks, int cbc_mac);
- void (*cbc_dec)(void *context, unsigned char *iv,
+ void (*cbc_dec)(void *context, unsigned char *iv,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks);
+ void (*ctr_enc)(void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks);
} bulk;
unsigned int iv:1; /* Set to 1 if a IV has been set. */
} marks;
- /* The initialization vector. To help code optimization we make
- sure that it is aligned on an unsigned long and u32 boundary. */
+ /* The initialization vector. For best performance we make sure
+ that it is properly aligned. In particular some implementations
+ of bulk operations expect an 16 byte aligned IV. */
union {
- unsigned long dummy_iv;
- u32 dummy_u32_iv;
- unsigned char iv[MAX_BLOCKSIZE];
+ cipher_context_alignment_t iv_align;
+ unsigned char iv[MAX_BLOCKSIZE];
} u_iv;
- unsigned char lastiv[MAX_BLOCKSIZE];
- int unused; /* Number of unused bytes in the IV. */
-
- unsigned char ctr[MAX_BLOCKSIZE]; /* For Counter (CTR) mode. */
+ /* The counter for CTR mode. This field is also used by AESWRAP and
+ thus we can't use the U_IV union. */
+ union {
+ cipher_context_alignment_t iv_align;
+ unsigned char ctr[MAX_BLOCKSIZE];
+ } u_ctr;
+ /* Space to save an IV or CTR for chaining operations. */
+ unsigned char lastiv[MAX_BLOCKSIZE];
+ int unused; /* Number of unused bytes in LASTIV. */
/* What follows are two contexts of the cipher in use. The first
one needs to be aligned well enough for the cipher operation
static gcry_err_code_t
dummy_setkey (void *c, const unsigned char *key, unsigned int keylen)
{
- (void)c;
+ (void)c;
(void)key;
(void)keylen;
return GPG_ERR_NO_ERROR;
{
gcry_err_code_t err = GPG_ERR_NO_ERROR;
int i;
-
+
for (i = 0; !err && cipher_table[i].cipher; i++)
{
if (! cipher_table[i].cipher->setkey)
ath_mutex_lock (&ciphers_registered_lock);
err = _gcry_module_add (&ciphers_registered, 0,
- (void *)cipher,
- (void *)(extraspec? extraspec : &dummy_extra_spec),
+ (void *)cipher,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
&mod);
ath_mutex_unlock (&ciphers_registered_lock);
ispassed as NULL. A pointer to the specification of the module
implementing this algorithm is return in OID_SPEC unless passed as
NULL.*/
-static int
+static int
search_oid (const char *oid, int *algorithm, gcry_cipher_oid_spec_t *oid_spec)
{
gcry_module_t module;
}
ath_mutex_unlock (&ciphers_registered_lock);
-
+
return algorithm;
}
else
err = GPG_ERR_CIPHER_ALGO;
ath_mutex_unlock (&ciphers_registered_lock);
-
+
return err;
}
-/* Return the standard length of the key for the cipher algorithm with
- the identifier ALGORITHM. This function expects a valid algorithm
- and will abort if the algorithm is not available or the length of
- the key is not known. */
+/* Return the standard length in bits of the key for the cipher
+ algorithm with the identifier ALGORITHM. */
static unsigned int
cipher_get_keylen (int algorithm)
{
log_bug ("cipher %d w/o key length\n", algorithm);
_gcry_module_release (cipher);
}
- else
- log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
}
/* Return the block length of the cipher algorithm with the identifier
- ALGORITHM. This function expects a valid algorithm and will abort
- if the algorithm is not available or the length of the key is not
- known. */
+ ALGORITHM. This function return 0 for an invalid algorithm. */
static unsigned int
cipher_get_blocksize (int algorithm)
{
log_bug ("cipher %d w/o blocksize\n", algorithm);
_gcry_module_release (cipher);
}
- else
- log_bug ("cipher %d not found\n", algorithm);
ath_mutex_unlock (&ciphers_registered_lock);
return len;
/* If the application missed to call the random poll function, we do
it here to ensure that it is used once in a while. */
_gcry_fast_random_poll ();
-
+
REGISTER_DEFAULT_CIPHERS;
/* Fetch the according module and check whether the cipher is marked
/* check flags */
if ((! err)
- && ((flags & ~(0
+ && ((flags & ~(0
| GCRY_CIPHER_SECURE
| GCRY_CIPHER_ENABLE_SYNC
| GCRY_CIPHER_CBC_CTS
h = gcry_calloc (1, size);
if (! h)
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
else
{
size_t off = 0;
h->bulk.cfb_dec = _gcry_aes_cfb_dec;
h->bulk.cbc_enc = _gcry_aes_cbc_enc;
h->bulk.cbc_dec = _gcry_aes_cbc_dec;
+ h->bulk.ctr_enc = _gcry_aes_ctr_enc;
break;
#endif /*USE_AES*/
-
+
default:
break;
}
cipher_setiv( gcry_cipher_hd_t c, const byte *iv, unsigned ivlen )
{
memset (c->u_iv.iv, 0, c->cipher->blocksize);
- if (iv)
+ if (iv)
{
if (ivlen != c->cipher->blocksize)
{
memset (&c->marks, 0, sizeof c->marks);
memset (c->u_iv.iv, 0, c->cipher->blocksize);
memset (c->lastiv, 0, c->cipher->blocksize);
- memset (c->ctr, 0, c->cipher->blocksize);
+ memset (c->u_ctr.ctr, 0, c->cipher->blocksize);
}
{
unsigned int blocksize = c->cipher->blocksize;
unsigned int n, nblocks;
-
+
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
if ((inbuflen % blocksize))
return GPG_ERR_INV_LENGTH;
nblocks = inbuflen / c->cipher->blocksize;
- for (n=0; n < nblocks; n++ )
+ for (n=0; n < nblocks; n++ )
{
c->cipher->decrypt (&c->context.c, outbuf, (byte*)/*arggg*/inbuf );
inbuf += blocksize;
&& (c->flags & GCRY_CIPHER_CBC_CTS)))
return GPG_ERR_INV_LENGTH;
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
if ((inbuflen % blocksize) == 0)
nblocks--;
if (c->bulk.cbc_enc)
{
c->bulk.cbc_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks,
- (c->flags & GCRY_CIPHER_CBC_MAC));
+ (c->flags & GCRY_CIPHER_CBC_MAC));
inbuf += nblocks * blocksize;
if (!(c->flags & GCRY_CIPHER_CBC_MAC))
outbuf += nblocks * blocksize;
}
for (; i < blocksize; i++)
outbuf[i] = 0 ^ *ivp++;
-
+
c->cipher->encrypt (&c->context.c, outbuf, outbuf);
memcpy (c->u_iv.iv, outbuf, blocksize);
}
if (c->bulk.cbc_dec)
{
- c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ c->bulk.cbc_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
inbuf += nblocks * blocksize;
outbuf += nblocks * blocksize;
}
else
{
- for (n=0; n < nblocks; n++ )
+ for (n=0; n < nblocks; n++ )
{
/* Because outbuf and inbuf might be the same, we have to
* save the original ciphertext block. We use LASTIV for
}
}
- if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
+ if ((c->flags & GCRY_CIPHER_CBC_CTS) && inbuflen > blocksize)
{
int restbytes;
-
+
if ((inbuflen % blocksize) == 0)
restbytes = blocksize;
else
restbytes = inbuflen % blocksize;
-
+
memcpy (c->lastiv, c->u_iv.iv, blocksize ); /* Save Cn-2. */
memcpy (c->u_iv.iv, inbuf + blocksize, restbytes ); /* Save Cn. */
c->cipher->decrypt ( &c->context.c, outbuf, inbuf );
for (ivp=c->u_iv.iv,i=0; i < restbytes; i++ )
outbuf[i] ^= *ivp++;
-
+
memcpy(outbuf + blocksize, outbuf, restbytes);
for(i=restbytes; i < blocksize; i++)
c->u_iv.iv[i] = outbuf[i];
unsigned char *ivp;
size_t blocksize = c->cipher->blocksize;
size_t blocksize_x_2 = blocksize + blocksize;
-
+
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
if (inbuflen >= blocksize_x_2 && c->bulk.cfb_enc)
{
unsigned int nblocks = inbuflen / blocksize;
- c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ c->bulk.cfb_enc (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
outbuf += nblocks * blocksize;
inbuf += nblocks * blocksize;
inbuflen -= nblocks * blocksize;
*outbuf++ = (*ivp++ ^= *inbuf++);
inbuflen -= blocksize;
}
- if ( inbuflen )
+ if ( inbuflen )
{
/* Save the current IV and then encrypt the IV. */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
int i;
size_t blocksize = c->cipher->blocksize;
size_t blocksize_x_2 = blocksize + blocksize;
-
+
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
/* Short enough to be encoded by the remaining XOR mask. */
/* XOR the input with the IV and store input into IV. */
for (ivp=c->u_iv.iv+blocksize - c->unused;
- inbuflen;
+ inbuflen;
inbuflen--, c->unused--)
{
temp = *inbuf++;
}
return 0;
}
-
+
if (c->unused)
{
/* XOR the input with the IV and store input into IV. */
*ivp++ = temp;
}
}
-
+
/* Now we can process complete blocks. We use a loop as long as we
have at least 2 blocks and use conditions for the rest. This
also allows to use a bulk encryption function if available. */
if (inbuflen >= blocksize_x_2 && c->bulk.cfb_dec)
{
unsigned int nblocks = inbuflen / blocksize;
- c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
+ c->bulk.cfb_dec (&c->context.c, c->u_iv.iv, outbuf, inbuf, nblocks);
outbuf += nblocks * blocksize;
inbuf += nblocks * blocksize;
inbuflen -= nblocks * blocksize;
}
if (inbuflen)
- {
+ {
/* Save the current IV and then encrypt the IV. */
memcpy ( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
/* Encrypt the IV (and save the current one). */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
c->cipher->encrypt ( &c->context.c, c->u_iv.iv, c->u_iv.iv );
-
+
for (ivp=c->u_iv.iv,i=0; i < blocksize; i++ )
*outbuf++ = (*ivp++ ^ *inbuf++);
inbuflen -= blocksize;
{
unsigned char *ivp;
size_t blocksize = c->cipher->blocksize;
-
+
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
*outbuf++ = *ivp++ ^ *inbuf++;
inbuflen -= blocksize;
}
- if ( inbuflen )
+ if ( inbuflen )
{ /* Process the remaining bytes. */
/* Encrypt the IV (and save the current one). */
memcpy( c->lastiv, c->u_iv.iv, blocksize );
const unsigned char *inbuf, unsigned int inbuflen)
{
unsigned int n;
- unsigned char tmp[MAX_BLOCKSIZE];
int i;
unsigned int blocksize = c->cipher->blocksize;
+ unsigned int nblocks;
if (outbuflen < inbuflen)
return GPG_ERR_BUFFER_TOO_SHORT;
- if ((inbuflen % blocksize))
- return GPG_ERR_INV_LENGTH;
+ /* First process a left over encrypted counter. */
+ if (c->unused)
+ {
+ gcry_assert (c->unused < blocksize);
+ i = blocksize - c->unused;
+ for (n=0; c->unused && n < inbuflen; c->unused--, n++, i++)
+ {
+ /* XOR input with encrypted counter and store in output. */
+ outbuf[n] = inbuf[n] ^ c->lastiv[i];
+ }
+ inbuf += n;
+ outbuf += n;
+ inbuflen -= n;
+ }
+
- for (n=0; n < inbuflen; n++)
+ /* Use a bulk method if available. */
+ nblocks = inbuflen / blocksize;
+ if (nblocks && c->bulk.ctr_enc)
{
- if ((n % blocksize) == 0)
- {
- c->cipher->encrypt (&c->context.c, tmp, c->ctr);
+ c->bulk.ctr_enc (&c->context.c, c->u_ctr.ctr, outbuf, inbuf, nblocks);
+ inbuf += nblocks * blocksize;
+ outbuf += nblocks * blocksize;
+ inbuflen -= nblocks * blocksize;
+ }
- for (i = blocksize; i > 0; i--)
- {
- c->ctr[i-1]++;
- if (c->ctr[i-1] != 0)
- break;
- }
- }
+ /* If we don't have a bulk method use the standard method. We also
+ use this method for the a remaining partial block. */
+ if (inbuflen)
+ {
+ unsigned char tmp[MAX_BLOCKSIZE];
+
+ for (n=0; n < inbuflen; n++)
+ {
+ if ((n % blocksize) == 0)
+ {
+ c->cipher->encrypt (&c->context.c, tmp, c->u_ctr.ctr);
+
+ for (i = blocksize; i > 0; i--)
+ {
+ c->u_ctr.ctr[i-1]++;
+ if (c->u_ctr.ctr[i-1] != 0)
+ break;
+ }
+ }
+
+ /* XOR input with encrypted counter and store in output. */
+ outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
+ }
+
+ /* Save the unused bytes of the counter. */
+ n %= blocksize;
+ c->unused = (blocksize - n) % blocksize;
+ if (c->unused)
+ memcpy (c->lastiv+n, tmp+n, c->unused);
- /* XOR input with encrypted counter and store in output. */
- outbuf[n] = inbuf[n] ^ tmp[n % blocksize];
+ wipememory (tmp, sizeof tmp);
}
- wipememory (tmp, sizeof tmp);
return 0;
}
#endif
/* We require a cipher with a 128 bit block length. */
if (c->cipher->blocksize != 16)
- return GPG_ERR_INV_LENGTH;
-
+ return GPG_ERR_INV_LENGTH;
+
/* The output buffer must be able to hold the input data plus one
additional block. */
if (outbuflen < inbuflen + 8)
return GPG_ERR_BUFFER_TOO_SHORT;
/* Input data must be multiple of 64 bits. */
if (inbuflen % 8)
- return GPG_ERR_INV_ARG;
+ return GPG_ERR_INV_ARG;
n = inbuflen / 8;
if (n < 2)
return GPG_ERR_INV_ARG;
- r = outbuf;
+ r = outbuf;
a = outbuf; /* We store A directly in OUTBUF. */
- b = c->ctr; /* B is also used to concatenate stuff. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
/* If an IV has been set we use that IV as the Alternative Initial
Value; if it has not been set we use the standard value. */
memcpy (r+i*8, b+8, 8);
}
}
-
+
return 0;
}
#endif
/* We require a cipher with a 128 bit block length. */
if (c->cipher->blocksize != 16)
- return GPG_ERR_INV_LENGTH;
-
+ return GPG_ERR_INV_LENGTH;
+
/* The output buffer must be able to hold the input data minus one
additional block. Fixme: The caller has more restrictive checks
- we may want to fix them for this mode. */
return GPG_ERR_BUFFER_TOO_SHORT;
/* Input data must be multiple of 64 bits. */
if (inbuflen % 8)
- return GPG_ERR_INV_ARG;
+ return GPG_ERR_INV_ARG;
n = inbuflen / 8;
if (n < 3)
return GPG_ERR_INV_ARG;
- r = outbuf;
+ r = outbuf;
a = c->lastiv; /* We use c->LASTIV as buffer for A. */
- b = c->ctr; /* B is also used to concatenate stuff. */
+ b = c->u_ctr.ctr; /* B is also used to concatenate stuff. */
/* Copy the inbuf to the outbuf and save A. */
memcpy (a, inbuf, 8);
case GCRY_CIPHER_MODE_CBC:
rc = do_cbc_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
-
+
case GCRY_CIPHER_MODE_CFB:
rc = do_cfb_encrypt (c, outbuf, outbuflen, inbuf, inbuflen);
break;
rc = 0;
}
break;
-
+
default:
log_fatal ("cipher_encrypt: invalid mode %d\n", c->mode );
rc = GPG_ERR_INV_CIPHER_MODE;
/* Failsafe: Make sure that the plaintext will never make it into
OUT if the encryption returned an error. */
if (err && out)
- memset (out, 0x42, outsize);
+ memset (out, 0x42, outsize);
return gcry_error (err);
}
rc = 0;
}
break;
-
+
default:
log_fatal ("cipher_decrypt: invalid mode %d\n", c->mode );
rc = GPG_ERR_INV_CIPHER_MODE;
_gcry_cipher_setctr (gcry_cipher_hd_t hd, const void *ctr, size_t ctrlen)
{
if (ctr && ctrlen == hd->cipher->blocksize)
- memcpy (hd->ctr, ctr, hd->cipher->blocksize);
+ {
+ memcpy (hd->u_ctr.ctr, ctr, hd->cipher->blocksize);
+ hd->unused = 0;
+ }
else if (!ctr || !ctrlen)
- memset (hd->ctr, 0, hd->cipher->blocksize);
+ {
+ memset (hd->u_ctr.ctr, 0, hd->cipher->blocksize);
+ hd->unused = 0;
+ }
else
return gpg_error (GPG_ERR_INV_ARG);
return 0;
break;
case GCRYCTL_SET_CTR: /* Deprecated; use gcry_cipher_setctr. */
- if (buffer && buflen == h->cipher->blocksize)
- memcpy (h->ctr, buffer, h->cipher->blocksize);
- else if (buffer == NULL || buflen == 0)
- memset (h->ctr, 0, h->cipher->blocksize);
- else
- rc = GPG_ERR_INV_ARG;
+ rc = gpg_err_code (_gcry_cipher_setctr (h, buffer, buflen));
break;
case 61: /* Disable weak key detection (private). */
if (h->extraspec->set_extra_info)
- rc = h->extraspec->set_extra_info
+ rc = h->extraspec->set_extra_info
(&h->context.c, CIPHER_INFO_NO_WEAK_KEY, NULL, 0);
else
rc = GPG_ERR_NOT_SUPPORTED;
case 62: /* Return current input vector (private). */
/* This is the input block as used in CFB and OFB mode which has
- initially been set as IV. The returned format is:
+ initially been set as IV. The returned format is:
1 byte Actual length of the block in bytes.
n byte The block.
If the provided buffer is too short, an error is returned. */
unsigned char *ivp;
unsigned char *dst = buffer;
int n = h->unused;
-
+
if (!n)
n = h->cipher->blocksize;
gcry_assert (n <= h->cipher->blocksize);
/* Return information about the cipher handle H. CMD is the kind of
information requested. BUFFER and NBYTES are reserved for now.
- There are no values for CMD yet defined.
+ There are no values for CMD yet defined.
The function always returns GPG_ERR_INV_OP.
-
+
*/
gcry_error_t
gcry_cipher_info (gcry_cipher_hd_t h, int cmd, void *buffer, size_t *nbytes)
GCRYCTL_TEST_ALGO:
Returns 0 if the specified algorithm ALGO is available for use.
BUFFER and NBYTES must be zero.
-
+
Note: Because this function is in most cases used to return an
integer value, we can make it easier for the caller to just look at
the return value. The caller will in all cases consult the value
if ((ui > 0) && (ui <= 512))
*nbytes = (size_t) ui / 8;
else
- /* The only reason is an invalid algo or a strange
- blocksize. */
+ /* The only reason for an error is an invalid algo. */
err = GPG_ERR_CIPHER_ALGO;
}
break;
gcry_cipher_algo_info because it allows for proper type
checking. */
size_t
-gcry_cipher_get_algo_keylen (int algo)
+gcry_cipher_get_algo_keylen (int algo)
{
size_t n;
gcry_cipher_algo_info because it allows for proper type
checking. */
size_t
-gcry_cipher_get_algo_blklen (int algo)
+gcry_cipher_get_algo_blklen (int algo)
{
size_t n;
{
ec = GPG_ERR_CIPHER_ALGO;
if (report)
- report ("cipher", algo, "module",
+ report ("cipher", algo, "module",
module && !(module->flags & FLAG_MODULE_DISABLED)?
"no selftest available" :
module? "algorithm disabled" : "algorithm not found");
* Bruce Schneier: Applied Cryptography. Second Edition.
* John Wiley & Sons, 1996. ISBN 0-471-12845-7. Pages 358 ff.
* This implementation is according to the definition of DES in FIPS
- * PUB 46-2 from December 1993.
+ * PUB 46-2 from December 1993.
*/
};
static unsigned char weak_keys_chksum[20] = {
0xD0, 0xCF, 0x07, 0x38, 0x93, 0x70, 0x8A, 0x83, 0x7D, 0xD7,
- 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41
+ 0x8A, 0x36, 0x65, 0x29, 0x6C, 0x1F, 0x7C, 0x3F, 0xD3, 0x41
};
if (memcmp (input, result, 8))
return "Triple-DES test failed.";
}
-
+
/*
* More Triple-DES test. These are testvectors as used by SSLeay,
* thanks to Jeroen C. van Gelderen.
*/
- {
+ {
struct { byte key[24]; byte plain[8]; byte cipher[8]; } testdata[] = {
{ { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
{ 0x95,0xF8,0xA5,0xE5,0xDD,0x31,0xD9,0x00 },
{ 0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00 }
},
-
+
{ { 0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01,
0x01,0x01,0x01,0x01,0x01,0x01,0x01,0x01 },
{
tripledes_set3keys (des3, testdata[i].key,
testdata[i].key + 8, testdata[i].key + 16);
-
+
tripledes_ecb_encrypt (des3, testdata[i].plain, result);
if (memcmp (testdata[i].cipher, result, 8))
return "Triple-DES SSLeay test failed on encryption.";
break;
default:
- ec = GPG_ERR_INV_OP;
+ ec = GPG_ERR_INV_OP;
break;
}
return ec;
\f
-/*
+/*
Self-test section.
*/
{
const char *what;
const char *errtxt;
-
+
(void)extended; /* No extended tests available. */
what = "low-level";
default:
ec = GPG_ERR_CIPHER_ALGO;
break;
-
+
}
return ec;
}
do_tripledes_setkey, do_tripledes_encrypt, do_tripledes_decrypt
};
-cipher_extra_spec_t _gcry_cipher_extraspec_tripledes =
+cipher_extra_spec_t _gcry_cipher_extraspec_tripledes =
{
run_selftests,
do_tripledes_set_extra_info
" 42CAA7DC289F0C5A9D155F02D3D551DB741A81695B74D4C8F477F9C7838EB0FB#)"
" (x #11D54E4ADBD3034160F2CED4B7CD292A4EBF3EC0#)))";
/* A sample 1024 bit DSA key used for the selftests (public only). */
-static const char sample_public_key[] =
+static const char sample_public_key[] =
"(public-key"
" (dsa"
" (p #00AD7C0025BA1A15F775F3F2D673718391D00456978D347B33D7B49E7F32EDAB"
unsigned int nbytes = (nbits+7)/8;
char *rndbuf = NULL;
+ /* To learn why we don't use mpi_mod to get the requested bit size,
+ read the paper: "The Insecurity of the Digital Signature
+ Algorithm with Partially Known Nonces" by Nguyen and Shparlinski.
+ Journal of Cryptology, New York. Vol 15, nr 3 (2003) */
+
if ( DBG_CIPHER )
log_debug("choosing a random k ");
- for (;;)
+ for (;;)
{
if( DBG_CIPHER )
progress('.');
- if ( !rndbuf || nbits < 32 )
+ if ( !rndbuf || nbits < 32 )
{
gcry_free(rndbuf);
rndbuf = gcry_random_bytes_secure( (nbits+7)/8, GCRY_STRONG_RANDOM );
else
{ /* Change only some of the higher bits. We could improve
this by directly requesting more memory at the first call
- to get_random_bytes() and use this the here maybe it is
- easier to do this directly in random.c. */
+ to get_random_bytes() and use these extra bytes here.
+ However the required management code is more complex and
+ thus we better use this simple method. */
char *pp = gcry_random_bytes_secure( 4, GCRY_STRONG_RANDOM );
memcpy( rndbuf,pp, 4 );
gcry_free(pp);
}
_gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
+
+ /* Make sure we have the requested number of bits. This code
+ looks a bit funny but it is easy to understand if you
+ consider that mpi_set_highbit clears all higher bits. We
+ don't have a clear_highbit, thus we first set the high bit
+ and then clear it again. */
if ( mpi_test_bit( k, nbits-1 ) )
mpi_set_highbit( k, nbits-1 );
else
}
if( !(mpi_cmp( k, q ) < 0) ) /* check: k < q */
- {
+ {
if( DBG_CIPHER )
progress('+');
continue; /* no */
gcry_free(rndbuf);
if( DBG_CIPHER )
progress('\n');
-
+
return k;
}
mpi_add_ui (h, h, 1);
/* g = h^e mod p */
gcry_mpi_powm (g, h, e, p);
- }
+ }
while (!mpi_cmp_ui (g, 1)); /* Continue until g != 1. */
}
x = mpi_alloc_secure( mpi_get_nlimbs(q) );
mpi_sub_ui( h, q, 1 ); /* put q-1 into h */
rndbuf = NULL;
- do
+ do
{
if( DBG_CIPHER )
progress('.');
if( !rndbuf )
rndbuf = gcry_random_bytes_secure ((qbits+7)/8, random_level);
- else
+ else
{ /* Change only some of the higher bits (= 2 bytes)*/
char *r = gcry_random_bytes_secure (2, random_level);
memcpy(rndbuf, r, 2 );
_gcry_mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 );
mpi_clear_highbit( x, qbits+1 );
- }
+ }
while ( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) );
gcry_free(rndbuf);
mpi_free( e );
y = mpi_alloc( mpi_get_nlimbs(p) );
gcry_mpi_powm( y, g, x, p );
- if( DBG_CIPHER )
+ if( DBG_CIPHER )
{
progress('\n');
log_mpidump("dsa p", p );
const void *seed;
size_t seedlen;
} initial_seed = { NULL, NULL, 0 };
- gcry_mpi_t prime_q = NULL;
- gcry_mpi_t prime_p = NULL;
+ gcry_mpi_t prime_q = NULL;
+ gcry_mpi_t prime_p = NULL;
gcry_mpi_t value_g = NULL; /* The generator. */
gcry_mpi_t value_y = NULL; /* g^x mod p */
gcry_mpi_t value_x = NULL; /* The secret exponent. */
initial_seed.seed = gcry_sexp_nth_data (initial_seed.sexp, 1,
&initial_seed.seedlen);
}
-
+
/* Fixme: Enable 186-3 after it has been approved and after fixing
the generation function. */
/* if (use_fips186_2) */
(void)use_fips186_2;
- ec = _gcry_generate_fips186_2_prime (nbits, qbits,
- initial_seed.seed,
+ ec = _gcry_generate_fips186_2_prime (nbits, qbits,
+ initial_seed.seed,
initial_seed.seedlen,
- &prime_q, &prime_p,
+ &prime_q, &prime_p,
r_counter,
r_seed, r_seedlen);
/* else */
mpi_sub_ui (value_e, prime_p, 1);
mpi_fdiv_q (value_e, value_e, prime_q );
value_g = mpi_alloc_like (prime_p);
- value_h = mpi_alloc_set_ui (1);
+ value_h = mpi_alloc_set_ui (1);
do
{
mpi_add_ui (value_h, value_h, 1);
/* g = h^e mod p */
mpi_powm (value_g, value_h, value_e, prime_p);
- }
+ }
while (!mpi_cmp_ui (value_g, 1)); /* Continue until g != 1. */
}
/* Select a random number x with: 0 < x < q */
value_x = gcry_mpi_snew (qbits);
- do
+ do
{
if( DBG_CIPHER )
progress('.');
gcry_mpi_randomize (value_x, qbits, GCRY_VERY_STRONG_RANDOM);
mpi_clear_highbit (value_x, qbits+1);
- }
+ }
while (!(mpi_cmp_ui (value_x, 0) > 0 && mpi_cmp (value_x, prime_q) < 0));
/* y = g^x mod p */
value_y = mpi_alloc_like (prime_p);
gcry_mpi_powm (value_y, value_g, value_x, prime_p);
- if (DBG_CIPHER)
+ if (DBG_CIPHER)
{
progress('\n');
log_mpidump("dsa p", prime_p );
int use_fips186_2 = 0;
int use_fips186 = 0;
dsa_domain_t domain;
-
+
(void)algo; /* No need to check it. */
(void)evalue; /* Not required for DSA. */
if (genparms)
{
gcry_sexp_t domainsexp;
-
+
/* Parse the optional qbits element. */
l1 = gcry_sexp_find_token (genparms, "qbits", 0);
if (l1)
char buf[50];
const char *s;
size_t n;
-
+
s = gcry_sexp_nth_data (l1, 1, &n);
if (!s || n >= DIM (buf) - 1 )
{
gcry_sexp_release (deriveparms);
return GPG_ERR_INV_VALUE;
}
-
+
/* Put all domain parameters into the domain object. */
l1 = gcry_sexp_find_token (domainsexp, "p", 0);
domain.p = gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
{
/* Format the seed-values unless domain parameters are used
for which a H_VALUE of NULL is an indication. */
- ec = gpg_err_code (gcry_sexp_build
+ ec = gpg_err_code (gcry_sexp_build
(&seedinfo, NULL,
"(seed-values(counter %d)(seed %b)(h %m))",
counter, (int)seedlen, seed, h_value));
p = stpcpy (p, ")");
}
p = stpcpy (p, ")");
-
+
/* Allocate space for the list of factors plus one for
an S-expression plus an extra NULL entry for safety
and fill it with the factors. */
for (j=0; j < nfactors; j++)
arg_list[i++] = (*retfactors) + j;
arg_list[i] = NULL;
-
- ec = gpg_err_code (gcry_sexp_build_array
+
+ ec = gpg_err_code (gcry_sexp_build_array
(r_extrainfo, NULL, format, arg_list));
}
}
\f
-/*
+/*
Self-test section.
*/
static const char *
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
{
- static const char sample_data[] =
- "(data (flags pkcs1)"
- " (hash sha1 #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
- static const char sample_data_bad[] =
- "(data (flags pkcs1)"
- " (hash sha1 #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
+ static const char sample_data[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f500102030405060708090a1b2c3d4#))";
+ static const char sample_data_bad[] =
+ "(data (flags raw)"
+ " (value #a0b1c2d3e4f510102030405060708090a1b2c3d4#))";
const char *errtxt = NULL;
gcry_error_t err;
err = gcry_sexp_sscan (&data, NULL,
sample_data, strlen (sample_data));
if (!err)
- err = gcry_sexp_sscan (&data_bad, NULL,
+ err = gcry_sexp_sscan (&data_bad, NULL,
sample_data_bad, strlen (sample_data_bad));
if (err)
{
/* Convert the S-expressions into the internal representation. */
what = "convert";
- err = gcry_sexp_sscan (&skey, NULL,
+ err = gcry_sexp_sscan (&skey, NULL,
sample_secret_key, strlen (sample_secret_key));
if (!err)
- err = gcry_sexp_sscan (&pkey, NULL,
+ err = gcry_sexp_sscan (&pkey, NULL,
sample_public_key, strlen (sample_public_key));
if (err)
{
default:
ec = GPG_ERR_PUBKEY_ALGO;
break;
-
+
}
return ec;
}
gcry_pk_spec_t _gcry_pubkey_spec_dsa =
{
- "DSA", dsa_names,
+ "DSA", dsa_names,
"pqgy", "pqgyx", "", "rs", "pqgy",
GCRY_PK_USAGE_SIGN,
dsa_generate,
dsa_verify,
dsa_get_nbits
};
-pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
+pk_extra_spec_t _gcry_pubkey_extraspec_dsa =
{
run_selftests,
dsa_generate_ext
};
-
/* ecc.c - Elliptic Curve Cryptography
- Copyright (C) 2007, 2008, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2007, 2008, 2010, 2011 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,
up. In fact there is not much left of the orginally code except for
some variable names and the text book implementaion of the sign and
verification algorithms. The arithmetic functions have entirely
- been rewritten and moved to mpi/ec.c. */
+ been rewritten and moved to mpi/ec.c.
+
+ ECDH encrypt and decrypt code written by Andrey Jivsov,
+*/
/* TODO:
- - If we support point compression we need to decide how to compute
- the keygrip - it should not change due to compression.
+ - If we support point compression we need to uncompress before
+ computing the keygrip
- In mpi/ec.c we use mpi_powm for x^2 mod p: Either implement a
special case in mpi_powm or check whether mpi_mulm is faster.
- Decide whether we should hide the mpi_point_t definition.
-
- - Support more than just ECDSA.
*/
#include "mpi.h"
#include "cipher.h"
-
/* Definition of a curve. */
typedef struct
{
gcry_mpi_t b; /* Second coefficient of the Weierstrass equation. */
mpi_point_t G; /* Base point (generator). */
gcry_mpi_t n; /* Order of G. */
-} elliptic_curve_t;
+ const char *name; /* Name of curve or NULL. */
+} elliptic_curve_t;
typedef struct
{
const char *name; /* Our name. */
const char *other; /* Other name. */
-} curve_aliases[] =
+} curve_aliases[] =
{
{ "NIST P-192", "1.2.840.10045.3.1.1" }, /* X9.62 OID */
{ "NIST P-192", "prime192v1" }, /* X9.62 name. */
{ "NIST P-224", "1.3.132.0.33" }, /* SECP OID. */
{ "NIST P-256", "1.2.840.10045.3.1.7" }, /* From NIST SP 800-78-1. */
- { "NIST P-256", "prime256v1" },
+ { "NIST P-256", "prime256v1" },
{ "NIST P-256", "secp256r1" },
{ "NIST P-384", "secp384r1" },
- { "NIST P-384", "1.3.132.0.34" },
+ { "NIST P-384", "1.3.132.0.34" },
{ "NIST P-521", "secp521r1" },
{ "NIST P-521", "1.3.132.0.35" },
{ NULL, NULL}
};
-
-
-/* This static table defines all available curves. */
-static const struct
-{
+typedef struct {
const char *desc; /* Description of the curve. */
unsigned int nbits; /* Number of bits. */
unsigned int fips:1; /* True if this is a FIPS140-2 approved curve. */
const char *a, *b; /* The coefficients. */
const char *n; /* The order of the base point. */
const char *g_x, *g_y; /* Base point. */
-} domain_parms[] =
+} ecc_domain_parms_t;
+
+/* This static table defines all available curves. */
+static const ecc_domain_parms_t domain_parms[] =
{
{
"NIST P-192", 192, 1,
"62c97ee72995ef42640c550b9013fad0761353c7086a272c24088be94769fd16650"
},
- { "brainpoolP160r1", 160, 0,
+ { "brainpoolP160r1", 160, 0,
"0xe95e4a5f737059dc60dfc7ad95b3d8139515620f",
"0x340e7be2a280eb74e2be61bada745d97e8f7c300",
"0x1e589a8595423412134faa2dbdec95c8d8675e58",
"0x1667cb477a1a8ec338f94741669c976316da6321"
},
- { "brainpoolP192r1", 192, 0,
+ { "brainpoolP192r1", 192, 0,
"0xc302f41d932a36cda7a3463093d18db78fce476de1a86297",
"0x6a91174076b1e0e19c39c031fe8685c1cae040e5c69a28ef",
"0x469a28ef7c28cca3dc721d044f4496bcca7ef4146fbf25c9",
}
-
/* Helper to scan a hex string. */
static gcry_mpi_t
scanval (const char *string)
axb = mpi_new (0);
y = mpi_new (0);
- mpi_powm (x_3, x, three, base->p);
- mpi_mulm (axb, base->a, x, base->p);
- mpi_addm (axb, axb, base->b, base->p);
- mpi_addm (y, x_3, axb, base->p);
+ mpi_powm (x_3, x, three, base->p);
+ mpi_mulm (axb, base->a, x, base->p);
+ mpi_addm (axb, axb, base->b, base->p);
+ mpi_addm (y, x_3, axb, base->p);
mpi_free (x_3);
mpi_free (axb);
}
-
-
-
/* Generate a random secret scalar k with an order of p
At the beginning this was identical to the code is in elgamal.c.
nbits = mpi_get_nbits (p);
k = mpi_snew (nbits);
if (DBG_CIPHER)
- log_debug ("choosing a random k of %u bits\n", nbits);
+ log_debug ("choosing a random k of %u bits at seclevel %d\n",
+ nbits, security_level);
gcry_mpi_randomize (k, nbits, security_level);
return k;
}
-/****************
- * Generate the crypto system setup.
- * As of now the fix NIST recommended values are used.
- * The subgroup generator point is in another function: gen_big_point.
- */
+
+/* Generate the crypto system setup. This function takes the NAME of
+ a curve or the desired number of bits and stores at R_CURVE the
+ parameters of the named curve or those of a suitable curve. The
+ chosen number of bits is stored on R_NBITS. */
static gpg_err_code_t
-generate_curve (unsigned int nbits, const char *name,
- elliptic_curve_t *curve, unsigned int *r_nbits)
+fill_in_curve (unsigned int nbits, const char *name,
+ elliptic_curve_t *curve, unsigned int *r_nbits)
{
int idx, aliasno;
+ const char *resname = NULL; /* Set to a found curve name. */
if (name)
{
- /* First check nor native curves. */
+ /* First check our native curves. */
for (idx = 0; domain_parms[idx].desc; idx++)
if (!strcmp (name, domain_parms[idx].desc))
- break;
+ {
+ resname = domain_parms[idx].desc;
+ break;
+ }
/* If not found consult the alias table. */
if (!domain_parms[idx].desc)
{
for (idx = 0; domain_parms[idx].desc; idx++)
if (!strcmp (curve_aliases[aliasno].name,
domain_parms[idx].desc))
- break;
+ {
+ resname = domain_parms[idx].desc;
+ break;
+ }
}
}
}
possible to bypass this check by specifying the curve parameters
directly. */
if (fips_mode () && !domain_parms[idx].fips )
- return GPG_ERR_NOT_SUPPORTED;
-
+ return GPG_ERR_NOT_SUPPORTED;
*r_nbits = domain_parms[idx].nbits;
curve->p = scanval (domain_parms[idx].p);
curve->G.x = scanval (domain_parms[idx].g_x);
curve->G.y = scanval (domain_parms[idx].g_y);
curve->G.z = mpi_alloc_set_ui (1);
+ curve->name = resname;
return 0;
}
generate_key (ECC_secret_key *sk, unsigned int nbits, const char *name,
int transient_key,
gcry_mpi_t g_x, gcry_mpi_t g_y,
- gcry_mpi_t q_x, gcry_mpi_t q_y)
+ gcry_mpi_t q_x, gcry_mpi_t q_y,
+ const char **r_usedcurve)
{
gpg_err_code_t err;
elliptic_curve_t E;
mpi_ec_t ctx;
gcry_random_level_t random_level;
- err = generate_curve (nbits, name, &E, &nbits);
+ *r_usedcurve = NULL;
+
+ err = fill_in_curve (nbits, name, &E, &nbits);
if (err)
return err;
if (DBG_CIPHER)
{
- log_mpidump ("ecc generation p", E.p);
- log_mpidump ("ecc generation a", E.a);
- log_mpidump ("ecc generation b", E.b);
- log_mpidump ("ecc generation n", E.n);
- log_mpidump ("ecc generation Gx", E.G.x);
- log_mpidump ("ecc generation Gy", E.G.y);
- log_mpidump ("ecc generation Gz", E.G.z);
+ log_mpidump ("ecgen curve p", E.p);
+ log_mpidump ("ecgen curve a", E.a);
+ log_mpidump ("ecgen curve b", E.b);
+ log_mpidump ("ecgen curve n", E.n);
+ log_mpidump ("ecgen curve Gx", E.G.x);
+ log_mpidump ("ecgen curve Gy", E.G.y);
+ log_mpidump ("ecgen curve Gz", E.G.z);
+ if (E.name)
+ log_debug ("ecgen curve used: %s\n", E.name);
}
random_level = transient_key ? GCRY_STRONG_RANDOM : GCRY_VERY_STRONG_RANDOM;
- if (DBG_CIPHER)
- log_debug ("choosing a random x of size %u%s\n", nbits,
- transient_key? " (transient-key)":"");
- d = gen_k (E.n, random_level);
+ d = gen_k (E.n, random_level);
/* Compute Q. */
point_init (&Q);
if (g_x && g_y)
{
if (_gcry_mpi_ec_get_affine (g_x, g_y, &sk->E.G, ctx))
- log_fatal ("ecc generate: Failed to get affine coordinates\n");
+ log_fatal ("ecgen: Failed to get affine coordinates\n");
}
if (q_x && q_y)
{
if (_gcry_mpi_ec_get_affine (q_x, q_y, &sk->Q, ctx))
- log_fatal ("ecc generate: Failed to get affine coordinates\n");
+ log_fatal ("ecgen: Failed to get affine coordinates\n");
}
_gcry_mpi_ec_free (ctx);
point_free (&Q);
mpi_free (d);
+
+ *r_usedcurve = E.name;
curve_free (&E);
- /* Now we can test our keys (this should never fail!). */
+ /* Now we can test our keys (this should never fail!). */
test_keys (sk, nbits - 64);
return 0;
}
-/****************
+/*
* To verify correct skey it use a random information.
* First, encrypt and decrypt this dummy value,
* test if the information is recuperated.
mpi_free (test);
}
-/****************
+
+/*
* To check the validity of the value, recalculate the correspondence
* between the public value and the secret one.
*/
static int
check_secret_key (ECC_secret_key * sk)
{
+ int rc = 1;
mpi_point_t Q;
- gcry_mpi_t y_2, y2 = mpi_alloc (0);
- mpi_ec_t ctx;
+ gcry_mpi_t y_2, y2;
+ mpi_ec_t ctx = NULL;
+
+ point_init (&Q);
/* ?primarity test of 'p' */
/* (...) //!! */
/* G in E(F_p) */
y_2 = gen_y_2 (sk->E.G.x, &sk->E); /* y^2=x^3+a*x+b */
+ y2 = mpi_alloc (0);
mpi_mulm (y2, sk->E.G.y, sk->E.G.y, sk->E.p); /* y^2=y*y */
if (mpi_cmp (y_2, y2))
{
if (DBG_CIPHER)
log_debug ("Bad check: Point 'G' does not belong to curve 'E'!\n");
- return (1);
+ goto leave;
}
/* G != PaI */
if (!mpi_cmp_ui (sk->E.G.z, 0))
{
if (DBG_CIPHER)
log_debug ("Bad check: 'G' cannot be Point at Infinity!\n");
- return (1);
+ goto leave;
}
- point_init (&Q);
ctx = _gcry_mpi_ec_init (sk->E.p, sk->E.a);
+
_gcry_mpi_ec_mul_point (&Q, sk->E.n, &sk->E.G, ctx);
if (mpi_cmp_ui (Q.z, 0))
{
if (DBG_CIPHER)
log_debug ("check_secret_key: E is not a curve of order n\n");
- point_free (&Q);
- _gcry_mpi_ec_free (ctx);
- return 1;
+ goto leave;
}
/* pubkey cannot be PaI */
if (!mpi_cmp_ui (sk->Q.z, 0))
{
if (DBG_CIPHER)
log_debug ("Bad check: Q can not be a Point at Infinity!\n");
- _gcry_mpi_ec_free (ctx);
- return (1);
+ goto leave;
}
/* pubkey = [d]G over E */
_gcry_mpi_ec_mul_point (&Q, sk->d, &sk->E.G, ctx);
if (DBG_CIPHER)
log_debug
("Bad check: There is NO correspondence between 'd' and 'Q'!\n");
- _gcry_mpi_ec_free (ctx);
- return (1);
+ goto leave;
}
+ rc = 0; /* Okay. */
+
+ leave:
_gcry_mpi_ec_free (ctx);
+ mpi_free (y2);
+ mpi_free (y_2);
point_free (&Q);
- return 0;
+ return rc;
}
mpi_point_t I;
mpi_ec_t ctx;
+ if (DBG_CIPHER)
+ log_mpidump ("ecdsa sign hash ", input );
+
k = NULL;
dr = mpi_alloc (0);
sum = mpi_alloc (0);
has to be recomputed. */
mpi_free (k);
k = gen_k (skey->E.n, GCRY_STRONG_RANDOM);
- _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
+ _gcry_mpi_ec_mul_point (&I, k, &skey->E.G, ctx);
if (_gcry_mpi_ec_get_affine (x, NULL, &I, ctx))
{
if (DBG_CIPHER)
mpi_mulm (s, k_1, sum, skey->E.n); /* s = k^(-1)*(hash+(d*r)) mod n */
}
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecdsa sign result r ", r);
+ log_mpidump ("ecdsa sign result s ", s);
+ }
+
leave:
_gcry_mpi_ec_free (ctx);
point_free (&I);
return err;
}
+
/*
* Check if R and S verifies INPUT.
*/
{
if (DBG_CIPHER)
{
- log_mpidump (" x", x);
- log_mpidump (" y", y);
- log_mpidump (" r", r);
- log_mpidump (" s", s);
+ log_mpidump (" x", x);
+ log_mpidump (" y", y);
+ log_mpidump (" r", r);
+ log_mpidump (" s", s);
log_debug ("ecc verify: Not verified\n");
}
err = GPG_ERR_BAD_SIGNATURE;
}
-
+\f
/*********************************************
************** interface ******************
*********************************************/
memmove (ptr+(pbytes-n), ptr, n);
memset (ptr, 0, (pbytes-n));
}
-
+
err = gcry_mpi_scan (&result, GCRYMPI_FMT_USG, buf, 1+2*pbytes, NULL);
if (err)
log_fatal ("mpi_scan failed: %s\n", gpg_strerror (err));
gcry_free (buf);
- mpi_free (x);
- mpi_free (y);
-
return result;
}
+
/* RESULT must have been initialized and is set on success to the
point given by VALUE. */
static gcry_error_t
gcry_free (buf);
return err;
}
- if (n < 1)
+ if (n < 1)
{
gcry_free (buf);
return GPG_ERR_INV_OBJ;
gcry_free (buf);
return GPG_ERR_NOT_IMPLEMENTED; /* No support for point compression. */
}
- if ( ((n-1)%2) )
+ if ( ((n-1)%2) )
{
gcry_free (buf);
return GPG_ERR_INV_OBJ;
mpi_free (x);
mpi_free (y);
-
+
return 0;
}
char *curve_name = NULL;
gcry_sexp_t l1;
int transient_key = 0;
+ const char *usedcurve = NULL;
(void)algo;
(void)evalue;
- (void)r_extrainfo;
if (genparms)
{
g_y = mpi_new (0);
q_x = mpi_new (0);
q_y = mpi_new (0);
- ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y);
+ ec = generate_key (&sk, nbits, curve_name, transient_key, g_x, g_y, q_x, q_y,
+ &usedcurve);
gcry_free (curve_name);
if (ec)
return ec;
+ if (usedcurve) /* Fixme: No error return checking. */
+ gcry_sexp_build (r_extrainfo, NULL, "(curve %s)", usedcurve);
skey[0] = sk.E.p;
skey[1] = sk.E.a;
skey[2] = sk.E.b;
- /* The function ec2os releases g_x and g_y. */
skey[3] = ec2os (g_x, g_y, sk.E.p);
skey[4] = sk.E.n;
- /* The function ec2os releases g_x and g_y. */
skey[5] = ec2os (q_x, q_y, sk.E.p);
skey[6] = sk.d;
+ mpi_free (g_x);
+ mpi_free (g_y);
+ mpi_free (q_x);
+ mpi_free (q_y);
+
point_free (&sk.E.G);
point_free (&sk.Q);
/* Make an empty list of factors. */
*retfactors = gcry_calloc ( 1, sizeof **retfactors );
if (!*retfactors)
- return gpg_err_code_from_syserror ();
+ return gpg_err_code_from_syserror (); /* Fixme: relase mem? */
+
+ if (DBG_CIPHER)
+ {
+ log_mpidump ("ecgen result p", skey[0]);
+ log_mpidump ("ecgen result a", skey[1]);
+ log_mpidump ("ecgen result b", skey[2]);
+ log_mpidump ("ecgen result G", skey[3]);
+ log_mpidump ("ecgen result n", skey[4]);
+ log_mpidump ("ecgen result Q", skey[5]);
+ log_mpidump ("ecgen result d", skey[6]);
+ }
return 0;
}
}
-/* Return the parameters of the curve NAME. */
+/* Return the parameters of the curve NAME in an MPI array. */
static gcry_err_code_t
ecc_get_param (const char *name, gcry_mpi_t *pkey)
{
elliptic_curve_t E;
mpi_ec_t ctx;
gcry_mpi_t g_x, g_y;
-
- err = generate_curve (0, name, &E, &nbits);
+
+ err = fill_in_curve (0, name, &E, &nbits);
if (err)
return err;
pkey[4] = E.n;
pkey[5] = NULL;
+ mpi_free (g_x);
+ mpi_free (g_y);
+
return 0;
}
+/* Return the parameters of the curve NAME as an S-expression. */
+static gcry_sexp_t
+ecc_get_param_sexp (const char *name)
+{
+ gcry_mpi_t pkey[6];
+ gcry_sexp_t result;
+ int i;
+
+ if (ecc_get_param (name, pkey))
+ return NULL;
+
+ if (gcry_sexp_build (&result, NULL,
+ "(public-key(ecc(p%m)(a%m)(b%m)(g%m)(n%m)))",
+ pkey[0], pkey[1], pkey[2], pkey[3], pkey[4]))
+ result = NULL;
+
+ for (i=0; pkey[i]; i++)
+ gcry_mpi_release (pkey[i]);
+
+ return result;
+}
+
+
+/* Return the name matching the parameters in PKEY. */
+static const char *
+ecc_get_curve (gcry_mpi_t *pkey, int iterator, unsigned int *r_nbits)
+{
+ gpg_err_code_t err;
+ elliptic_curve_t E;
+ int idx;
+ gcry_mpi_t tmp;
+ const char *result = NULL;
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ if (!pkey)
+ {
+ idx = iterator;
+ if (idx >= 0 && idx < DIM (domain_parms))
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ }
+ return result;
+ }
+
+ if (!pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4])
+ return NULL;
+
+ E.p = pkey[0];
+ E.a = pkey[1];
+ E.b = pkey[2];
+ point_init (&E.G);
+ err = os2ec (&E.G, pkey[3]);
+ if (err)
+ {
+ point_free (&E.G);
+ return NULL;
+ }
+ E.n = pkey[4];
+
+ for (idx = 0; domain_parms[idx].desc; idx++)
+ {
+ tmp = scanval (domain_parms[idx].p);
+ if (!mpi_cmp (tmp, E.p))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].a);
+ if (!mpi_cmp (tmp, E.a))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].b);
+ if (!mpi_cmp (tmp, E.b))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].n);
+ if (!mpi_cmp (tmp, E.n))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_x);
+ if (!mpi_cmp (tmp, E.G.x))
+ {
+ mpi_free (tmp);
+ tmp = scanval (domain_parms[idx].g_y);
+ if (!mpi_cmp (tmp, E.G.y))
+ {
+ result = domain_parms[idx].desc;
+ if (r_nbits)
+ *r_nbits = domain_parms[idx].nbits;
+ break;
+ }
+ }
+ }
+ }
+ }
+ }
+ mpi_free (tmp);
+ }
+
+ point_free (&E.G);
+
+ return result;
+}
+
+
static gcry_err_code_t
ecc_check_secret_key (int algo, gcry_mpi_t *skey)
{
(void)algo;
+ /* FIXME: This check looks a bit fishy: Now long is the array? */
if (!skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] || !skey[5]
- || !skey[6] || !skey[7] || !skey[8] || !skey[9] || !skey[10])
+ || !skey[6])
return GPG_ERR_BAD_MPI;
sk.E.p = skey[0];
return err;
}
+
static gcry_err_code_t
ecc_verify (int algo, gcry_mpi_t hash, gcry_mpi_t *data, gcry_mpi_t *pkey,
int (*cmp)(void *, gcry_mpi_t), void *opaquev)
}
+/* ecdh raw is classic 2-round DH protocol published in 1976.
+ *
+ * Overview of ecc_encrypt_raw and ecc_decrypt_raw.
+ *
+ * As with any PK operation, encrypt version uses a public key and
+ * decrypt -- private.
+ *
+ * Symbols used below:
+ * G - field generator point
+ * d - private long-term scalar
+ * dG - public long-term key
+ * k - ephemeral scalar
+ * kG - ephemeral public key
+ * dkG - shared secret
+ *
+ * ecc_encrypt_raw description:
+ * input:
+ * data[0] : private scalar (k)
+ * output:
+ * result[0] : shared point (kdG)
+ * result[1] : generated ephemeral public key (kG)
+ *
+ * ecc_decrypt_raw description:
+ * input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * result[0] : shared point (kdG)
+ */
+static gcry_err_code_t
+ecc_encrypt_raw (int algo, gcry_mpi_t *resarr, gcry_mpi_t k,
+ gcry_mpi_t *pkey, int flags)
+{
+ ECC_public_key pk;
+ mpi_ec_t ctx;
+ gcry_mpi_t result[2];
+ int err;
+
+ (void)algo;
+ (void)flags;
+
+ if (!k
+ || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] || !pkey[4] || !pkey[5])
+ return GPG_ERR_BAD_MPI;
+
+ pk.E.p = pkey[0];
+ pk.E.a = pkey[1];
+ pk.E.b = pkey[2];
+ point_init (&pk.E.G);
+ err = os2ec (&pk.E.G, pkey[3]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ return err;
+ }
+ pk.E.n = pkey[4];
+ point_init (&pk.Q);
+ err = os2ec (&pk.Q, pkey[5]);
+ if (err)
+ {
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+ return err;
+ }
+
+ ctx = _gcry_mpi_ec_init (pk.E.p, pk.E.a);
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so */
+ {
+ mpi_point_t R; /* Result that we return. */
+ gcry_mpi_t x, y;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+
+ point_init (&R);
+
+ /* R = kQ <=> R = kdG */
+ _gcry_mpi_ec_mul_point (&R, k, &pk.Q, ctx);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates for kdG\n");
+
+ result[0] = ec2os (x, y, pk.E.p);
+
+ /* R = kG */
+ _gcry_mpi_ec_mul_point (&R, k, &pk.E.G, ctx);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates for kG\n");
+
+ result[1] = ec2os (x, y, pk.E.p);
+
+ mpi_free (x);
+ mpi_free (y);
+
+ point_free (&R);
+ }
+
+ _gcry_mpi_ec_free (ctx);
+ point_free (&pk.E.G);
+ point_free (&pk.Q);
+
+ if (!result[0] || !result[1])
+ {
+ mpi_free (result[0]);
+ mpi_free (result[1]);
+ return GPG_ERR_ENOMEM;
+ }
+
+ /* Success. */
+ resarr[0] = result[0];
+ resarr[1] = result[1];
+
+ return 0;
+}
+
+/* input:
+ * data[0] : a point kG (ephemeral public key)
+ * output:
+ * resaddr[0] : shared point kdG
+ *
+ * see ecc_encrypt_raw for details.
+ */
+static gcry_err_code_t
+ecc_decrypt_raw (int algo, gcry_mpi_t *result, gcry_mpi_t *data,
+ gcry_mpi_t *skey, int flags)
+{
+ ECC_secret_key sk;
+ mpi_point_t R; /* Result that we return. */
+ mpi_point_t kG;
+ mpi_ec_t ctx;
+ gcry_mpi_t r;
+ int err;
+
+ (void)algo;
+ (void)flags;
+
+ *result = NULL;
+
+ if (!data || !data[0]
+ || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4]
+ || !skey[5] || !skey[6] )
+ return GPG_ERR_BAD_MPI;
+
+ point_init (&kG);
+ err = os2ec (&kG, data[0]);
+ if (err)
+ {
+ point_free (&kG);
+ return err;
+ }
+
+
+ sk.E.p = skey[0];
+ sk.E.a = skey[1];
+ sk.E.b = skey[2];
+ point_init (&sk.E.G);
+ err = os2ec (&sk.E.G, skey[3]);
+ if (err)
+ {
+ point_free (&kG);
+ point_free (&sk.E.G);
+ return err;
+ }
+ sk.E.n = skey[4];
+ point_init (&sk.Q);
+ err = os2ec (&sk.Q, skey[5]);
+ if (err)
+ {
+ point_free (&kG);
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+ return err;
+ }
+ sk.d = skey[6];
+
+ ctx = _gcry_mpi_ec_init (sk.E.p, sk.E.a);
+
+ /* R = dkG */
+ point_init (&R);
+ _gcry_mpi_ec_mul_point (&R, sk.d, &kG, ctx);
+
+ point_free (&kG);
+
+ /* The following is false: assert( mpi_cmp_ui( R.x, 1 )==0 );, so: */
+ {
+ gcry_mpi_t x, y;
+
+ x = mpi_new (0);
+ y = mpi_new (0);
+
+ if (_gcry_mpi_ec_get_affine (x, y, &R, ctx))
+ log_fatal ("ecdh: Failed to get affine coordinates\n");
+
+ r = ec2os (x, y, sk.E.p);
+ mpi_free (x);
+ mpi_free (y);
+ }
+
+ point_free (&R);
+ _gcry_mpi_ec_free (ctx);
+ point_free (&kG);
+ point_free (&sk.E.G);
+ point_free (&sk.Q);
+
+ if (!r)
+ return GPG_ERR_ENOMEM;
+
+ /* Success. */
+
+ *result = r;
+
+ return 0;
+}
+
static unsigned int
ecc_get_nbits (int algo, gcry_mpi_t *pkey)
}
-
/* See rsa.c for a description of this function. */
static gpg_err_code_t
compute_keygrip (gcry_md_hd_t md, gcry_sexp_t keyparam)
{
- static const char names[] = "pabgnq";
+#define N_COMPONENTS 6
+ static const char names[N_COMPONENTS+1] = "pabgnq";
gpg_err_code_t ec = 0;
gcry_sexp_t l1;
- gcry_mpi_t values[6];
+ gcry_mpi_t values[N_COMPONENTS];
int idx;
/* Clear the values for easier error cleanup. */
- for (idx=0; idx < 6; idx++)
+ for (idx=0; idx < N_COMPONENTS; idx++)
values[idx] = NULL;
-
- /* Fill values with all available parameters. */
- for (idx=0; idx < 6; idx++)
+
+ /* Fill values with all provided parameters. */
+ for (idx=0; idx < N_COMPONENTS; idx++)
{
l1 = gcry_sexp_find_token (keyparam, names+idx, 1);
if (l1)
}
}
}
-
+
/* Check whether a curve parameter is available and use that to fill
in missing values. */
l1 = gcry_sexp_find_token (keyparam, "curve", 5);
if (l1)
{
char *curve;
- gcry_mpi_t tmpvalues[6];
-
- for (idx = 0; idx < 6; idx++)
+ gcry_mpi_t tmpvalues[N_COMPONENTS];
+
+ for (idx = 0; idx < N_COMPONENTS; idx++)
tmpvalues[idx] = NULL;
curve = _gcry_sexp_nth_string (l1, 1);
+ gcry_sexp_release (l1);
if (!curve)
{
ec = GPG_ERR_INV_OBJ; /* Name missing or out of core. */
if (ec)
goto leave;
- for (idx = 0; idx < 6; idx++)
+ for (idx = 0; idx < N_COMPONENTS; idx++)
{
if (!values[idx])
values[idx] = tmpvalues[idx];
/* Check that all parameters are known and normalize all MPIs (that
should not be required but we use an internal function later and
thus we better make 100% sure that they are normalized). */
- for (idx = 0; idx < 6; idx++)
+ for (idx = 0; idx < N_COMPONENTS; idx++)
if (!values[idx])
{
ec = GPG_ERR_NO_OBJ;
}
else
_gcry_mpi_normalize (values[idx]);
-
+
/* Hash them all. */
- for (idx = 0; idx < 6; idx++)
+ for (idx = 0; idx < N_COMPONENTS; idx++)
{
char buf[30];
unsigned char *rawmpi;
unsigned int rawmpilen;
-
+
rawmpi = _gcry_mpi_get_buffer (values[idx], &rawmpilen, NULL);
if (!rawmpi)
{
}
leave:
- for (idx = 0; idx < 6; idx++)
+ for (idx = 0; idx < N_COMPONENTS; idx++)
_gcry_mpi_release (values[idx]);
-
+
return ec;
+#undef N_COMPONENTS
}
\f
-/*
+/*
Self-test section.
*/
{
const char *what;
const char *errtxt;
-
+
what = "low-level";
errtxt = NULL; /*selftest ();*/
if (errtxt)
default:
ec = GPG_ERR_PUBKEY_ALGO;
break;
-
+
}
return ec;
}
"ecc",
NULL,
};
+static const char *ecdh_names[] =
+ {
+ "ecdh",
+ "ecc",
+ NULL,
+ };
gcry_pk_spec_t _gcry_pubkey_spec_ecdsa =
{
ecc_get_nbits
};
-pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
+gcry_pk_spec_t _gcry_pubkey_spec_ecdh =
+ {
+ "ECDH", ecdh_names,
+ "pabgnq", "pabgnqd", "se", "", "pabgnq",
+ GCRY_PK_USAGE_ENCR,
+ ecc_generate,
+ ecc_check_secret_key,
+ ecc_encrypt_raw,
+ ecc_decrypt_raw,
+ NULL,
+ NULL,
+ ecc_get_nbits
+ };
+
+
+pk_extra_spec_t _gcry_pubkey_extraspec_ecdsa =
{
run_selftests,
ecc_generate_ext,
compute_keygrip,
- ecc_get_param
+ ecc_get_param,
+ ecc_get_curve,
+ ecc_get_param_sexp
};
-
};
int i;
- for(i=0; t[i].p_n; i++ )
+ for(i=0; t[i].p_n; i++ )
{
if( n <= t[i].p_n )
return t[i].q_n;
log_fatal ("Elgamal test key for %s %s failed\n",
(failed & 1)? "encrypt+decrypt":"",
(failed & 2)? "sign+verify":"");
- if (failed && DBG_CIPHER)
+ if (failed && DBG_CIPHER)
log_debug ("Elgamal test key for %s %s failed\n",
(failed & 1)? "encrypt+decrypt":"",
(failed & 2)? "sign+verify":"");
if( DBG_CIPHER )
log_debug("choosing a random k ");
mpi_sub_ui( p_1, p, 1);
- for(;;)
+ for(;;)
{
- if( !rndbuf || nbits < 32 )
+ if( !rndbuf || nbits < 32 )
{
gcry_free(rndbuf);
rndbuf = gcry_random_bytes_secure( nbytes, GCRY_STRONG_RANDOM );
}
else
- {
+ {
/* Change only some of the higher bits. We could improve
this by directly requesting more memory at the first call
to get_random_bytes() and use this the here maybe it is
gcry_free(pp);
}
_gcry_mpi_set_buffer( k, rndbuf, nbytes, 0 );
-
+
for(;;)
{
if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
if( DBG_CIPHER )
log_debug("choosing a random x of size %u", xbits );
rndbuf = NULL;
- do
+ do
{
if( DBG_CIPHER )
progress('.');
gcry_free(r);
}
}
- else
+ else
{
rndbuf = gcry_random_bytes_secure( (xbits+7)/8,
GCRY_VERY_STRONG_RANDOM );
}
_gcry_mpi_set_buffer( x, rndbuf, (xbits+7)/8, 0 );
mpi_clear_highbit( x, xbits+1 );
- }
+ }
while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
gcry_free(rndbuf);
y = gcry_mpi_new (nbits);
gcry_mpi_powm( y, g, x, p );
- if( DBG_CIPHER )
+ if( DBG_CIPHER )
{
progress('\n');
log_mpidump("elg p= ", p );
value for the secret key but the one given as X. This is useful to
implement a passphrase based decryption for a public key based
encryption. It has appliactions in backup systems.
-
+
Returns: A structure filled with all needed values and an array
with n-1 factors of (p-1). */
static gcry_err_code_t
y = gcry_mpi_new (nbits);
gcry_mpi_powm ( y, g, x, p );
- if ( DBG_CIPHER )
+ if ( DBG_CIPHER )
{
progress ('\n');
log_mpidump ("elg p= ", p );
mpi_invm( t1, t1, skey->p );
mpi_mulm( output, b, t1, skey->p );
#if 0
- if( DBG_CIPHER )
+ if( DBG_CIPHER )
{
log_mpidump("elg decrypted x= ", skey->x);
log_mpidump("elg decrypted p= ", skey->p);
mpi_mulm(b, t, inv, p_1 );
#if 0
- if( DBG_CIPHER )
+ if( DBG_CIPHER )
{
log_mpidump("elg sign p= ", skey->p);
log_mpidump("elg sign g= ", skey->g);
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
-
+
return ec;
}
skey[1] = sk.g;
skey[2] = sk.y;
skey[3] = sk.x;
-
+
return GPG_ERR_NO_ERROR;
}
sk.g = skey[1];
sk.y = skey[2];
sk.x = skey[3];
-
+
if (! check_secret_key (&sk))
err = GPG_ERR_BAD_SECKEY;
}
resarr[1] = mpi_alloc (mpi_get_nlimbs (sk.p));
sign (resarr[0], resarr[1], data, &sk);
}
-
+
return err;
}
elg_get_nbits
};
-pk_extra_spec_t _gcry_pubkey_extraspec_elg =
+pk_extra_spec_t _gcry_pubkey_extraspec_elg =
{
NULL,
elg_generate_ext,
NULL
};
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
describing the error.
DATAMODE controls what will be hashed according to this table:
-
+
0 - Hash the supplied DATA of DATALEN.
1 - Hash one million times a 'a'. DATA and DATALEN are ignored.
-
+
*/
const char *
_gcry_hash_selftest_check_one (int algo,
gcry_error_t err = 0;
gcry_md_hd_t hd;
unsigned char *digest;
-
+
if (_gcry_md_get_algo_dlen (algo) != expectlen)
return "digest size does not match expected size";
-
+
err = _gcry_md_open (&hd, algo, 0);
if (err)
return "gcry_md_open failed";
-
+
switch (datamode)
{
case 0:
break;
case 1: /* Hash one million times an "a". */
- {
+ {
char aaa[1000];
int i;
if (!result)
{
digest = _gcry_md_read (hd, algo);
-
+
if ( memcmp (digest, expect, expectlen) )
result = "digest mismatch";
}
return result;
}
-
#define GCRY_HASH_COMMON_H
-const char * _gcry_hash_selftest_check_one
-/**/ (int algo,
+const char * _gcry_hash_selftest_check_one
+/**/ (int algo,
int datamode, const void *data, size_t datalen,
const void *expect, size_t expectlen);
-
+
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
-/*
+/*
Although algorithm self-tests are usually implemented in the module
implementing the algorithm, the case for HMAC is different because
HMAC is implemnetd on a higher level using a special feature of the
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
succdess or a string describing the failure. */
static const char *
check_one (int algo,
- const void *data, size_t datalen,
+ const void *data, size_t datalen,
const void *key, size_t keylen,
const void *expect, size_t expectlen)
{
return "does not match";
}
_gcry_md_close (hd);
- return NULL;
+ return NULL;
}
"\xa4\x58\x30\x73\x7d\x5c\xc6\xc7\x5d\x24", 20);
if (errtxt)
goto failed;
-
+
what = "FIPS-198a, A.3";
for (i=0, j=0x50; i < 100; i++)
key[i] = j++;
"\x5c\xaf\x7c\xb0\x92\xec\xf8\xd1\xa3\xaa", 20 );
if (errtxt)
goto failed;
-
+
what = "FIPS-198a, A.4";
for (i=0, j=0x70; i < 49; i++)
key[i] = j++;
static gpg_err_code_t
selftests_sha224 (int extended, selftest_report_func_t report)
{
- static struct
+ static struct
{
const char * const desc;
const char * const data;
} tv[] =
{
{ "data-28 key-4",
- "what do ya want for nothing?",
+ "what do ya want for nothing?",
"Jefe",
{ 0xa3, 0x0e, 0x01, 0x09, 0x8b, 0xc6, 0xdb, 0xbf,
0x45, 0x69, 0x0f, 0x3a, 0x7e, 0x9e, 0x6d, 0x0f,
const char *what;
const char *errtxt;
int tvidx;
-
+
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
static gpg_err_code_t
selftests_sha256 (int extended, selftest_report_func_t report)
{
- static struct
+ static struct
{
const char * const desc;
const char * const data;
} tv[] =
{
{ "data-28 key-4",
- "what do ya want for nothing?",
+ "what do ya want for nothing?",
"Jefe",
{ 0x5b, 0xdc, 0xc1, 0x46, 0xbf, 0x60, 0x75, 0x4e,
0x6a, 0x04, 0x24, 0x26, 0x08, 0x95, 0x75, 0xc7,
const char *what;
const char *errtxt;
int tvidx;
-
+
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
hmac256_context_t hmachd;
static gpg_err_code_t
selftests_sha384 (int extended, selftest_report_func_t report)
{
- static struct
+ static struct
{
const char * const desc;
const char * const data;
} tv[] =
{
{ "data-28 key-4",
- "what do ya want for nothing?",
+ "what do ya want for nothing?",
"Jefe",
{ 0xaf, 0x45, 0xd2, 0xe3, 0x76, 0x48, 0x40, 0x31,
0x61, 0x7f, 0x78, 0xd2, 0xb5, 0x8a, 0x6b, 0x1b,
const char *what;
const char *errtxt;
int tvidx;
-
+
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
static gpg_err_code_t
selftests_sha512 (int extended, selftest_report_func_t report)
{
- static struct
+ static struct
{
const char * const desc;
const char * const data;
} tv[] =
{
{ "data-28 key-4",
- "what do ya want for nothing?",
+ "what do ya want for nothing?",
"Jefe",
{ 0x16, 0x4b, 0x7a, 0x7b, 0xfc, 0xf8, 0x19, 0xe2,
0xe3, 0x95, 0xfb, 0xe7, 0x3b, 0x56, 0xe0, 0xa3,
const char *what;
const char *errtxt;
int tvidx;
-
+
for (tvidx=0; tv[tvidx].desc; tvidx++)
{
what = tv[tvidx].desc;
--- /dev/null
+/* idea.c - IDEA function
+ * Copyright 1997, 1998, 1999, 2001 Werner Koch (dd9jn)
+ * Copyright 2013 g10 Code GmbH
+ *
+ * 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.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
+ * WERNER KOCH BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
+ * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ *
+ * Except as contained in this notice, the name of Werner Koch shall not be
+ * used in advertising or otherwise to promote the sale, use or other dealings
+ * in this Software without prior written authorization from Werner Koch.
+ *
+ * Patents on IDEA have expired:
+ * Europe: EP0482154 on 2011-05-16,
+ * Japan: JP3225440 on 2011-05-16,
+ * U.S.: 5,214,703 on 2012-01-07.
+ */
+
+/*
+ * Please see http://www.noepatents.org/ to learn why software patents
+ * are bad for society and what you can do to fight them.
+ *
+ * The code herein is based on the one from:
+ * Bruce Schneier: Applied Cryptography. John Wiley & Sons, 1996.
+ * ISBN 0-471-11709-9.
+ */
+
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+
+#include "types.h" /* for byte and u32 typedefs */
+#include "g10lib.h"
+#include "cipher.h"
+
+
+#define IDEA_KEYSIZE 16
+#define IDEA_BLOCKSIZE 8
+#define IDEA_ROUNDS 8
+#define IDEA_KEYLEN (6*IDEA_ROUNDS+4)
+
+typedef struct {
+ u16 ek[IDEA_KEYLEN];
+ u16 dk[IDEA_KEYLEN];
+ int have_dk;
+} IDEA_context;
+
+static const char *selftest(void);
+
+
+static u16
+mul_inv( u16 x )
+{
+ u16 t0, t1;
+ u16 q, y;
+
+ if( x < 2 )
+ return x;
+ t1 = 0x10001L / x;
+ y = 0x10001L % x;
+ if( y == 1 )
+ return (1-t1) & 0xffff;
+
+ t0 = 1;
+ do {
+ q = x / y;
+ x = x % y;
+ t0 += q * t1;
+ if( x == 1 )
+ return t0;
+ q = y / x;
+ y = y % x;
+ t1 += q * t0;
+ } while( y != 1 );
+ return (1-t1) & 0xffff;
+}
+
+
+
+static void
+expand_key( const byte *userkey, u16 *ek )
+{
+ int i,j;
+
+ for(j=0; j < 8; j++ ) {
+ ek[j] = (*userkey << 8) + userkey[1];
+ userkey += 2;
+ }
+ for(i=0; j < IDEA_KEYLEN; j++ ) {
+ i++;
+ ek[i+7] = ek[i&7] << 9 | ek[(i+1)&7] >> 7;
+ ek += i & 8;
+ i &= 7;
+ }
+}
+
+
+static void
+invert_key( u16 *ek, u16 dk[IDEA_KEYLEN] )
+{
+ int i;
+ u16 t1, t2, t3;
+ u16 temp[IDEA_KEYLEN];
+ u16 *p = temp + IDEA_KEYLEN;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+
+ for(i=0; i < IDEA_ROUNDS-1; i++ ) {
+ t1 = *ek++;
+ *--p = *ek++;
+ *--p = t1;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t2;
+ *--p = t3;
+ *--p = t1;
+ }
+ t1 = *ek++;
+ *--p = *ek++;
+ *--p = t1;
+
+ t1 = mul_inv( *ek++ );
+ t2 = -*ek++;
+ t3 = -*ek++;
+ *--p = mul_inv( *ek++ );
+ *--p = t3;
+ *--p = t2;
+ *--p = t1;
+ memcpy(dk, temp, sizeof(temp) );
+ memset(temp, 0, sizeof(temp) ); /* burn temp */
+}
+
+
+static void
+cipher( byte *outbuf, const byte *inbuf, u16 *key )
+{
+ u16 s2, s3;
+ u16 in[4];
+ int r = IDEA_ROUNDS;
+#define x1 (in[0])
+#define x2 (in[1])
+#define x3 (in[2])
+#define x4 (in[3])
+#define MUL(x,y) \
+ do {u16 _t16; u32 _t32; \
+ if( (_t16 = (y)) ) { \
+ if( (x = (x)&0xffff) ) { \
+ _t32 = (u32)x * _t16; \
+ x = _t32 & 0xffff; \
+ _t16 = _t32 >> 16; \
+ x = ((x)-_t16) + (x<_t16?1:0); \
+ } \
+ else { \
+ x = 1 - _t16; \
+ } \
+ } \
+ else { \
+ x = 1 - x; \
+ } \
+ } while(0)
+
+ memcpy (in, inbuf, sizeof in);
+#ifndef WORDS_BIGENDIAN
+ x1 = (x1>>8) | (x1<<8);
+ x2 = (x2>>8) | (x2<<8);
+ x3 = (x3>>8) | (x3<<8);
+ x4 = (x4>>8) | (x4<<8);
+#endif
+ do {
+ MUL(x1, *key++);
+ x2 += *key++;
+ x3 += *key++;
+ MUL(x4, *key++ );
+
+ s3 = x3;
+ x3 ^= x1;
+ MUL(x3, *key++);
+ s2 = x2;
+ x2 ^=x4;
+ x2 += x3;
+ MUL(x2, *key++);
+ x3 += x2;
+
+ x1 ^= x2;
+ x4 ^= x3;
+
+ x2 ^= s3;
+ x3 ^= s2;
+ } while( --r );
+ MUL(x1, *key++);
+ x3 += *key++;
+ x2 += *key++;
+ MUL(x4, *key);
+
+#ifndef WORDS_BIGENDIAN
+ x1 = (x1>>8) | (x1<<8);
+ x2 = (x2>>8) | (x2<<8);
+ x3 = (x3>>8) | (x3<<8);
+ x4 = (x4>>8) | (x4<<8);
+#endif
+ memcpy (outbuf+0, &x1, 2);
+ memcpy (outbuf+2, &x3, 2);
+ memcpy (outbuf+4, &x2, 2);
+ memcpy (outbuf+6, &x4, 2);
+#undef MUL
+#undef x1
+#undef x2
+#undef x3
+#undef x4
+}
+
+
+static int
+do_setkey( IDEA_context *c, const byte *key, unsigned int keylen )
+{
+ static int initialized = 0;
+ static const char *selftest_failed = 0;
+
+ if( !initialized ) {
+ initialized = 1;
+ selftest_failed = selftest();
+ if( selftest_failed )
+ log_error( "%s\n", selftest_failed );
+ }
+ if( selftest_failed )
+ return GPG_ERR_SELFTEST_FAILED;
+
+ assert(keylen == 16);
+ c->have_dk = 0;
+ expand_key( key, c->ek );
+ invert_key( c->ek, c->dk );
+ return 0;
+}
+
+static gcry_err_code_t
+idea_setkey (void *context, const byte *key, unsigned int keylen)
+{
+ IDEA_context *ctx = context;
+ int rc = do_setkey (ctx, key, keylen);
+ _gcry_burn_stack (23+6*sizeof(void*));
+ return rc;
+}
+
+static void
+encrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+ cipher( outbuf, inbuf, c->ek );
+}
+
+static void
+idea_encrypt (void *context, byte *out, const byte *in)
+{
+ IDEA_context *ctx = context;
+ encrypt_block (ctx, out, in);
+ _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+static void
+decrypt_block( IDEA_context *c, byte *outbuf, const byte *inbuf )
+{
+ if( !c->have_dk ) {
+ c->have_dk = 1;
+ invert_key( c->ek, c->dk );
+ }
+ cipher( outbuf, inbuf, c->dk );
+}
+
+static void
+idea_decrypt (void *context, byte *out, const byte *in)
+{
+ IDEA_context *ctx = context;
+ decrypt_block (ctx, out, in);
+ _gcry_burn_stack (24+3*sizeof (void*));
+}
+
+
+static const char *
+selftest( void )
+{
+static struct {
+ byte key[16];
+ byte plain[8];
+ byte cipher[8];
+} test_vectors[] = {
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x00, 0x00, 0x00, 0x01, 0x00, 0x02, 0x00, 0x03 },
+ { 0x11, 0xFB, 0xED, 0x2B, 0x01, 0x98, 0x6D, 0xE5 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x54, 0x0E, 0x5F, 0xEA, 0x18, 0xC2, 0xF8, 0xB1 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x00, 0x19, 0x32, 0x4B, 0x64, 0x7D, 0x96, 0xAF },
+ { 0x9F, 0x0A, 0x0A, 0xB6, 0xE1, 0x0C, 0xED, 0x78 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0xF5, 0x20, 0x2D, 0x5B, 0x9C, 0x67, 0x1B, 0x08 },
+ { 0xCF, 0x18, 0xFD, 0x73, 0x55, 0xE2, 0xC5, 0xC5 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0xFA, 0xE6, 0xD2, 0xBE, 0xAA, 0x96, 0x82, 0x6E },
+ { 0x85, 0xDF, 0x52, 0x00, 0x56, 0x08, 0x19, 0x3D } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x0A, 0x14, 0x1E, 0x28, 0x32, 0x3C, 0x46, 0x50 },
+ { 0x2F, 0x7D, 0xE7, 0x50, 0x21, 0x2F, 0xB7, 0x34 } },
+ { { 0x00, 0x01, 0x00, 0x02, 0x00, 0x03, 0x00, 0x04,
+ 0x00, 0x05, 0x00, 0x06, 0x00, 0x07, 0x00, 0x08 },
+ { 0x05, 0x0A, 0x0F, 0x14, 0x19, 0x1E, 0x23, 0x28 },
+ { 0x7B, 0x73, 0x14, 0x92, 0x5D, 0xE5, 0x9C, 0x09 } },
+ { { 0x00, 0x05, 0x00, 0x0A, 0x00, 0x0F, 0x00, 0x14,
+ 0x00, 0x19, 0x00, 0x1E, 0x00, 0x23, 0x00, 0x28 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x3E, 0xC0, 0x47, 0x80, 0xBE, 0xFF, 0x6E, 0x20 } },
+ { { 0x3A, 0x98, 0x4E, 0x20, 0x00, 0x19, 0x5D, 0xB3,
+ 0x2E, 0xE5, 0x01, 0xC8, 0xC4, 0x7C, 0xEA, 0x60 },
+ { 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08 },
+ { 0x97, 0xBC, 0xD8, 0x20, 0x07, 0x80, 0xDA, 0x86 } },
+ { { 0x00, 0x64, 0x00, 0xC8, 0x01, 0x2C, 0x01, 0x90,
+ 0x01, 0xF4, 0x02, 0x58, 0x02, 0xBC, 0x03, 0x20 },
+ { 0x05, 0x32, 0x0A, 0x64, 0x14, 0xC8, 0x19, 0xFA },
+ { 0x65, 0xBE, 0x87, 0xE7, 0xA2, 0x53, 0x8A, 0xED } },
+ { { 0x9D, 0x40, 0x75, 0xC1, 0x03, 0xBC, 0x32, 0x2A,
+ 0xFB, 0x03, 0xE7, 0xBE, 0x6A, 0xB3, 0x00, 0x06 },
+ { 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08, 0x08 },
+ { 0xF5, 0xDB, 0x1A, 0xC4, 0x5E, 0x5E, 0xF9, 0xF9 } }
+};
+ IDEA_context c;
+ byte buffer[8];
+ int i;
+
+ for(i=0; i < DIM(test_vectors); i++ ) {
+ do_setkey( &c, test_vectors[i].key, 16 );
+ encrypt_block( &c, buffer, test_vectors[i].plain );
+ if( memcmp( buffer, test_vectors[i].cipher, 8 ) )
+ return "IDEA test encryption failed.";
+ decrypt_block( &c, buffer, test_vectors[i].cipher );
+ if( memcmp( buffer, test_vectors[i].plain, 8 ) )
+ return "IDEA test decryption failed.";
+ }
+
+ return NULL;
+}
+
+
+gcry_cipher_spec_t _gcry_cipher_spec_idea =
+{
+ "IDEA", NULL, NULL, IDEA_BLOCKSIZE, 128,
+ sizeof (IDEA_context),
+ idea_setkey, idea_encrypt, idea_decrypt
+};
--- /dev/null
+/* kdf.c - Key Derivation Functions
+ * Copyright (C) 1998, 2011 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/>.
+ */
+
+#include <config.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "g10lib.h"
+#include "cipher.h"
+#include "ath.h"
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide an HASHALGO, a valid ALGO and depending on that algo a
+ SALT of 8 bytes and the number of ITERATIONS. Code taken from
+ gnupg/agent/protect.c:hash_passphrase. */
+gpg_err_code_t
+openpgp_s2k (const void *passphrase, size_t passphraselen,
+ int algo, int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ char *key = keybuffer;
+ int pass, i;
+ int used = 0;
+ int secmode;
+
+ if ((algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ && (!salt || saltlen != 8))
+ return GPG_ERR_INV_VALUE;
+
+ secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+
+ ec = gpg_err_code (gcry_md_open (&md, hashalgo,
+ secmode? GCRY_MD_FLAG_SECURE : 0));
+ if (ec)
+ return ec;
+
+ for (pass=0; used < keysize; pass++)
+ {
+ if (pass)
+ {
+ gcry_md_reset (md);
+ for (i=0; i < pass; i++) /* Preset the hash context. */
+ gcry_md_putc (md, 0);
+ }
+
+ if (algo == GCRY_KDF_SALTED_S2K || algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ int len2 = passphraselen + 8;
+ unsigned long count = len2;
+
+ if (algo == GCRY_KDF_ITERSALTED_S2K)
+ {
+ count = iterations;
+ if (count < len2)
+ count = len2;
+ }
+
+ while (count > len2)
+ {
+ gcry_md_write (md, salt, saltlen);
+ gcry_md_write (md, passphrase, passphraselen);
+ count -= len2;
+ }
+ if (count < saltlen)
+ gcry_md_write (md, salt, count);
+ else
+ {
+ gcry_md_write (md, salt, saltlen);
+ count -= saltlen;
+ gcry_md_write (md, passphrase, count);
+ }
+ }
+ else
+ gcry_md_write (md, passphrase, passphraselen);
+
+ gcry_md_final (md);
+ i = gcry_md_get_algo_dlen (hashalgo);
+ if (i > keysize - used)
+ i = keysize - used;
+ memcpy (key+used, gcry_md_read (md, hashalgo), i);
+ used += i;
+ }
+ gcry_md_close (md);
+ return 0;
+}
+
+
+/* Transform a passphrase into a suitable key of length KEYSIZE and
+ store this key in the caller provided buffer KEYBUFFER. The caller
+ must provide PRFALGO which indicates the pseudorandom function to
+ use: This shall be the algorithms id of a hash algorithm; it is
+ used in HMAC mode. SALT is a salt of length SALTLEN and ITERATIONS
+ gives the number of iterations. */
+gpg_err_code_t
+pkdf2 (const void *passphrase, size_t passphraselen,
+ int hashalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+ gcry_md_hd_t md;
+ int secmode;
+ unsigned int dklen = keysize;
+ char *dk = keybuffer;
+ unsigned int hlen; /* Output length of the digest function. */
+ unsigned int l; /* Rounded up number of blocks. */
+ unsigned int r; /* Number of octets in the last block. */
+ char *sbuf; /* Malloced buffer to concatenate salt and iter
+ as well as space to hold TBUF and UBUF. */
+ char *tbuf; /* Buffer for T; ptr into SBUF, size is HLEN. */
+ char *ubuf; /* Buffer for U; ptr into SBUF, size is HLEN. */
+ unsigned int lidx; /* Current block number. */
+ unsigned long iter; /* Current iteration number. */
+ unsigned int i;
+
+ if (!salt || !saltlen || !iterations || !dklen)
+ return GPG_ERR_INV_VALUE;
+
+ hlen = gcry_md_get_algo_dlen (hashalgo);
+ if (!hlen)
+ return GPG_ERR_DIGEST_ALGO;
+
+ secmode = gcry_is_secure (passphrase) || gcry_is_secure (keybuffer);
+
+ /* We ignore step 1 from pksc5v2.1 which demands a check that dklen
+ is not larger that 0xffffffff * hlen. */
+
+ /* Step 2 */
+ l = ((dklen - 1)/ hlen) + 1;
+ r = dklen - (l - 1) * hlen;
+
+ /* Setup buffers and prepare a hash context. */
+ sbuf = (secmode
+ ? gcry_malloc_secure (saltlen + 4 + hlen + hlen)
+ : gcry_malloc (saltlen + 4 + hlen + hlen));
+ if (!sbuf)
+ return gpg_err_code_from_syserror ();
+ tbuf = sbuf + saltlen + 4;
+ ubuf = tbuf + hlen;
+
+ ec = gpg_err_code (gcry_md_open (&md, hashalgo,
+ (GCRY_MD_FLAG_HMAC
+ | (secmode?GCRY_MD_FLAG_SECURE:0))));
+ if (ec)
+ {
+ gcry_free (sbuf);
+ return ec;
+ }
+
+ /* Step 3 and 4. */
+ memcpy (sbuf, salt, saltlen);
+ for (lidx = 1; lidx <= l; lidx++)
+ {
+ for (iter = 0; iter < iterations; iter++)
+ {
+ ec = gpg_err_code (gcry_md_setkey (md, passphrase, passphraselen));
+ if (ec)
+ {
+ gcry_md_close (md);
+ gcry_free (sbuf);
+ return ec;
+ }
+ if (!iter) /* Compute U_1: */
+ {
+ sbuf[saltlen] = (lidx >> 24);
+ sbuf[saltlen + 1] = (lidx >> 16);
+ sbuf[saltlen + 2] = (lidx >> 8);
+ sbuf[saltlen + 3] = lidx;
+ gcry_md_write (md, sbuf, saltlen + 4);
+ memcpy (ubuf, gcry_md_read (md, 0), hlen);
+ memcpy (tbuf, ubuf, hlen);
+ }
+ else /* Compute U_(2..c): */
+ {
+ gcry_md_write (md, ubuf, hlen);
+ memcpy (ubuf, gcry_md_read (md, 0), hlen);
+ for (i=0; i < hlen; i++)
+ tbuf[i] ^= ubuf[i];
+ }
+ }
+ if (lidx == l) /* Last block. */
+ memcpy (dk, tbuf, r);
+ else
+ {
+ memcpy (dk, tbuf, hlen);
+ dk += hlen;
+ }
+ }
+
+ gcry_md_close (md);
+ gcry_free (sbuf);
+ return 0;
+}
+
+
+/* Derive a key from a passphrase. KEYSIZE gives the requested size
+ of the keys in octets. KEYBUFFER is a caller provided buffer
+ filled on success with the derived key. The input passphrase is
+ taken from (PASSPHRASE,PASSPHRASELEN) which is an arbitrary memory
+ buffer. ALGO specifies the KDF algorithm to use; these are the
+ constants GCRY_KDF_*. SUBALGO specifies an algorithm used
+ internally by the KDF algorithms; this is usually a hash algorithm
+ but certain KDF algorithm may use it differently. {SALT,SALTLEN}
+ is a salt as needed by most KDF algorithms. ITERATIONS is a
+ positive integer parameter to most KDFs. 0 is returned on success,
+ or an error code on failure. */
+gpg_error_t
+gcry_kdf_derive (const void *passphrase, size_t passphraselen,
+ int algo, int subalgo,
+ const void *salt, size_t saltlen,
+ unsigned long iterations,
+ size_t keysize, void *keybuffer)
+{
+ gpg_err_code_t ec;
+
+ if (!passphrase || (!passphraselen && algo != GCRY_KDF_PBKDF2))
+ {
+ ec = GPG_ERR_INV_DATA;
+ goto leave;
+ }
+ if (!keybuffer || !keysize)
+ {
+ ec = GPG_ERR_INV_VALUE;
+ goto leave;
+ }
+
+
+ switch (algo)
+ {
+ case GCRY_KDF_SIMPLE_S2K:
+ case GCRY_KDF_SALTED_S2K:
+ case GCRY_KDF_ITERSALTED_S2K:
+ ec = openpgp_s2k (passphrase, passphraselen, algo, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ case GCRY_KDF_PBKDF1:
+ ec = GPG_ERR_UNSUPPORTED_ALGORITHM;
+ break;
+
+ case GCRY_KDF_PBKDF2:
+ ec = pkdf2 (passphrase, passphraselen, subalgo,
+ salt, saltlen, iterations, keysize, keybuffer);
+ break;
+
+ default:
+ ec = GPG_ERR_UNKNOWN_ALGORITHM;
+ break;
+ }
+
+ leave:
+ return gpg_error (ec);
+}
gcry_md_spec_t *digest;
md_extra_spec_t *extraspec;
unsigned int algorithm;
- int fips_allowed;
+ int fips_allowed;
} digest_table[] =
{
-#if USE_CRC
+#if USE_CRC
/* We allow the CRC algorithms even in FIPS mode because they are
actually no cryptographic primitives. */
- { &_gcry_digest_spec_crc32,
+ { &_gcry_digest_spec_crc32,
&dummy_extra_spec, GCRY_MD_CRC32, 1 },
- { &_gcry_digest_spec_crc32_rfc1510,
+ { &_gcry_digest_spec_crc32_rfc1510,
&dummy_extra_spec, GCRY_MD_CRC32_RFC1510, 1 },
{ &_gcry_digest_spec_crc24_rfc2440,
&dummy_extra_spec, GCRY_MD_CRC24_RFC2440, 1 },
&dummy_extra_spec, GCRY_MD_RMD160 },
#endif
#if USE_SHA1
- { &_gcry_digest_spec_sha1,
+ { &_gcry_digest_spec_sha1,
&_gcry_digest_extraspec_sha1, GCRY_MD_SHA1, 1 },
#endif
#if USE_SHA256
{
gcry_err_code_t err = 0;
int i;
-
+
for (i = 0; !err && digest_table[i].digest; i++)
{
if ( fips_mode ())
}
/* Internal function. Lookup a digest entry by it's name. */
-static gcry_module_t
+static gcry_module_t
gcry_md_lookup_name (const char *name)
{
gcry_module_t digest;
ath_mutex_lock (&digests_registered_lock);
err = _gcry_module_add (&digests_registered, 0,
- (void *) digest,
- (void *)(extraspec? extraspec : &dummy_extra_spec),
+ (void *) digest,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
&mod);
ath_mutex_unlock (&digests_registered_lock);
-
+
if (! err)
{
*module = mod;
}
-static int
+static int
search_oid (const char *oid, int *algorithm, gcry_md_oid_spec_t *oid_spec)
{
gcry_module_t module;
else
digest = (gcry_md_spec_t *) module->spec;
-
+
if (!err && algorithm == GCRY_MD_MD5 && fips_mode ())
{
_gcry_inactivate_fips_mode ("MD5 used");
err = GPG_ERR_DIGEST_ALGO;
}
}
-
+
if (!err)
{
size_t size = (sizeof (*entry)
GcryDigestEntry *ar, *br;
gcry_md_hd_t bhd;
size_t n;
-
+
if (ahd->bufpos)
md_write (ahd, NULL, 0);
- sizeof (ar->context)));
br->next = b->list;
b->list = br;
-
+
/* Add a reference to the module. */
ath_mutex_lock (&digests_registered_lock);
_gcry_module_use (br->module);
md_write (gcry_md_hd_t a, const void *inbuf, size_t inlen)
{
GcryDigestEntry *r;
-
+
if (a->ctx->debug)
{
if (a->bufpos && fwrite (a->buf, a->bufpos, 1, a->ctx->debug) != 1)
if (err)
_gcry_fatal_error (err, NULL);
- md_write (om,
- (a->ctx->macpads)+(a->ctx->macpads_Bsize),
+ md_write (om,
+ (a->ctx->macpads)+(a->ctx->macpads_Bsize),
a->ctx->macpads_Bsize);
md_write (om, p, dlen);
md_final (om);
if (!algo)
return GPG_ERR_DIGEST_ALGO; /* Might happen if no algo is enabled. */
- if ( keylen > hd->ctx->macpads_Bsize )
+ if ( keylen > hd->ctx->macpads_Bsize )
{
helpkey = gcry_malloc_secure (md_digest_length (algo));
if (!helpkey)
opad = (hd->ctx->macpads)+(hd->ctx->macpads_Bsize);
memcpy ( ipad, key, keylen );
memcpy ( opad, key, keylen );
- for (i=0; i < hd->ctx->macpads_Bsize; i++ )
+ for (i=0; i < hd->ctx->macpads_Bsize; i++ )
{
ipad[i] ^= 0x36;
opad[i] ^= 0x5c;
gcry_md_ctl (gcry_md_hd_t hd, int cmd, void *buffer, size_t buflen)
{
gcry_err_code_t rc = 0;
-
+
switch (cmd)
{
case GCRYCTL_FINALIZE:
{
const char unsigned *asn;
size_t asnlen;
-
+
asn = md_asn_oid (algo, &asnlen, NULL);
if (buffer && (*nbytes >= asnlen))
{
if (fips_mode ())
return;
-
+
if ( md->ctx->debug )
{
log_debug("Oops: md debug already started\n");
volatile u64 b = 42;
volatile u64 c;
c = a * b;
+ (void)c;
}
#endif
}
else
{
algo = *(int*)buffer;
-
+
*nbytes = 0;
for(r=h->ctx->list; r; r = r->next ) {
if (r->module->mod_id == algo)
int
-gcry_md_is_secure (gcry_md_hd_t a)
+gcry_md_is_secure (gcry_md_hd_t a)
{
size_t value;
int
-gcry_md_is_enabled (gcry_md_hd_t a, int algo)
+gcry_md_is_enabled (gcry_md_hd_t a, int algo)
{
size_t value;
{
ec = GPG_ERR_DIGEST_ALGO;
if (report)
- report ("digest", algo, "module",
+ report ("digest", algo, "module",
module && !(module->flags & FLAG_MODULE_DISABLED)?
"no selftest available" :
module? "algorithm disabled" : "algorithm not found");
MD4_CONTEXT *hd = context;
if( hd->count == 64 ) /* flush the buffer */
- {
+ {
transform( hd, hd->buf );
_gcry_burn_stack (80+6*sizeof(void*));
hd->count = 0;
lsb <<= 3;
msb <<= 3;
msb |= t >> 29;
-
+
if( hd->count < 56 ) /* enough room */
{
hd->buf[hd->count++] = 0x80; /* pad */
while( hd->count < 56 )
hd->buf[hd->count++] = 0; /* pad */
}
- else /* need one extra block */
- {
+ else /* need one extra block */
+ {
hd->buf[hd->count++] = 0x80; /* pad character */
while( hd->count < 64 )
hd->buf[hd->count++] = 0;
md4_init, md4_write, md4_final, md4_read,
sizeof (MD4_CONTEXT)
};
-
*
* According to the definition of MD5 in RFC 1321 from April 1992.
* NOTE: This is *not* the same file as the one from glibc.
- * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
- * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
+ * Written by Ulrich Drepper <drepper@gnu.ai.mit.edu>, 1995.
+ * heavily modified for GnuPG by Werner Koch <wk@gnupg.org>
*/
/* Test values:
register u32 C = ctx->C;
register u32 D = ctx->D;
u32 *cwp = correct_words;
-
+
#ifdef WORDS_BIGENDIAN
- {
+ {
int i;
byte *p2;
const byte *p1;
{
const unsigned char *inbuf = inbuf_arg;
MD5_CONTEXT *hd = context;
-
+
if( hd->count == 64 ) /* flush the buffer */
{
transform( hd, hd->buf );
}
_gcry_burn_stack (80+6*sizeof(void*));
- while( inlen >= 64 )
+ while( inlen >= 64 )
{
transform( hd, inbuf );
hd->count = 0;
MD5_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
-
+
md5_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
#include "cipher.h"
#include "ath.h"
-static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
+static gcry_mpi_t gen_prime (unsigned int nbits, int secret, int randomlevel,
int (*extra_check)(void *, gcry_mpi_t),
void *extra_check_arg);
static int check_prime( gcry_mpi_t prime, gcry_mpi_t val_2, int rm_rounds,
\f
/* An object and a list to build up a global pool of primes. See
save_pool_prime and get_pool_prime. */
-struct primepool_s
+struct primepool_s
{
struct primepool_s *next;
gcry_mpi_t prime; /* If this is NULL the entry is not used. */
/* Remove some of the entries. Our strategy is removing
the last third from the list. */
int i;
-
+
for (i=0, item2 = primepool; item2; item2 = item2->next)
{
if (i >= n/3*2)
{
/* Out of memory. Silently giving up. */
gcry_mpi_release (prime);
- return;
+ return;
}
item->next = primepool;
primepool = item;
fbits = (pbits - req_qbits -1) / n;
qbits = pbits - n * fbits;
}
-
+
if (DBG_CIPHER)
log_debug ("gen prime: pbits=%u qbits=%u fbits=%u/%u n=%d\n",
pbits, req_qbits, qbits, fbits, n);
/* Generate a specific Q-Factor if requested. */
if (need_q_factor)
q_factor = gen_prime (req_qbits, is_secret, randomlevel, NULL, NULL);
-
+
/* Allocate an array to hold all factors + 2 for later usage. */
factors = gcry_calloc (n + 2, sizeof (*factors));
if (!factors)
}
for (i=0; i < n; i++)
pool_in_use[i] = -1;
-
+
/* Make a pool of 3n+5 primes (this is an arbitrary value). We
- require at least 30 primes for are useful selection process.
-
+ require at least 30 primes for are useful selection process.
+
Fixme: We need to research the best formula for sizing the pool.
*/
m = n * 3 + 5;
is_locked = 1;
for (i = 0; i < n; i++)
{
- perms[i] = 1;
+ perms[i] = 1;
/* At a maximum we use strong random for the factors.
This saves us a lot of entropy. Given that Q and
possible Q-factor are also used in the final prime
gcry_free (perms);
perms = NULL;
progress ('!');
- goto next_try;
+ goto next_try;
}
}
/* Generate next prime candidate:
- p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1.
+ p = 2 * q [ * q_factor] * factor_0 * factor_1 * ... * factor_n + 1.
*/
mpi_set (prime, q);
mpi_mul_ui (prime, prime, 2);
}
else
count1 = 0;
-
+
if (nprime > pbits)
{
if (++count2 > 20)
factors_new[i] = mpi_copy (factors[i]);
}
}
-
+
if (g)
{
/* Create a generator (start with 3). */
gcry_mpi_t tmp = mpi_alloc (mpi_get_nlimbs (prime));
gcry_mpi_t b = mpi_alloc (mpi_get_nlimbs (prime));
gcry_mpi_t pmin1 = mpi_alloc (mpi_get_nlimbs (prime));
-
+
if (need_q_factor)
err = GPG_ERR_NOT_IMPLEMENTED;
else
}
if (DBG_CIPHER)
progress('\n');
- }
+ }
while (i < n + 2);
mpi_free (factors[n+1]);
mpi_free (pmin1);
}
}
-
+
if (! DBG_CIPHER)
progress ('\n');
_gcry_generate_elg_prime (int mode, unsigned pbits, unsigned qbits,
gcry_mpi_t g, gcry_mpi_t **ret_factors)
{
- gcry_err_code_t err = GPG_ERR_NO_ERROR;
gcry_mpi_t prime = NULL;
-
- err = prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
- ret_factors, GCRY_WEAK_RANDOM, 0, 0,
- NULL, NULL);
+
+ if (prime_generate_internal ((mode == 1), &prime, pbits, qbits, g,
+ ret_factors, GCRY_WEAK_RANDOM, 0, 0,
+ NULL, NULL))
+ prime = NULL; /* (Should be NULL in the error case anyway.) */
return prime;
}
static gcry_mpi_t
-gen_prime (unsigned int nbits, int secret, int randomlevel,
+gen_prime (unsigned int nbits, int secret, int randomlevel,
int (*extra_check)(void *, gcry_mpi_t), void *extra_check_arg)
{
gcry_mpi_t prime, ptest, pminus1, val_2, val_3, result;
unsigned int x, step;
unsigned int count1, count2;
int *mods;
-
+
/* if ( DBG_CIPHER ) */
/* log_debug ("generate a prime of %u bits ", nbits ); */
for (;;)
{ /* try forvever */
int dotcount=0;
-
+
/* generate a random number */
gcry_mpi_randomize( prime, nbits, randomlevel );
-
+
/* Set high order bit to 1, set low order bit to 1. If we are
generating a secret prime we are most probably doing that
for RSA, to make sure that the modulus does have the
if (secret)
mpi_set_bit (prime, nbits-2);
mpi_set_bit(prime, 0);
-
+
/* Calculate all remainders. */
for (i=0; (x = small_prime_numbers[i]); i++ )
mods[i] = mpi_fdiv_r_ui(NULL, prime, x);
-
+
/* Now try some primes starting with prime. */
- for(step=0; step < 20000; step += 2 )
+ for(step=0; step < 20000; step += 2 )
{
/* Check against all the small primes we have in mods. */
count1++;
- for (i=0; (x = small_prime_numbers[i]); i++ )
+ for (i=0; (x = small_prime_numbers[i]); i++ )
{
while ( mods[i] + step >= x )
mods[i] -= x;
}
if ( x )
continue; /* Found a multiple of an already known prime. */
-
+
mpi_add_ui( ptest, prime, step );
/* Do a fast Fermat test now. */
mpi_sub_ui( pminus1, ptest, 1);
gcry_mpi_powm( result, val_2, pminus1, ptest );
if ( !mpi_cmp_ui( result, 1 ) )
- {
+ {
/* Not composite, perform stronger tests */
if (is_prime(ptest, 5, &count2 ))
{
}
if (extra_check && extra_check (extra_check_arg, ptest))
- {
+ {
/* The extra check told us that this prime is
not of the caller's taste. */
progress ('/');
}
else
- {
+ {
/* Got it. */
mpi_free(val_2);
mpi_free(val_3);
mpi_free(pminus1);
mpi_free(prime);
gcry_free(mods);
- return ptest;
+ return ptest;
}
}
}
gcry_mpi_powm( result, val_2, pminus1, prime );
mpi_free( pminus1 );
if ( mpi_cmp_ui( result, 1 ) )
- {
+ {
/* Is composite. */
mpi_free( result );
progress('.');
unsigned nbits = mpi_get_nbits( n );
if (steps < 5) /* Make sure that we do at least 5 rounds. */
- steps = 5;
+ steps = 5;
mpi_sub_ui( nminus1, n, 1 );
j++;
if (j == m)
goto ready;
-
+
This code is based on the algorithm 452 from the "Collected
Algorithms From ACM, Volume II" by C. N. Liu and D. T. Tang.
*/
/* Need to handle this simple case separately. */
if( m == 1 )
- {
+ {
for (i=0; i < n; i++ )
{
if ( array[i] )
else
k1 = k2 + 1;
}
- else
+ else
{
/* M is even. */
if( !array[n-1] )
k2 = k1 + 1;
goto leave;
}
-
+
if( !(j1 & 1) )
{
k1 = n - j1;
}
scan:
jp = n - j1 - 1;
- for (i=1; i <= jp; i++ )
+ for (i=1; i <= jp; i++ )
{
i1 = jp + 2 - i;
if( array[i1-1] )
if (!prime)
return gpg_error (GPG_ERR_INV_ARG);
- *prime = NULL;
+ *prime = NULL;
if (flags & GCRY_PRIME_FLAG_SPECIAL_FACTOR)
mode = 1;
mpi_free (factors_generated[i]);
gcry_free (factors_generated);
}
- err = GPG_ERR_GENERAL;
+ err = GPG_ERR_GENERAL;
}
}
if (!factors || !r_g || !prime)
return gpg_error (GPG_ERR_INV_ARG);
- *r_g = NULL;
+ *r_g = NULL;
for (n=0; factors[n]; n++)
;
if (n < 2)
return gpg_error (GPG_ERR_INV_ARG);
- /* Extra sanity check - usually disabled. */
+ /* Extra sanity check - usually disabled. */
/* mpi_set (tmp, factors[0]); */
/* for(i = 1; i < n; i++) */
/* mpi_mul (tmp, tmp, factors[i]); */
/* mpi_add_ui (tmp, tmp, 1); */
/* if (mpi_cmp (prime, tmp)) */
/* return gpg_error (GPG_ERR_INV_ARG); */
-
- gcry_mpi_sub_ui (pmin1, prime, 1);
- do
+
+ gcry_mpi_sub_ui (pmin1, prime, 1);
+ do
{
if (first)
first = 0;
else
gcry_mpi_add_ui (g, g, 1);
-
+
if (DBG_CIPHER)
{
log_debug ("checking g:");
}
else
progress('^');
-
+
for (i = 0; i < n; i++)
{
mpi_fdiv_q (tmp, pmin1, factors[i]);
progress('\n');
}
while (i < n);
-
+
gcry_mpi_release (tmp);
- gcry_mpi_release (b);
- gcry_mpi_release (pmin1);
- *r_g = g;
+ gcry_mpi_release (b);
+ gcry_mpi_release (pmin1);
+ *r_g = g;
- return 0;
+ return 0;
}
/* Convenience function to release the factors array. */
if (factors)
{
int i;
-
+
for (i=0; factors[i]; i++)
mpi_free (factors[i]);
gcry_free (factors);
static gcry_mpi_t
find_x931_prime (const gcry_mpi_t pfirst)
{
- gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
gcry_mpi_t prime;
-
+
prime = gcry_mpi_copy (pfirst);
- /* If P is even add 1. */
+ /* If P is even add 1. */
mpi_set_bit (prime, 0);
/* We use 64 Rabin-Miller rounds which is better and thus
}
-/* Generate a prime using the algorithm from X9.31 appendix B.4.
+/* Generate a prime using the algorithm from X9.31 appendix B.4.
This function requires that the provided public exponent E is odd.
XP, XP1 and XP2 are the seed values. All values are mandatory.
internal values P1 and P2 are saved at these addresses. On error
NULL is returned. */
gcry_mpi_t
-_gcry_derive_x931_prime (const gcry_mpi_t xp,
+_gcry_derive_x931_prime (const gcry_mpi_t xp,
const gcry_mpi_t xp1, const gcry_mpi_t xp2,
const gcry_mpi_t e,
gcry_mpi_t *r_p1, gcry_mpi_t *r_p2)
{
gcry_mpi_t r1, tmp;
-
+
/* r1 = (p2^{-1} mod p1)p2 - (p1^{-1} mod p2) */
tmp = mpi_alloc_like (p1);
mpi_invm (tmp, p2, p1);
mpi_mul (tmp, tmp, p2);
r1 = tmp;
-
+
tmp = mpi_alloc_like (p2);
mpi_invm (tmp, p1, p2);
mpi_mul (tmp, tmp, p1);
mpi_sub (r1, r1, tmp);
/* Fixup a negative value. */
- if (mpi_is_neg (r1))
+ if (mpi_is_neg (r1))
mpi_add (r1, r1, p1p2);
/* yp0 = xp + (r1 - xp mod p1*p2) */
mpi_free (r1);
/* Fixup a negative value. */
- if (mpi_cmp (yp0, xp) < 0 )
+ if (mpi_cmp (yp0, xp) < 0 )
mpi_add (yp0, yp0, p1p2);
}
*/
{
- gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
+ gcry_mpi_t val_2 = mpi_alloc_set_ui (2);
gcry_mpi_t gcdtmp = mpi_alloc_like (yp0);
int gcdres;
-
+
mpi_sub_ui (p1p2, p1p2, 1); /* Adjust for loop body. */
mpi_sub_ui (yp0, yp0, 1); /* Ditto. */
for (;;)
; /* No seed value given: We are asked to generate it. */
else if (!seed || seedlen < qbits/8)
return GPG_ERR_INV_ARG;
-
+
/* Allocate a buffer to later compute SEED+some_increment. */
seed_plus = gcry_malloc (seedlen < 20? 20:seedlen);
if (!seed_plus)
value_w = gcry_mpi_new (pbits);
value_x = gcry_mpi_new (pbits);
- restart:
+ restart:
/* Generate Q. */
for (;;)
{
gcry_create_nonce (seed_help_buffer, seedlen);
seed = seed_help_buffer;
}
-
+
/* Step 2: U = sha1(seed) ^ sha1((seed+1) mod 2^{qbits}) */
memcpy (seed_plus, seed, seedlen);
for (i=seedlen-1; i >= 0; i--)
gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
for (i=0; i < sizeof value_u; i++)
value_u[i] ^= digest[i];
-
+
/* Step 3: Form q from U */
gcry_mpi_release (prime_q); prime_q = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
value_u, sizeof value_u, NULL));
if (ec)
goto leave;
mpi_set_highbit (prime_q, qbits-1 );
mpi_set_bit (prime_q, 0);
-
+
/* Step 4: Test whether Q is prime using 64 round of Rabin-Miller. */
if (check_prime (prime_q, val_2, 64, NULL, NULL))
break; /* Yes, Q is prime. */
/* Step 5. */
seed = NULL; /* Force a new seed at Step 1. */
}
-
+
/* Step 6. Note that we do no use an explicit offset but increment
SEED_PLUS accordingly. SEED_PLUS is currently SEED+1. */
counter = 0;
prime_p = gcry_mpi_new (pbits);
for (;;)
{
- /* Step 7: For k = 0,...n let
- V_k = sha1(seed+offset+k) mod 2^{qbits}
- Step 8: W = V_0 + V_1*2^160 +
- ...
+ /* Step 7: For k = 0,...n let
+ V_k = sha1(seed+offset+k) mod 2^{qbits}
+ Step 8: W = V_0 + V_1*2^160 +
+ ...
+ V_{n-1}*2^{(n-1)*160}
- + (V_{n} mod 2^b)*2^{n*160}
+ + (V_{n} mod 2^b)*2^{n*160}
*/
mpi_set_ui (value_w, 0);
for (value_k=0; value_k <= value_n; value_k++)
break;
}
gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-
+
gcry_mpi_release (tmpval); tmpval = NULL;
ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
digest, sizeof digest, NULL));
value is stored at R_COUNTER and the seed actually used for
generation is stored at R_SEED and R_SEEDVALUE. The hash algorithm
used is stored at R_HASHALGO.
-
+
Note that this function is very similar to the fips186_2 code. Due
to the minor differences, other buffer sizes and for documentarion,
we use a separate function.
gcry_mpi_t tmpval = NULL; /* Helper variable. */
int hashalgo; /* The id of the Approved Hash Function. */
int i;
-
+
unsigned char value_u[256/8];
int value_n, value_b, value_j;
int counter;
; /* No seed value given: We are asked to generate it. */
else if (!seed || seedlen < qbits/8)
return GPG_ERR_INV_ARG;
-
+
/* Allocate a buffer to later compute SEED+some_increment and a few
helper variables. */
- seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer?
+ seed_plus = gcry_malloc (seedlen < sizeof seed_help_buffer?
sizeof seed_help_buffer : seedlen);
if (!seed_plus)
{
/* Step 4: b = L - 1 - (n * outlen) */
value_b = pbits - 1 - (value_n * qbits);
- restart:
+ restart:
/* Generate Q. */
for (;;)
{
gcry_create_nonce (seed_help_buffer, seedlen);
seed = seed_help_buffer;
}
-
+
/* Step 6: U = hash(seed) */
gcry_md_hash_buffer (hashalgo, value_u, seed, seedlen);
}
}
gcry_mpi_release (prime_q); prime_q = NULL;
- ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
+ ec = gpg_err_code (gcry_mpi_scan (&prime_q, GCRYMPI_FMT_USG,
value_u, sizeof value_u, NULL));
if (ec)
goto leave;
mpi_set_highbit (prime_q, qbits-1 );
-
+
/* Step 8: Test whether Q is prime using 64 round of Rabin-Miller.
According to table C.1 this is sufficient for all
supported prime sizes (i.e. up 3072/256). */
/* Step 8. */
seed = NULL; /* Force a new seed at Step 5. */
}
-
+
/* Step 11. Note that we do no use an explicit offset but increment
SEED_PLUS accordingly. */
memcpy (seed_plus, seed, seedlen);
prime_p = gcry_mpi_new (pbits);
for (;;)
{
- /* Step 11.1: For j = 0,...n let
- V_j = hash(seed+offset+j)
- Step 11.2: W = V_0 + V_1*2^outlen +
- ...
+ /* Step 11.1: For j = 0,...n let
+ V_j = hash(seed+offset+j)
+ Step 11.2: W = V_0 + V_1*2^outlen +
+ ...
+ V_{n-1}*2^{(n-1)*outlen}
- + (V_{n} mod 2^b)*2^{n*outlen}
+ + (V_{n} mod 2^b)*2^{n*outlen}
*/
mpi_set_ui (value_w, 0);
for (value_j=0; value_j <= value_n; value_j++)
break;
}
gcry_md_hash_buffer (GCRY_MD_SHA1, digest, seed_plus, seedlen);
-
+
gcry_mpi_release (tmpval); tmpval = NULL;
ec = gpg_err_code (gcry_mpi_scan (&tmpval, GCRYMPI_FMT_USG,
digest, sizeof digest, NULL));
if (mpi_get_nbits (prime_p) >= pbits-1
&& check_prime (prime_p, val_2, 64, NULL, NULL) )
break; /* Yes, P is prime, continue with Step 15. */
-
+
/* Step 11.9: counter = counter + 1, offset = offset + n + 1.
If counter >= 4L goto Step 5. */
counter++;
gcry_mpi_release (val_2);
return ec;
}
-
/* pubkey.c - pubkey dispatcher
- * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
- * 2007, 2008 Free Software Foundation, Inc.
+ * Copyright (C) 1998, 1999, 2000, 2002, 2003, 2005,
+ * 2007, 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
gcry_pk_spec_t *pubkey;
pk_extra_spec_t *extraspec;
unsigned int algorithm;
- int fips_allowed;
+ int fips_allowed;
} pubkey_table[] =
{
#if USE_RSA
#if USE_ECC
{ &_gcry_pubkey_spec_ecdsa,
&_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDSA, 0 },
+ { &_gcry_pubkey_spec_ecdh,
+ &_gcry_pubkey_extraspec_ecdsa, GCRY_PK_ECDH, 0 },
#endif
{ NULL, 0 },
};
{
gcry_err_code_t err = 0;
int i;
-
+
for (i = 0; (! err) && pubkey_table[i].pubkey; i++)
{
#define pubkey_use_dummy(func) \
err = _gcry_module_add (&pubkeys_registered,
pubkey_table[i].algorithm,
- (void *) pubkey_table[i].pubkey,
- (void *) pubkey_table[i].extraspec,
+ (void *) pubkey_table[i].pubkey,
+ (void *) pubkey_table[i].extraspec,
NULL);
}
}
/* Internal function. Lookup a pubkey entry by it's name. */
-static gcry_module_t
+static gcry_module_t
gcry_pk_lookup_name (const char *name)
{
gcry_module_t pubkey;
ath_mutex_lock (&pubkeys_registered_lock);
err = _gcry_module_add (&pubkeys_registered, 0,
- (void *) pubkey,
- (void *)(extraspec? extraspec : &dummy_extra_spec),
+ (void *) pubkey,
+ (void *)(extraspec? extraspec : &dummy_extra_spec),
&mod);
ath_mutex_unlock (&pubkeys_registered_lock);
if (extraspec && extraspec->ext_generate)
{
/* Use the extended generate function. */
- ec = extraspec->ext_generate
+ ec = extraspec->ext_generate
(algorithm, nbits, use_e, genparms, skey, retfactors, r_extrainfo);
}
else
{
/* Use the standard generate function. */
- ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
+ ec = ((gcry_pk_spec_t *) pubkey->spec)->generate
(algorithm, nbits, use_e, skey, retfactors);
}
_gcry_module_release (pubkey);
/* Note: In fips mode DBG_CIPHER will enver evaluate to true but as
an extra failsafe protection we explicitly test for fips mode
- here. */
+ here. */
if (DBG_CIPHER && !fips_mode ())
{
log_debug ("pubkey_encrypt: algo=%d\n", algorithm);
}
rc = GPG_ERR_PUBKEY_ALGO;
-
+
ready:
ath_mutex_unlock (&pubkeys_registered_lock);
{
log_debug ("pubkey_verify: algo=%d\n", algorithm);
for (i = 0; i < pubkey_get_npkey (algorithm); i++)
- log_mpidump (" pkey:", pkey[i]);
+ log_mpidump (" pkey", pkey[i]);
for (i = 0; i < pubkey_get_nsig (algorithm); i++)
- log_mpidump (" sig:", data[i]);
- log_mpidump (" hash:", hash);
+ log_mpidump (" sig", data[i]);
+ log_mpidump (" hash", hash);
}
ath_mutex_lock (&pubkeys_registered_lock);
}
+/* Turn VALUE into an octet string and store it in an allocated buffer
+ at R_FRAME or - if R_RAME is NULL - copy it into the caller
+ provided buffer SPACE; either SPACE or R_FRAME may be used. If
+ SPACE if not NULL, the caller must provide a buffer of at least
+ NBYTES. If the resulting octet string is shorter than NBYTES pad
+ it to the left with zeroes. If VALUE does not fit into NBYTES
+ return an error code. */
+static gpg_err_code_t
+octet_string_from_mpi (unsigned char **r_frame, void *space,
+ gcry_mpi_t value, size_t nbytes)
+{
+ gpg_err_code_t rc;
+ size_t nframe, noff, n;
+ unsigned char *frame;
+
+ if (!r_frame == !space)
+ return GPG_ERR_INV_ARG; /* Only one may be used. */
+
+ if (r_frame)
+ *r_frame = NULL;
+
+ rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
+ NULL, 0, &nframe, value));
+ if (rc)
+ return rc;
+ if (nframe > nbytes)
+ return GPG_ERR_TOO_LARGE; /* Value too long to fit into NBYTES. */
+
+ noff = (nframe < nbytes)? nbytes - nframe : 0;
+ n = nframe + noff;
+ if (space)
+ frame = space;
+ else
+ {
+ frame = mpi_is_secure (value)? gcry_malloc_secure (n) : gcry_malloc (n);
+ if (!frame)
+ {
+ rc = gpg_err_code_from_syserror ();
+ return rc;
+ }
+ }
+ if (noff)
+ memset (frame, 0, noff);
+ nframe += noff;
+ rc = gcry_err_code (gcry_mpi_print (GCRYMPI_FMT_USG,
+ frame+noff, nframe-noff, NULL, value));
+ if (rc)
+ {
+ gcry_free (frame);
+ return rc;
+ }
+
+ if (r_frame)
+ *r_frame = frame;
+ return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys using the pkcs#1 block
+ type 2 padding. On sucess the result is stored as a new MPI at
+ R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests. Note that this value may not
+ contain zero bytes.
+
+ We encode the value in this way:
+
+ 0 2 RND(n bytes) 0 VALUE
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 2 is the block type.
+ RND are non-zero random bytes.
+
+ (Note that OpenPGP includes the cipher algorithm and a checksum in
+ VALUE; the caller needs to prepare the value accordingly.)
+ */
+static gcry_err_code_t
+pkcs1_encode_for_encryption (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *random_override,
+ size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ unsigned char *p;
+
+ if (valuelen + 7 > nframe || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ if ( !(frame = gcry_malloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 2; /* block type */
+ i = nframe - 3 - valuelen;
+ gcry_assert (i > 0);
+
+ if (random_override)
+ {
+ int j;
+
+ if (random_override_len != i)
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ /* Check that random does not include a zero byte. */
+ for (j=0; j < random_override_len; j++)
+ if (!random_override[j])
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + n, random_override, random_override_len);
+ n += random_override_len;
+ }
+ else
+ {
+ p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
+ /* Replace zero bytes by new values. */
+ for (;;)
+ {
+ int j, k;
+ unsigned char *pp;
+
+ /* Count the zero bytes. */
+ for (j=k=0; j < i; j++)
+ {
+ if (!p[j])
+ k++;
+ }
+ if (!k)
+ break; /* Okay: no (more) zero bytes. */
+
+ k += k/128 + 3; /* Better get some more. */
+ pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
+ for (j=0; j < i && k; )
+ {
+ if (!p[j])
+ p[j] = pp[--k];
+ if (p[j])
+ j++;
+ }
+ gcry_free (pp);
+ }
+ memcpy (frame+n, p, i);
+ n += i;
+ gcry_free (p);
+ }
+
+ frame[n++] = 0;
+ memcpy (frame+n, value, valuelen);
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 2 encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* Decode a plaintext in VALUE assuming pkcs#1 block type 2 padding.
+ NBITS is the size of the secret key. On success the result is
+ stored as a newly allocated buffer at R_RESULT and its valid length at
+ R_RESULTLEN. On error NULL is stored at R_RESULT. */
+static gcry_err_code_t
+pkcs1_decode_for_encryption (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, gcry_mpi_t value)
+{
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ size_t n;
+
+ *r_result = NULL;
+
+ if ( !(frame = gcry_malloc_secure (nframe)))
+ return gpg_err_code_from_syserror ();
+
+ err = gcry_mpi_print (GCRYMPI_FMT_USG, frame, nframe, &n, value);
+ if (err)
+ {
+ gcry_free (frame);
+ return gcry_err_code (err);
+ }
+
+ nframe = n; /* Set NFRAME to the actual length. */
+
+ /* FRAME = 0x00 || 0x02 || PS || 0x00 || M
+
+ pkcs#1 requires that the first byte is zero. Our MPIs usually
+ strip leading zero bytes; thus we are not able to detect them.
+ However due to the way gcry_mpi_print is implemented we may see
+ leading zero bytes nevertheless. We handle this by making the
+ first zero byte optional. */
+ if (nframe < 4)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Too short. */
+ }
+ n = 0;
+ if (!frame[0])
+ n++;
+ if (frame[n++] != 0x02)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* Wrong block type. */
+ }
+
+ /* Skip the non-zero random bytes and the terminating zero byte. */
+ for (; n < nframe && frame[n] != 0x00; n++)
+ ;
+ if (n+1 >= nframe)
+ {
+ gcry_free (frame);
+ return GPG_ERR_ENCODING_PROBLEM; /* No zero byte. */
+ }
+ n++; /* Skip the zero byte. */
+
+ /* To avoid an extra allocation we reuse the frame buffer. The only
+ caller of this function will anyway free the result soon. */
+ memmove (frame, frame + n, nframe - n);
+ *r_result = frame;
+ *r_resultlen = nframe - n;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from PKCS#1 block type 2 encoded data:",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* Encode {VALUE,VALUELEN} for an NBITS keys and hash algorith ALGO
+ using the pkcs#1 block type 1 padding. On success the result is
+ stored as a new MPI at R_RESULT. On error the value at R_RESULT is
+ undefined.
+
+ We encode the value in this way:
+
+ 0 1 PAD(n bytes) 0 ASN(asnlen bytes) VALUE(valuelen bytes)
+
+ 0 is a marker we unfortunately can't encode because we return an
+ MPI which strips all leading zeroes.
+ 1 is the block type.
+ PAD consists of 0xff bytes.
+ 0 marks the end of the padding.
+ ASN is the DER encoding of the hash algorithm; along with the VALUE
+ it yields a valid DER encoding.
+
+ (Note that PGP prior to version 2.3 encoded the message digest as:
+ 0 1 MD(16 bytes) 0 PAD(n bytes) 1
+ The MD is always 16 bytes here because it's always MD5. GnuPG
+ does not not support pre-v2.3 signatures, but I'm including this
+ comment so the information is easily found if needed.)
+*/
+static gcry_err_code_t
+pkcs1_encode_for_signature (gcry_mpi_t *r_result, unsigned int nbits,
+ const unsigned char *value, size_t valuelen,
+ int algo)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ byte asn[100];
+ byte *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ int i;
+ size_t n;
+ size_t asnlen, dlen;
+
+ asnlen = DIM(asn);
+ dlen = gcry_md_get_algo_dlen (algo);
+
+ if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
+ {
+ /* We don't have yet all of the above algorithms. */
+ return GPG_ERR_NOT_IMPLEMENTED;
+ }
+
+ if ( valuelen != dlen )
+ {
+ /* Hash value does not match the length of digest for
+ the given algorithm. */
+ return GPG_ERR_CONFLICT;
+ }
+
+ if ( !dlen || dlen + asnlen + 4 > nframe)
+ {
+ /* Can't encode an DLEN byte digest MD into an NFRAME byte
+ frame. */
+ return GPG_ERR_TOO_SHORT;
+ }
+
+ if ( !(frame = gcry_malloc (nframe)) )
+ return gpg_err_code_from_syserror ();
+
+ /* Assemble the pkcs#1 block type 1. */
+ n = 0;
+ frame[n++] = 0;
+ frame[n++] = 1; /* block type */
+ i = nframe - valuelen - asnlen - 3 ;
+ gcry_assert (i > 1);
+ memset (frame+n, 0xff, i );
+ n += i;
+ frame[n++] = 0;
+ memcpy (frame+n, asn, asnlen);
+ n += asnlen;
+ memcpy (frame+n, value, valuelen );
+ n += valuelen;
+ gcry_assert (n == nframe);
+
+ /* Convert it into an MPI. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, n, &nframe);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PKCS#1 block type 1 encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* Mask generation function for OAEP. See RFC-3447 B.2.1. */
+static gcry_err_code_t
+mgf1 (unsigned char *output, size_t outlen, unsigned char *seed, size_t seedlen,
+ int algo)
+{
+ size_t dlen, nbytes, n;
+ int idx;
+ gcry_md_hd_t hd;
+ gcry_error_t err;
+
+ err = gcry_md_open (&hd, algo, 0);
+ if (err)
+ return gpg_err_code (err);
+
+ dlen = gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1 which would be assert(OUTLEN <= 2^32). The loop
+ in step 3 is merged with step 4 by concatenating no more octets
+ than what would fit into OUTPUT. The ceiling for the counter IDX
+ is implemented indirectly. */
+ nbytes = 0; /* Step 2. */
+ idx = 0;
+ while ( nbytes < outlen )
+ {
+ unsigned char c[4], *digest;
+
+ if (idx)
+ gcry_md_reset (hd);
+
+ c[0] = (idx >> 24) & 0xFF;
+ c[1] = (idx >> 16) & 0xFF;
+ c[2] = (idx >> 8) & 0xFF;
+ c[3] = idx & 0xFF;
+ idx++;
+
+ gcry_md_write (hd, seed, seedlen);
+ gcry_md_write (hd, c, 4);
+ digest = gcry_md_read (hd, 0);
+
+ n = (outlen - nbytes < dlen)? (outlen - nbytes) : dlen;
+ memcpy (output+nbytes, digest, n);
+ nbytes += n;
+ }
+
+ gcry_md_close (hd);
+ return GPG_ERR_NO_ERROR;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP encoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. {VALUE,VALUELEN} is the message to
+ encrypt. {LABEL,LABELLEN} is the optional label to be associated
+ with the message, if LABEL is NULL the default is to use the empty
+ string as label. On success the encoded ciphertext is returned at
+ R_RESULT.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the seed instead of using a random string for it. This feature is
+ only useful for regression tests.
+
+ Here is figure 1 from the RFC depicting the process:
+
+ +----------+---------+-------+
+ DB = | lHash | PS | M |
+ +----------+---------+-------+
+ |
+ +----------+ V
+ | seed |--> MGF ---> xor
+ +----------+ |
+ | |
+ +--+ V |
+ |00| xor <----- MGF <-----|
+ +--+ | |
+ | | |
+ V V V
+ +--+----------+----------------------------+
+ EM = |00|maskedSeed| maskedDB |
+ +--+----------+----------------------------+
+ */
+static gcry_err_code_t
+oaep_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen,
+ const unsigned char *label, size_t labellen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ unsigned char *frame = NULL;
+ size_t nframe = (nbits+7) / 8;
+ unsigned char *p;
+ size_t hlen;
+ size_t n;
+
+ *r_result = NULL;
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ hlen = gcry_md_get_algo_dlen (algo);
+
+ /* We skip step 1a which would be to check that LABELLEN is not
+ greater than 2^61-1. See rfc-3447 7.1.1. */
+
+ /* Step 1b. Note that the obsolete rfc-2437 uses the check:
+ valuelen > nframe - 2 * hlen - 1 . */
+ if (valuelen > nframe - 2 * hlen - 2 || !nframe)
+ {
+ /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
+ return GPG_ERR_TOO_SHORT; /* The key is too short. */
+ }
+
+ /* Allocate the frame. */
+ frame = gcry_calloc_secure (1, nframe);
+ if (!frame)
+ return gpg_err_code_from_syserror ();
+
+ /* Step 2a: Compute the hash of the label. We store it in the frame
+ where later the maskedDB will commence. */
+ gcry_md_hash_buffer (algo, frame + 1 + hlen, label, labellen);
+
+ /* Step 2b: Set octet string to zero. */
+ /* This has already been done while allocating FRAME. */
+
+ /* Step 2c: Create DB by concatenating lHash, PS, 0x01 and M. */
+ n = nframe - valuelen - 1;
+ frame[n] = 0x01;
+ memcpy (frame + n + 1, value, valuelen);
+
+ /* Step 3d: Generate seed. We store it where the maskedSeed will go
+ later. */
+ if (random_override)
+ {
+ if (random_override_len != hlen)
+ {
+ gcry_free (frame);
+ return GPG_ERR_INV_ARG;
+ }
+ memcpy (frame + 1, random_override, hlen);
+ }
+ else
+ gcry_randomize (frame + 1, hlen, GCRY_STRONG_RANDOM);
+
+ /* Step 2e and 2f: Create maskedDB. */
+ {
+ unsigned char *dmask;
+
+ dmask = gcry_malloc_secure (nframe - hlen - 1);
+ if (!dmask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ return rc;
+ }
+ rc = mgf1 (dmask, nframe - hlen - 1, frame+1, hlen, algo);
+ if (rc)
+ {
+ gcry_free (dmask);
+ gcry_free (frame);
+ return rc;
+ }
+ for (n = 1 + hlen, p = dmask; n < nframe; n++)
+ frame[n] ^= *p++;
+ gcry_free (dmask);
+ }
+
+ /* Step 2g and 2h: Create maskedSeed. */
+ {
+ unsigned char *smask;
+
+ smask = gcry_malloc_secure (hlen);
+ if (!smask)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ return rc;
+ }
+ rc = mgf1 (smask, hlen, frame + 1 + hlen, nframe - hlen - 1, algo);
+ if (rc)
+ {
+ gcry_free (smask);
+ gcry_free (frame);
+ return rc;
+ }
+ for (n = 1, p = smask; n < 1 + hlen; n++)
+ frame[n] ^= *p++;
+ gcry_free (smask);
+ }
+
+ /* Step 2i: Concatenate 0x00, maskedSeed and maskedDB. */
+ /* This has already been done by using in-place operations. */
+
+ /* Convert the stuff into an MPI as expected by the caller. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, frame, nframe, NULL);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("OAEP encoded data", *r_result);
+ gcry_free (frame);
+
+ return rc;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) OAEP decoding. NBITS is the length of the
+ key measured in bits. ALGO is the hash function; it must be a
+ valid and usable algorithm. VALUE is the raw decrypted message
+ {LABEL,LABELLEN} is the optional label to be associated with the
+ message, if LABEL is NULL the default is to use the empty string as
+ label. On success the plaintext is returned as a newly allocated
+ buffer at R_RESULT; its valid length is stored at R_RESULTLEN. On
+ error NULL is stored at R_RESULT. */
+static gcry_err_code_t
+oaep_decode (unsigned char **r_result, size_t *r_resultlen,
+ unsigned int nbits, int algo,
+ gcry_mpi_t value, const unsigned char *label, size_t labellen)
+{
+ gcry_err_code_t rc;
+ unsigned char *frame = NULL; /* Encoded messages (EM). */
+ unsigned char *masked_seed; /* Points into FRAME. */
+ unsigned char *masked_db; /* Points into FRAME. */
+ unsigned char *seed = NULL; /* Allocated space for the seed and DB. */
+ unsigned char *db; /* Points into SEED. */
+ unsigned char *lhash = NULL; /* Hash of the label. */
+ size_t nframe; /* Length of the ciphertext (EM). */
+ size_t hlen; /* Length of the hash digest. */
+ size_t db_len; /* Length of DB and masked_db. */
+ size_t nkey = (nbits+7)/8; /* Length of the key in bytes. */
+ int failed = 0; /* Error indicator. */
+ size_t n;
+
+ *r_result = NULL;
+
+ /* This code is implemented as described by rfc-3447 7.1.2. */
+
+ /* Set defaults for LABEL. */
+ if (!label || !labellen)
+ {
+ label = (const unsigned char*)"";
+ labellen = 0;
+ }
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+
+ /* Hash the label right away. */
+ lhash = gcry_malloc (hlen);
+ if (!lhash)
+ return gpg_err_code_from_syserror ();
+ gcry_md_hash_buffer (algo, lhash, label, labellen);
+
+ /* Turn the MPI into an octet string. If the octet string is
+ shorter than the key we pad it to the left with zeroes. This may
+ happen due to the leading zero in OAEP frames and due to the
+ following random octets (seed^mask) which may have leading zero
+ bytes. This all is needed to cope with our leading zeroes
+ suppressing MPI implementation. The code implictly implements
+ Step 1b (bail out if NFRAME != N). */
+ rc = octet_string_from_mpi (&frame, NULL, value, nkey);
+ if (rc)
+ {
+ gcry_free (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+ nframe = nkey;
+
+ /* Step 1c: Check that the key is long enough. */
+ if ( nframe < 2 * hlen + 2 )
+ {
+ gcry_free (frame);
+ gcry_free (lhash);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 2 has already been done by the caller and the
+ gcry_mpi_aprint above. */
+
+ /* Allocate space for SEED and DB. */
+ seed = gcry_malloc_secure (nframe - 1);
+ if (!seed)
+ {
+ rc = gpg_err_code_from_syserror ();
+ gcry_free (frame);
+ gcry_free (lhash);
+ return rc;
+ }
+ db = seed + hlen;
+
+ /* To avoid choosen ciphertext attacks from now on we make sure to
+ run all code even in the error case; this avoids possible timing
+ attacks as described by Manger. */
+
+ /* Step 3a: Hash the label. */
+ /* This has already been done. */
+
+ /* Step 3b: Separate the encoded message. */
+ masked_seed = frame + 1;
+ masked_db = frame + 1 + hlen;
+ db_len = nframe - 1 - hlen;
+
+ /* Step 3c and 3d: seed = maskedSeed ^ mgf(maskedDB, hlen). */
+ if (mgf1 (seed, hlen, masked_db, db_len, algo))
+ failed = 1;
+ for (n = 0; n < hlen; n++)
+ seed[n] ^= masked_seed[n];
+
+ /* Step 3e and 3f: db = maskedDB ^ mgf(seed, db_len). */
+ if (mgf1 (db, db_len, seed, hlen, algo))
+ failed = 1;
+ for (n = 0; n < db_len; n++)
+ db[n] ^= masked_db[n];
+
+ /* Step 3g: Check lhash, an possible empty padding string terminated
+ by 0x01 and the first byte of EM being 0. */
+ if (memcmp (lhash, db, hlen))
+ failed = 1;
+ for (n = hlen; n < db_len; n++)
+ if (db[n] == 0x01)
+ break;
+ if (n == db_len)
+ failed = 1;
+ if (frame[0])
+ failed = 1;
+
+ gcry_free (lhash);
+ gcry_free (frame);
+ if (failed)
+ {
+ gcry_free (seed);
+ return GPG_ERR_ENCODING_PROBLEM;
+ }
+
+ /* Step 4: Output M. */
+ /* To avoid an extra allocation we reuse the seed buffer. The only
+ caller of this function will anyway free the result soon. */
+ n++;
+ memmove (seed, db + n, db_len - n);
+ *r_result = seed;
+ *r_resultlen = db_len - n;
+ seed = NULL;
+
+ if (DBG_CIPHER)
+ log_printhex ("value extracted from OAEP encoded data:",
+ *r_result, *r_resultlen);
+
+ return 0;
+}
+
+
+/* RFC-3447 (pkcs#1 v2.1) PSS encoding. Encode {VALUE,VALUELEN} for
+ an NBITS key. Note that VALUE is already the mHash from the
+ picture below. ALGO is a valid hash algorithm and SALTLEN is the
+ length of salt to be used. On success the result is stored as a
+ new MPI at R_RESULT. On error the value at R_RESULT is undefined.
+
+ If {RANDOM_OVERRIDE, RANDOM_OVERRIDE_LEN} is given it is used as
+ the salt instead of using a random string for the salt. This
+ feature is only useful for regression tests.
+
+ Here is figure 2 from the RFC (errata 595 applied) depicting the
+ process:
+
+ +-----------+
+ | M |
+ +-----------+
+ |
+ V
+ Hash
+ |
+ V
+ +--------+----------+----------+
+ M' = |Padding1| mHash | salt |
+ +--------+----------+----------+
+ |
+ +--------+----------+ V
+ DB = |Padding2| salt | Hash
+ +--------+----------+ |
+ | |
+ V | +----+
+ xor <--- MGF <---| |0xbc|
+ | | +----+
+ | | |
+ V V V
+ +-------------------+----------+----+
+ EM = | maskedDB | H |0xbc|
+ +-------------------+----------+----+
+
+ */
+static gcry_err_code_t
+pss_encode (gcry_mpi_t *r_result, unsigned int nbits, int algo,
+ const unsigned char *value, size_t valuelen, int saltlen,
+ const void *random_override, size_t random_override_len)
+{
+ gcry_err_code_t rc = 0;
+ gcry_error_t err;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *salt; /* Points into BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.1. */
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers. */
+ buflen = 8 + hlen + saltlen + (emlen - hlen - 1);
+ buf = gcry_malloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ mhash = buf + 8;
+ salt = mhash + hlen;
+ dbmask= salt + saltlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we do only a consistency check and copy to MHASH. */
+ if (valuelen != hlen)
+ {
+ rc = GPG_ERR_INV_LENGTH;
+ goto leave;
+ }
+ memcpy (mhash, value, hlen);
+
+ /* Step 3: Check length constraints. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT;
+ goto leave;
+ }
+
+ /* Allocate space for EM. */
+ em = gcry_malloc (emlen);
+ if (!em)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ h = em + emlen - 1 - hlen;
+
+ /* Step 4: Create a salt. */
+ if (saltlen)
+ {
+ if (random_override)
+ {
+ if (random_override_len != saltlen)
+ {
+ rc = GPG_ERR_INV_ARG;
+ goto leave;
+ }
+ memcpy (salt, random_override, saltlen);
+ }
+ else
+ gcry_randomize (salt, saltlen, GCRY_STRONG_RANDOM);
+ }
+
+ /* Step 5 and 6: M' = Hash(Padding1 || mHash || salt). */
+ memset (buf, 0, 8); /* Padding. */
+ gcry_md_hash_buffer (algo, h, buf, 8 + hlen + saltlen);
+
+ /* Step 7 and 8: DB = PS || 0x01 || salt. */
+ /* Note that we use EM to store DB and later Xor in-place. */
+ p = em + emlen - 1 - hlen - saltlen - 1;
+ memset (em, 0, p - em);
+ *p++ = 0x01;
+ memcpy (p, salt, saltlen);
+
+ /* Step 9: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 10: maskedDB = DB ^ dbMask */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 11: Set the leftmost bits to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 12: EM = maskedDB || H || 0xbc. */
+ em[emlen-1] = 0xbc;
+
+ /* Convert EM into an MPI. */
+ err = gcry_mpi_scan (r_result, GCRYMPI_FMT_USG, em, emlen, NULL);
+ if (err)
+ rc = gcry_err_code (err);
+ else if (DBG_CIPHER)
+ log_mpidump ("PSS encoded data", *r_result);
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ gcry_free (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ gcry_free (buf);
+ }
+ return rc;
+}
+
+
+/* Verify a signature assuming PSS padding. VALUE is the hash of the
+ message (mHash) encoded as an MPI; its length must match the digest
+ length of ALGO. ENCODED is the output of the RSA public key
+ function (EM). NBITS is the size of the public key. ALGO is the
+ hash algorithm and SALTLEN is the length of the used salt. The
+ function returns 0 on success or on error code. */
+static gcry_err_code_t
+pss_verify (gcry_mpi_t value, gcry_mpi_t encoded, unsigned int nbits, int algo,
+ size_t saltlen)
+{
+ gcry_err_code_t rc = 0;
+ size_t hlen; /* Length of the hash digest. */
+ unsigned char *em = NULL; /* Encoded message. */
+ size_t emlen = (nbits+7)/8; /* Length in bytes of EM. */
+ unsigned char *salt; /* Points into EM. */
+ unsigned char *h; /* Points into EM. */
+ unsigned char *buf = NULL; /* Help buffer. */
+ size_t buflen; /* Length of BUF. */
+ unsigned char *dbmask; /* Points into BUF. */
+ unsigned char *mhash; /* Points into BUF. */
+ unsigned char *p;
+ size_t n;
+
+ /* This code is implemented as described by rfc-3447 9.1.2. */
+
+ /* Get the length of the digest. */
+ hlen = gcry_md_get_algo_dlen (algo);
+ gcry_assert (hlen); /* We expect a valid ALGO here. */
+
+ /* Allocate a help buffer and setup some pointers.
+ This buffer is used for two purposes:
+ +------------------------------+-------+
+ 1. | dbmask | mHash |
+ +------------------------------+-------+
+ emlen - hlen - 1 hlen
+
+ +----------+-------+---------+-+-------+
+ 2. | padding1 | mHash | salt | | mHash |
+ +----------+-------+---------+-+-------+
+ 8 hlen saltlen hlen
+ */
+ buflen = 8 + hlen + saltlen;
+ if (buflen < emlen - hlen - 1)
+ buflen = emlen - hlen - 1;
+ buflen += hlen;
+ buf = gcry_malloc (buflen);
+ if (!buf)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ dbmask = buf;
+ mhash = buf + buflen - hlen;
+
+ /* Step 2: That would be: mHash = Hash(M) but our input is already
+ mHash thus we only need to convert VALUE into MHASH. */
+ rc = octet_string_from_mpi (NULL, mhash, value, hlen);
+ if (rc)
+ goto leave;
+
+ /* Convert the signature into an octet string. */
+ rc = octet_string_from_mpi (&em, NULL, encoded, emlen);
+ if (rc)
+ goto leave;
+
+ /* Step 3: Check length of EM. Because we internally use MPI
+ functions we can't do this properly; EMLEN is always the length
+ of the key because octet_string_from_mpi needs to left pad the
+ result with zero to cope with the fact that our MPIs suppress all
+ leading zeroes. Thus what we test here are merely the digest and
+ salt lengths to the key. */
+ if (emlen < hlen + saltlen + 2)
+ {
+ rc = GPG_ERR_TOO_SHORT; /* For the hash and saltlen. */
+ goto leave;
+ }
+
+ /* Step 4: Check last octet. */
+ if (em[emlen - 1] != 0xbc)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 5: Split EM. */
+ h = em + emlen - 1 - hlen;
+
+ /* Step 6: Check the leftmost bits. */
+ if ((em[0] & ~(0xFF >> (8 * emlen - nbits))))
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 7: dbmask = MGF(H, emlen - hlen - 1). */
+ mgf1 (dbmask, emlen - hlen - 1, h, hlen, algo);
+
+ /* Step 8: maskedDB = DB ^ dbMask. */
+ for (n = 0, p = dbmask; n < emlen - hlen - 1; n++, p++)
+ em[n] ^= *p;
+
+ /* Step 9: Set leftmost bits in DB to zero. */
+ em[0] &= 0xFF >> (8 * emlen - nbits);
+
+ /* Step 10: Check the padding of DB. */
+ for (n = 0; n < emlen - hlen - saltlen - 2 && !em[n]; n++)
+ ;
+ if (n != emlen - hlen - saltlen - 2 || em[n++] != 1)
+ {
+ rc = GPG_ERR_BAD_SIGNATURE;
+ goto leave;
+ }
+
+ /* Step 11: Extract salt from DB. */
+ salt = em + n;
+
+ /* Step 12: M' = (0x)00 00 00 00 00 00 00 00 || mHash || salt */
+ memset (buf, 0, 8);
+ memcpy (buf+8, mhash, hlen);
+ memcpy (buf+8+hlen, salt, saltlen);
+
+ /* Step 13: H' = Hash(M'). */
+ gcry_md_hash_buffer (algo, buf, buf, 8 + hlen + saltlen);
+
+ /* Step 14: Check H == H'. */
+ rc = memcmp (h, buf, hlen) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+
+ leave:
+ if (em)
+ {
+ wipememory (em, emlen);
+ gcry_free (em);
+ }
+ if (buf)
+ {
+ wipememory (buf, buflen);
+ gcry_free (buf);
+ }
+ return rc;
+}
+
+
+/* Callback for the pubkey algorithm code to verify PSS signatures.
+ OPAQUE is the data provided by the actual caller. The meaning of
+ TMP depends on the actual algorithm (but there is only RSA); now
+ for RSA it is the output of running the public key function on the
+ input. */
+static int
+pss_verify_cmp (void *opaque, gcry_mpi_t tmp)
+{
+ struct pk_encoding_ctx *ctx = opaque;
+ gcry_mpi_t hash = ctx->verify_arg;
+
+ return pss_verify (hash, tmp, ctx->nbits - 1, ctx->hash_algo, ctx->saltlen);
+}
+
+
/* Internal function. */
static gcry_err_code_t
sexp_elements_extract (gcry_sexp_t key_sexp, const char *element_names,
/* Clear the array for easier error cleanup. */
for (name = element_names, idx = 0; *name; name++, idx++)
elements[idx] = NULL;
- gcry_assert (idx >= 6); /* We know that ECC has at least 6 elements. */
+ gcry_assert (idx >= 5); /* We know that ECC has at least 5 elements
+ (params only) or 6 (full public key). */
+ if (idx == 5)
+ elements[5] = NULL; /* Extra clear for the params only case. */
+
/* Init the array with the available curve parameters. */
for (name = element_names, idx = 0; *name && !err; name++, idx++)
{
char *curve;
gcry_mpi_t params[6];
-
+
for (idx = 0; idx < DIM(params); idx++)
params[idx] = NULL;
-
+
curve = _gcry_sexp_nth_string (list, 1);
gcry_sexp_release (list);
if (!curve)
{
/* No curve name given (or out of core). */
- err = GPG_ERR_INV_OBJ;
+ err = GPG_ERR_INV_OBJ;
goto leave;
}
err = extraspec->get_param (curve, params);
gcry_free (curve);
if (err)
goto leave;
-
+
for (idx = 0; idx < DIM(params); idx++)
{
if (!elements[idx])
err = GPG_ERR_NO_OBJ;
goto leave;
}
-
+
leave:
if (err)
{
* openpgp-elg
* openpgp-elg-sig
* ecdsa
+ * ecdh
* Provide a SE with the first element be either "private-key" or
* or "public-key". It is followed by a list with its first element
* be one of the above algorithm identifiers and the remaning
* NOTE: we look through the list to find a list beginning with
* "private-key" or "public-key" - the first one found is used.
*
+ * If OVERRIDE_ELEMS is not NULL those elems override the parameter
+ * specification taken from the module. This ise used by
+ * gcry_pk_get_curve.
+ *
* Returns: A pointer to an allocated array of MPIs if the return value is
* zero; the caller has to release this array.
*
* The <mpi> are expected to be in GCRYMPI_FMT_USG
*/
static gcry_err_code_t
-sexp_to_key (gcry_sexp_t sexp, int want_private, gcry_mpi_t **retarray,
- gcry_module_t *retalgo)
+sexp_to_key (gcry_sexp_t sexp, int want_private, const char *override_elems,
+ gcry_mpi_t **retarray, gcry_module_t *retalgo)
{
gcry_err_code_t err = 0;
gcry_sexp_t list, l2;
int is_ecc;
/* Check that the first element is valid. */
- list = gcry_sexp_find_token (sexp,
+ list = gcry_sexp_find_token (sexp,
want_private? "private-key":"public-key", 0);
if (!list)
return GPG_ERR_INV_OBJ; /* Does not contain a key object. */
ath_mutex_lock (&pubkeys_registered_lock);
module = gcry_pk_lookup_name (name);
ath_mutex_unlock (&pubkeys_registered_lock);
-
+
/* Fixme: We should make sure that an ECC key is always named "ecc"
and not "ecdsa". "ecdsa" should be used for the signature
itself. We need a function to test whether an algorithm given
with a key is compatible with an application of the key (signing,
encryption). For RSA this is easy, but ECC is the first
- algorithm which has many flavours. */
- is_ecc = ( !strcmp (name, "ecdsa") || !strcmp (name, "ecc") );
+ algorithm which has many flavours. */
+ is_ecc = ( !strcmp (name, "ecdsa")
+ || !strcmp (name, "ecdh")
+ || !strcmp (name, "ecc") );
gcry_free (name);
-
+
if (!module)
{
gcry_sexp_release (list);
extraspec = module->extraspec;
}
- elems = want_private ? pubkey->elements_skey : pubkey->elements_pkey;
+ if (override_elems)
+ elems = override_elems;
+ else if (want_private)
+ elems = pubkey->elements_skey;
+ else
+ elems = pubkey->elements_pkey;
array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
if (!array)
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
if (!err)
{
if (is_ecc)
else
err = sexp_elements_extract (list, elems, array, pubkey->name);
}
-
+
gcry_sexp_release (list);
-
+
if (err)
{
gcry_free (array);
*retarray = array;
*retalgo = module;
}
-
+
return err;
}
gcry_mpi_t *array;
gcry_module_t module;
gcry_pk_spec_t *pubkey;
-
+
/* Check that the first element is valid. */
list = gcry_sexp_find_token( sexp, "sig-val" , 0 );
if (!list)
gcry_sexp_release (l2);
return GPG_ERR_INV_OBJ; /* Invalid structure of object. */
}
- else if (!strcmp (name, "flags"))
+ else if (!strcmp (name, "flags"))
{
/* Skip flags, since they are not used but here just for the
sake of consistent S-expressions. */
}
name = _gcry_sexp_nth_string (l2, 0);
}
-
+
ath_mutex_lock (&pubkeys_registered_lock);
module = gcry_pk_lookup_name (name);
ath_mutex_unlock (&pubkeys_registered_lock);
elems = pubkey->elements_sig;
array = gcry_calloc (strlen (elems) + 1 , sizeof *array );
if (!array)
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
if (!err)
err = sexp_elements_extract (list, elems, array, NULL);
ath_mutex_lock (&pubkeys_registered_lock);
_gcry_module_release (module);
ath_mutex_unlock (&pubkeys_registered_lock);
-
+
gcry_free (array);
}
else
*retarray = array;
*retalgo = module;
}
-
+
return err;
}
+static inline int
+get_hash_algo (const char *s, size_t n)
+{
+ static const struct { const char *name; int algo; } hashnames[] = {
+ { "sha1", GCRY_MD_SHA1 },
+ { "md5", GCRY_MD_MD5 },
+ { "sha256", GCRY_MD_SHA256 },
+ { "ripemd160", GCRY_MD_RMD160 },
+ { "rmd160", GCRY_MD_RMD160 },
+ { "sha384", GCRY_MD_SHA384 },
+ { "sha512", GCRY_MD_SHA512 },
+ { "sha224", GCRY_MD_SHA224 },
+ { "md2", GCRY_MD_MD2 },
+ { "md4", GCRY_MD_MD4 },
+ { "tiger", GCRY_MD_TIGER },
+ { "haval", GCRY_MD_HAVAL },
+ { NULL, 0 }
+ };
+ int algo;
+ int i;
+
+ for (i=0; hashnames[i].name; i++)
+ {
+ if ( strlen (hashnames[i].name) == n
+ && !memcmp (hashnames[i].name, s, n))
+ break;
+ }
+ if (hashnames[i].name)
+ algo = hashnames[i].algo;
+ else
+ {
+ /* In case of not listed or dynamically allocated hash
+ algorithm we fall back to this somewhat slower
+ method. Further, it also allows to use OIDs as
+ algorithm names. */
+ char *tmpname;
+
+ tmpname = gcry_malloc (n+1);
+ if (!tmpname)
+ algo = 0; /* Out of core - silently give up. */
+ else
+ {
+ memcpy (tmpname, s, n);
+ tmpname[n] = 0;
+ algo = gcry_md_map_name (tmpname);
+ gcry_free (tmpname);
+ }
+ }
+ return algo;
+}
+
/****************
* Take sexp and return an array of MPI as used for our internal decrypt
* function.
* s_data = (enc-val
- * [(flags [pkcs1])]
+ * [(flags [raw, pkcs1, oaep, no-blinding])]
+ * [(hash-algo <algo>)]
+ * [(label <label>)]
* (<algo>
* (<param_name1> <mpi>)
* ...
* (<param_namen> <mpi>)
* ))
+ * HASH-ALGO and LABEL are specific to OAEP.
* RET_MODERN is set to true when at least an empty flags list has been found.
+ * CTX is used to return encoding information; it may be NULL in which
+ * case raw encoding is used.
*/
static gcry_err_code_t
sexp_to_enc (gcry_sexp_t sexp, gcry_mpi_t **retarray, gcry_module_t *retalgo,
- int *ret_modern, int *ret_want_pkcs1, int *flags)
+ int *ret_modern, int *flags, struct pk_encoding_ctx *ctx)
{
gcry_err_code_t err = 0;
gcry_sexp_t list = NULL, l2 = NULL;
const char *elems;
gcry_mpi_t *array = NULL;
- *ret_want_pkcs1 = 0;
*ret_modern = 0;
/* Check that the first element is valid. */
err = GPG_ERR_INV_OBJ; /* Invalid structure of object. */
goto leave;
}
-
+
if (!strcmp (name, "flags"))
{
/* There is a flags element - process it. */
const char *s;
int i;
-
+
*ret_modern = 1;
for (i = gcry_sexp_length (l2) - 1; i > 0; i--)
{
s = gcry_sexp_nth_data (l2, i, &n);
if (! s)
; /* Not a data element - ignore. */
- else if (n == 3 && !memcmp (s, "raw", 3))
- ; /* This is just a dummy as it is the default. */
- else if (n == 5 && !memcmp (s, "pkcs1", 5))
- *ret_want_pkcs1 = 1;
+ else if (n == 3 && !memcmp (s, "raw", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW;
+ else if (n == 5 && !memcmp (s, "pkcs1", 5)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PKCS1;
+ else if (n == 4 && !memcmp (s, "oaep", 4)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_OAEP;
+ else if (n == 3 && !memcmp (s, "pss", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ {
+ err = GPG_ERR_CONFLICT;
+ goto leave;
+ }
else if (n == 11 && ! memcmp (s, "no-blinding", 11))
parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
else
goto leave;
}
}
-
- /* Get the next which has the actual data. */
gcry_sexp_release (l2);
- l2 = gcry_sexp_nth (list, 2);
+
+ /* Get the OAEP parameters HASH-ALGO and LABEL, if any. */
+ if (ctx->encoding == PUBKEY_ENC_OAEP)
+ {
+ /* Get HASH-ALGO. */
+ l2 = gcry_sexp_find_token (list, "hash-algo", 0);
+ if (l2)
+ {
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if (!s)
+ err = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ err = GPG_ERR_DIGEST_ALGO;
+ }
+ gcry_sexp_release (l2);
+ if (err)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ l2 = gcry_sexp_find_token (list, "label", 0);
+ if (l2)
+ {
+ s = gcry_sexp_nth_data (l2, 1, &n);
+ if (!s)
+ err = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = gcry_malloc (n);
+ if (!ctx->label)
+ err = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ gcry_sexp_release (l2);
+ if (err)
+ goto leave;
+ }
+ }
+
+ /* Get the next which has the actual data - skip HASH-ALGO and LABEL. */
+ for (i = 2; (l2 = gcry_sexp_nth (list, i)) != NULL; i++)
+ {
+ s = gcry_sexp_nth_data (l2, 0, &n);
+ if (!(n == 9 && !memcmp (s, "hash-algo", 9))
+ && !(n == 5 && !memcmp (s, "label", 5))
+ && !(n == 15 && !memcmp (s, "random-override", 15)))
+ break;
+ gcry_sexp_release (l2);
+ }
+
if (!l2)
{
err = GPG_ERR_NO_OBJ; /* No cdr for the data object. */
ath_mutex_lock (&pubkeys_registered_lock);
module = gcry_pk_lookup_name (name);
ath_mutex_unlock (&pubkeys_registered_lock);
-
+
if (!module)
{
err = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
array = gcry_calloc (strlen (elems) + 1, sizeof (*array));
if (!array)
{
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
goto leave;
}
_gcry_module_release (module);
ath_mutex_unlock (&pubkeys_registered_lock);
gcry_free (array);
+ gcry_free (ctx->label);
+ ctx->label = NULL;
}
else
{
passing to the low level functions. We currently support the
old style way of passing just a MPI and the modern interface which
allows to pass flags so that we can choose between raw and pkcs1
- padding - may be more padding options later.
+ padding - may be more padding options later.
(<mpi>)
or
(data
- [(flags [pkcs1])]
+ [(flags [raw, pkcs1, oaep, pss, no-blinding])]
[(hash <algo> <value>)]
[(value <text>)]
+ [(hash-algo <algo>)]
+ [(label <label>)]
+ [(salt-length <length>)]
+ [(random-override <data>)]
)
-
+
Either the VALUE or the HASH element must be present for use
with signatures. VALUE is used for encryption.
- NBITS is the length of the key in bits.
+ HASH-ALGO and LABEL are specific to OAEP.
-*/
+ SALT-LENGTH is for PSS.
+
+ RANDOM-OVERRIDE is used to replace random nonces for regression
+ testing. */
static gcry_err_code_t
-sexp_data_to_mpi (gcry_sexp_t input, unsigned int nbits, gcry_mpi_t *ret_mpi,
- int for_encryption, int *flags)
+sexp_data_to_mpi (gcry_sexp_t input, gcry_mpi_t *ret_mpi,
+ struct pk_encoding_ctx *ctx)
{
gcry_err_code_t rc = 0;
gcry_sexp_t ldata, lhash, lvalue;
int i;
size_t n;
const char *s;
- int is_raw = 0, is_pkcs1 = 0, unknown_flag=0;
- int parsed_flags = 0, dummy_flags;
+ int unknown_flag=0;
+ int parsed_flags = 0;
- if (! flags)
- flags = &dummy_flags;
-
*ret_mpi = NULL;
ldata = gcry_sexp_find_token (input, "data", 0);
if (!ldata)
s = gcry_sexp_nth_data (lflags, i, &n);
if (!s)
; /* not a data element*/
- else if ( n == 3 && !memcmp (s, "raw", 3))
- is_raw = 1;
- else if ( n == 5 && !memcmp (s, "pkcs1", 5))
- is_pkcs1 = 1;
+ else if ( n == 3 && !memcmp (s, "raw", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW;
+ else if ( n == 5 && !memcmp (s, "pkcs1", 5)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PKCS1;
+ else if ( n == 4 && !memcmp (s, "oaep", 4)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_OAEP;
+ else if ( n == 3 && !memcmp (s, "pss", 3)
+ && ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_PSS;
else if (n == 11 && ! memcmp (s, "no-blinding", 11))
parsed_flags |= PUBKEY_FLAG_NO_BLINDING;
else
}
}
- if (!is_pkcs1 && !is_raw)
- is_raw = 1; /* default to raw */
+ if (ctx->encoding == PUBKEY_ENC_UNKNOWN)
+ ctx->encoding = PUBKEY_ENC_RAW; /* default to raw */
/* Get HASH or MPI */
lhash = gcry_sexp_find_token (ldata, "hash", 0);
rc = GPG_ERR_INV_OBJ; /* none or both given */
else if (unknown_flag)
rc = GPG_ERR_INV_FLAG;
- else if (is_raw && is_pkcs1 && !for_encryption)
- rc = GPG_ERR_CONFLICT;
- else if (is_raw && lvalue)
+ else if (ctx->encoding == PUBKEY_ENC_RAW && lvalue)
{
- *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, 0);
+ *ret_mpi = gcry_sexp_nth_mpi (lvalue, 1, GCRYMPI_FMT_USG);
if (!*ret_mpi)
rc = GPG_ERR_INV_OBJ;
}
- else if (is_pkcs1 && lvalue && for_encryption)
- {
- /* Create pkcs#1 block type 2 padding. */
- unsigned char *frame = NULL;
- size_t nframe = (nbits+7) / 8;
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
+ const void * value;
+ size_t valuelen;
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ rc = pkcs1_encode_for_encryption (ret_mpi, ctx->nbits,
+ value, valuelen,
+ random_override,
+ random_override_len);
+ gcry_free (random_override);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_PKCS1 && lhash
+ && (ctx->op == PUBKEY_OP_SIGN || ctx->op == PUBKEY_OP_VERIFY))
+ {
+ if (gcry_sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ const void * value;
+ size_t valuelen;
+
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
+ || !valuelen )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ rc = pkcs1_encode_for_signature (ret_mpi, ctx->nbits,
+ value, valuelen,
+ ctx->hash_algo);
+ }
+ }
+ else if (ctx->encoding == PUBKEY_ENC_OAEP && lvalue
+ && ctx->op == PUBKEY_OP_ENCRYPT)
+ {
const void * value;
size_t valuelen;
- unsigned char *p;
if ( !(value=gcry_sexp_nth_data (lvalue, 1, &valuelen)) || !valuelen )
- rc = GPG_ERR_INV_OBJ;
- else if (valuelen + 7 > nframe || !nframe)
- {
- /* Can't encode a VALUELEN value in a NFRAME bytes frame. */
- rc = GPG_ERR_TOO_SHORT; /* the key is too short */
- }
- else if ( !(frame = gcry_malloc_secure (nframe)))
- rc = gpg_err_code_from_errno (errno);
+ rc = GPG_ERR_INV_OBJ;
else
- {
- n = 0;
- frame[n++] = 0;
- frame[n++] = 2; /* block type */
- i = nframe - 3 - valuelen;
- gcry_assert (i > 0);
- p = gcry_random_bytes_secure (i, GCRY_STRONG_RANDOM);
- /* Replace zero bytes by new values. */
- for (;;)
+ {
+ gcry_sexp_t list;
+ void *random_override = NULL;
+ size_t random_override_len = 0;
+
+ /* Get HASH-ALGO. */
+ list = gcry_sexp_find_token (ldata, "hash-algo", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Get LABEL. */
+ list = gcry_sexp_find_token (ldata, "label", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ ctx->label = gcry_malloc (n);
+ if (!ctx->label)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (ctx->label, s, n);
+ ctx->labellen = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
{
- int j, k;
- unsigned char *pp;
-
- /* Count the zero bytes. */
- for (j=k=0; j < i; j++)
- {
- if (!p[j])
- k++;
- }
- if (!k)
- break; /* Okay: no (more) zero bytes. */
-
- k += k/128 + 3; /* Better get some more. */
- pp = gcry_random_bytes_secure (k, GCRY_STRONG_RANDOM);
- for (j=0; j < i && k; )
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
{
- if (!p[j])
- p[j] = pp[--k];
- if (p[j])
- j++;
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
}
- gcry_free (pp);
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
}
- memcpy (frame+n, p, i);
- n += i;
- gcry_free (p);
-
- frame[n++] = 0;
- memcpy (frame+n, value, valuelen);
- n += valuelen;
- gcry_assert (n == nframe);
-
- /* FIXME, error checking? */
- gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
- }
- gcry_free(frame);
+ rc = oaep_encode (ret_mpi, ctx->nbits, ctx->hash_algo,
+ value, valuelen,
+ ctx->label, ctx->labellen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
+ }
}
- else if (is_pkcs1 && lhash && !for_encryption)
- {
- /* Create pkcs#1 block type 1 padding. */
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_SIGN)
+ {
if (gcry_sexp_length (lhash) != 3)
rc = GPG_ERR_INV_OBJ;
else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
rc = GPG_ERR_INV_OBJ;
else
{
- static struct { const char *name; int algo; } hashnames[] =
- { { "sha1", GCRY_MD_SHA1 },
- { "md5", GCRY_MD_MD5 },
- { "sha256", GCRY_MD_SHA256 },
- { "ripemd160", GCRY_MD_RMD160 },
- { "rmd160", GCRY_MD_RMD160 },
- { "sha384", GCRY_MD_SHA384 },
- { "sha512", GCRY_MD_SHA512 },
- { "sha224", GCRY_MD_SHA224 },
- { "md2", GCRY_MD_MD2 },
- { "md4", GCRY_MD_MD4 },
- { "tiger", GCRY_MD_TIGER },
- { "haval", GCRY_MD_HAVAL },
- { NULL, 0 }
- };
- int algo;
- byte asn[100];
- byte *frame = NULL;
- size_t nframe = (nbits+7) / 8;
const void * value;
size_t valuelen;
- size_t asnlen, dlen;
-
- for (i=0; hashnames[i].name; i++)
- {
- if ( strlen (hashnames[i].name) == n
- && !memcmp (hashnames[i].name, s, n))
- break;
- }
- if (hashnames[i].name)
- algo = hashnames[i].algo;
- else
- {
- /* In case of not listed or dynamically allocated hash
- algorithm we fall back to this somewhat slower
- method. Further, it also allows to use OIDs as
- algorithm names. */
- char *tmpname;
-
- tmpname = gcry_malloc (n+1);
- if (!tmpname)
- algo = 0; /* Out of core - silently give up. */
- else
- {
- memcpy (tmpname, s, n);
- tmpname[n] = 0;
- algo = gcry_md_map_name (tmpname);
- gcry_free (tmpname);
- }
- }
+ void *random_override = NULL;
+ size_t random_override_len = 0;
- asnlen = DIM(asn);
- dlen = gcry_md_get_algo_dlen (algo);
+ ctx->hash_algo = get_hash_algo (s, n);
- if (!algo)
+ if (!ctx->hash_algo)
rc = GPG_ERR_DIGEST_ALGO;
else if ( !(value=gcry_sexp_nth_data (lhash, 2, &valuelen))
|| !valuelen )
rc = GPG_ERR_INV_OBJ;
- else if (gcry_md_algo_info (algo, GCRYCTL_GET_ASNOID, asn, &asnlen))
- {
- /* We don't have yet all of the above algorithms. */
- rc = GPG_ERR_NOT_IMPLEMENTED;
- }
- else if ( valuelen != dlen )
- {
- /* Hash value does not match the length of digest for
- the given algorithm. */
- rc = GPG_ERR_CONFLICT;
- }
- else if( !dlen || dlen + asnlen + 4 > nframe)
- {
- /* Can't encode an DLEN byte digest MD into a NFRAME
- byte frame. */
- rc = GPG_ERR_TOO_SHORT;
- }
- else if ( !(frame = gcry_malloc (nframe)) )
- rc = gpg_err_code_from_errno (errno);
else
- { /* Assemble the pkcs#1 block type 1. */
- n = 0;
- frame[n++] = 0;
- frame[n++] = 1; /* block type */
- i = nframe - valuelen - asnlen - 3 ;
- gcry_assert (i > 1);
- memset (frame+n, 0xff, i );
- n += i;
- frame[n++] = 0;
- memcpy (frame+n, asn, asnlen);
- n += asnlen;
- memcpy (frame+n, value, valuelen );
- n += valuelen;
- gcry_assert (n == nframe);
-
- /* Convert it into an MPI. FIXME: error checking? */
- gcry_mpi_scan (ret_mpi, GCRYMPI_FMT_USG, frame, n, &nframe);
- }
-
- gcry_free (frame);
+ {
+ gcry_sexp_t list;
+
+ /* Get SALT-LENGTH. */
+ list = gcry_sexp_find_token (ldata, "salt-length", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ {
+ rc = GPG_ERR_NO_OBJ;
+ goto leave;
+ }
+ ctx->saltlen = (unsigned int)strtoul (s, NULL, 10);
+ gcry_sexp_release (list);
+ }
+
+ /* Get optional RANDOM-OVERRIDE. */
+ list = gcry_sexp_find_token (ldata, "random-override", 0);
+ if (list)
+ {
+ s = gcry_sexp_nth_data (list, 1, &n);
+ if (!s)
+ rc = GPG_ERR_NO_OBJ;
+ else if (n > 0)
+ {
+ random_override = gcry_malloc (n);
+ if (!random_override)
+ rc = gpg_err_code_from_syserror ();
+ else
+ {
+ memcpy (random_override, s, n);
+ random_override_len = n;
+ }
+ }
+ gcry_sexp_release (list);
+ if (rc)
+ goto leave;
+ }
+
+ /* Encode the data. (NBITS-1 is due to 8.1.1, step 1.) */
+ rc = pss_encode (ret_mpi, ctx->nbits - 1, ctx->hash_algo,
+ value, valuelen, ctx->saltlen,
+ random_override, random_override_len);
+
+ gcry_free (random_override);
+ }
}
}
+ else if (ctx->encoding == PUBKEY_ENC_PSS && lhash
+ && ctx->op == PUBKEY_OP_VERIFY)
+ {
+ if (gcry_sexp_length (lhash) != 3)
+ rc = GPG_ERR_INV_OBJ;
+ else if ( !(s=gcry_sexp_nth_data (lhash, 1, &n)) || !n )
+ rc = GPG_ERR_INV_OBJ;
+ else
+ {
+ ctx->hash_algo = get_hash_algo (s, n);
+
+ if (!ctx->hash_algo)
+ rc = GPG_ERR_DIGEST_ALGO;
+ else
+ {
+ *ret_mpi = gcry_sexp_nth_mpi (lhash, 2, GCRYMPI_FMT_USG);
+ if (!*ret_mpi)
+ rc = GPG_ERR_INV_OBJ;
+ ctx->verify_cmp = pss_verify_cmp;
+ ctx->verify_arg = *ret_mpi;
+ }
+ }
+ }
else
rc = GPG_ERR_CONFLICT;
-
+
+ leave:
gcry_sexp_release (ldata);
gcry_sexp_release (lhash);
gcry_sexp_release (lvalue);
if (!rc)
- *flags = parsed_flags;
+ ctx->flags = parsed_flags;
+ else
+ {
+ gcry_free (ctx->label);
+ ctx->label = NULL;
+ }
return rc;
}
+static void
+init_encoding_ctx (struct pk_encoding_ctx *ctx, enum pk_operation op,
+ unsigned int nbits)
+{
+ ctx->op = op;
+ ctx->nbits = nbits;
+ ctx->encoding = PUBKEY_ENC_UNKNOWN;
+ ctx->flags = 0;
+ ctx->hash_algo = GCRY_MD_SHA1;
+ ctx->label = NULL;
+ ctx->labellen = 0;
+ ctx->saltlen = 20;
+ ctx->verify_cmp = NULL;
+ ctx->verify_arg = NULL;
+}
+
/*
Do a PK encrypt operation
-
+
Caller has to provide a public key as the SEXP pkey and data as a
SEXP with just one MPI in it. Alternatively S_DATA might be a
complex S-Expression, similar to the one used for signature
verification. This provides a flag which allows to handle PKCS#1
- block type 2 padding. The function returns a a sexp which may be
+ block type 2 padding. The function returns a sexp which may be
passed to to pk_decrypt.
-
+
Returns: 0 or an errorcode.
-
+
s_data = See comment for sexp_data_to_mpi
s_pkey = <key-as-defined-in-sexp_to_key>
r_ciph = (enc-val
{
gcry_mpi_t *pkey = NULL, data = NULL, *ciph = NULL;
const char *algo_name, *algo_elems;
- int flags;
+ struct pk_encoding_ctx ctx;
gcry_err_code_t rc;
gcry_pk_spec_t *pubkey = NULL;
gcry_module_t module = NULL;
REGISTER_DEFAULT_PUBKEYS;
/* Get the key. */
- rc = sexp_to_key (s_pkey, 0, &pkey, &module);
+ rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module);
if (rc)
goto leave;
algo_name = pubkey->aliases? *pubkey->aliases : NULL;
if (!algo_name || !*algo_name)
algo_name = pubkey->name;
-
+
algo_elems = pubkey->elements_enc;
-
+
/* Get the stuff we want to encrypt. */
- rc = sexp_data_to_mpi (s_data, gcry_pk_get_nbits (s_pkey), &data, 1,
- &flags);
+ init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey));
+ rc = sexp_data_to_mpi (s_data, &data, &ctx);
if (rc)
goto leave;
ciph = gcry_calloc (strlen (algo_elems) + 1, sizeof (*ciph));
if (!ciph)
{
- rc = gpg_err_code_from_errno (errno);
+ rc = gpg_err_code_from_syserror ();
goto leave;
}
- rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, flags);
+ rc = pubkey_encrypt (module->mod_id, ciph, data, pkey, ctx.flags);
mpi_free (data);
data = NULL;
if (rc)
goto leave;
/* We did it. Now build the return list */
- {
- char *string, *p;
- int i;
- size_t nelem = strlen (algo_elems);
- size_t needed = 19 + strlen (algo_name) + (nelem * 5);
- void **arg_list;
-
- /* Build the string. */
- string = p = gcry_malloc (needed);
- if (!string)
- {
- rc = gpg_err_code_from_errno (errno);
+ if (ctx.encoding == PUBKEY_ENC_OAEP
+ || ctx.encoding == PUBKEY_ENC_PKCS1)
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. We know that this
+ encoding does only make sense with RSA thus we don't need to
+ build the S-expression on the fly. */
+ unsigned char *em;
+ size_t emlen = (ctx.nbits+7)/8;
+
+ rc = octet_string_from_mpi (&em, NULL, ciph[0], emlen);
+ if (rc)
goto leave;
- }
- p = stpcpy ( p, "(enc-val(" );
- p = stpcpy ( p, algo_name );
- for (i=0; algo_elems[i]; i++ )
- {
- *p++ = '(';
- *p++ = algo_elems[i];
- p = stpcpy ( p, "%m)" );
- }
- strcpy ( p, "))" );
-
- /* And now the ugly part: We don't have a function to pass an
- * array to a format string, so we have to do it this way :-(. */
- /* FIXME: There is now such a format specifier, so we can
- change the code to be more clear. */
- arg_list = malloc (nelem * sizeof *arg_list);
- if (!arg_list)
- {
- rc = gpg_err_code_from_errno (errno);
+ rc = gcry_err_code (gcry_sexp_build (r_ciph, NULL,
+ "(enc-val(%s(a%b)))",
+ algo_name, (int)emlen, em));
+ gcry_free (em);
+ if (rc)
goto leave;
- }
+ }
+ else
+ {
+ char *string, *p;
+ int i;
+ size_t nelem = strlen (algo_elems);
+ size_t needed = 19 + strlen (algo_name) + (nelem * 5);
+ void **arg_list;
- for (i = 0; i < nelem; i++)
- arg_list[i] = ciph + i;
-
- rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
- free (arg_list);
- if (rc)
- BUG ();
- gcry_free (string);
- }
+ /* Build the string. */
+ string = p = gcry_malloc (needed);
+ if (!string)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ p = stpcpy ( p, "(enc-val(" );
+ p = stpcpy ( p, algo_name );
+ for (i=0; algo_elems[i]; i++ )
+ {
+ *p++ = '(';
+ *p++ = algo_elems[i];
+ p = stpcpy ( p, "%m)" );
+ }
+ strcpy ( p, "))" );
+
+ /* And now the ugly part: We don't have a function to pass an
+ * array to a format string, so we have to do it this way :-(. */
+ /* FIXME: There is now such a format specifier, so we can
+ change the code to be more clear. */
+ arg_list = malloc (nelem * sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+
+ for (i = 0; i < nelem; i++)
+ arg_list[i] = ciph + i;
+
+ rc = gcry_sexp_build_array (r_ciph, NULL, string, arg_list);
+ free (arg_list);
+ if (rc)
+ BUG ();
+ gcry_free (string);
+ }
leave:
if (pkey)
ath_mutex_unlock (&pubkeys_registered_lock);
}
+ gcry_free (ctx.label);
+
return gcry_error (rc);
}
-/*
+/*
Do a PK decrypt operation
-
+
Caller has to provide a secret key as the SEXP skey and data in a
format as created by gcry_pk_encrypt. For historic reasons the
function returns simply an MPI as an S-expression part; this is
deprecated and the new method should be used which returns a real
S-expressionl this is selected by adding at least an empty flags
list to S_DATA.
-
+
Returns: 0 or an errorcode.
-
+
s_data = (enc-val
- [(flags)]
+ [(flags [raw, pkcs1, oaep])]
(<algo>
(<param_name1> <mpi>)
...
s_skey = <key-as-defined-in-sexp_to_key>
r_plain= Either an incomplete S-expression without the parentheses
or if the flags list is used (even if empty) a real S-expression:
- (value PLAIN).
+ (value PLAIN). In raw mode (or no flags given) the returned value
+ is to be interpreted as a signed MPI, thus it may have an extra
+ leading zero octet even if not included in the original data.
+ With pkcs1 or oaep decoding enabled the returned value is a
+ verbatim octet string.
*/
gcry_error_t
gcry_pk_decrypt (gcry_sexp_t *r_plain, gcry_sexp_t s_data, gcry_sexp_t s_skey)
{
gcry_mpi_t *skey = NULL, *data = NULL, plain = NULL;
- int modern, want_pkcs1, flags;
+ unsigned char *unpad = NULL;
+ size_t unpadlen = 0;
+ int modern, flags;
+ struct pk_encoding_ctx ctx;
gcry_err_code_t rc;
gcry_module_t module_enc = NULL, module_key = NULL;
- gcry_pk_spec_t *pubkey = NULL;
*r_plain = NULL;
+ ctx.label = NULL;
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (s_skey, 1, &skey, &module_key);
+ rc = sexp_to_key (s_skey, 1, NULL, &skey, &module_key);
if (rc)
goto leave;
- rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &want_pkcs1, &flags);
+ init_encoding_ctx (&ctx, PUBKEY_OP_DECRYPT, gcry_pk_get_nbits (s_skey));
+ rc = sexp_to_enc (s_data, &data, &module_enc, &modern, &flags, &ctx);
if (rc)
goto leave;
-
+
if (module_key->mod_id != module_enc->mod_id)
{
rc = GPG_ERR_CONFLICT; /* Key algo does not match data algo. */
goto leave;
}
- pubkey = (gcry_pk_spec_t *) module_key->spec;
-
rc = pubkey_decrypt (module_key->mod_id, &plain, data, skey, flags);
if (rc)
goto leave;
- if (gcry_sexp_build (r_plain, NULL, modern? "(value %m)" : "%m", plain))
- BUG ();
-
+ /* Do un-padding if necessary. */
+ switch (ctx.encoding)
+ {
+ case PUBKEY_ENC_PKCS1:
+ rc = pkcs1_decode_for_encryption (&unpad, &unpadlen,
+ gcry_pk_get_nbits (s_skey), plain);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ case PUBKEY_ENC_OAEP:
+ rc = oaep_decode (&unpad, &unpadlen,
+ gcry_pk_get_nbits (s_skey), ctx.hash_algo,
+ plain, ctx.label, ctx.labellen);
+ mpi_free (plain);
+ plain = NULL;
+ if (!rc)
+ rc = gcry_err_code (gcry_sexp_build (r_plain, NULL, "(value %b)",
+ (int)unpadlen, unpad));
+ break;
+
+ default:
+ /* Raw format. For backward compatibility we need to assume a
+ signed mpi by using the sexp format string "%m". */
+ rc = gcry_err_code (gcry_sexp_build
+ (r_plain, NULL, modern? "(value %m)" : "%m", plain));
+ break;
+ }
+
leave:
+ gcry_free (unpad);
+
if (skey)
{
release_mpi_array (skey);
gcry_free (skey);
}
- if (plain)
- mpi_free (plain);
+ mpi_free (plain);
if (data)
{
ath_mutex_unlock (&pubkeys_registered_lock);
}
+ gcry_free (ctx.label);
+
return gcry_error (rc);
}
/*
Create a signature.
-
+
Caller has to provide a secret key as the SEXP skey and data
expressed as a SEXP list hash with only one element which should
instantly be available as a MPI. Alternatively the structure given
below may be used for S_HASH, it provides the abiliy to pass flags
- to the operation; the only flag defined by now is "pkcs1" which
- does PKCS#1 block type 1 style padding.
-
+ to the operation; the flags defined by now are "pkcs1" which does
+ PKCS#1 block type 1 style padding and "pss" for PSS encoding.
+
Returns: 0 or an errorcode.
In case of 0 the function returns a new SEXP with the
signature value; the structure of this signature depends on the
other arguments but is always suitable to be passed to
gcry_pk_verify
-
+
s_hash = See comment for sexp_data_to_mpi
-
+
s_skey = <key-as-defined-in-sexp_to_key>
r_sig = (sig-val
(<algo>
(<param_name1> <mpi>)
...
(<param_namen> <mpi>))
- [(hash algo)])
+ [(hash algo)])
Note that (hash algo) in R_SIG is not used.
*/
gcry_pk_spec_t *pubkey = NULL;
gcry_module_t module = NULL;
const char *algo_name, *algo_elems;
+ struct pk_encoding_ctx ctx;
int i;
gcry_err_code_t rc;
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (s_skey, 1, &skey, &module);
+ rc = sexp_to_key (s_skey, 1, NULL, &skey, &module);
if (rc)
goto leave;
algo_name = pubkey->aliases? *pubkey->aliases : NULL;
if (!algo_name || !*algo_name)
algo_name = pubkey->name;
-
+
algo_elems = pubkey->elements_sig;
/* Get the stuff we want to sign. Note that pk_get_nbits does also
work on a private key. */
- rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_skey),
- &hash, 0, NULL);
+ init_encoding_ctx (&ctx, PUBKEY_OP_SIGN, gcry_pk_get_nbits (s_skey));
+ rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
if (rc)
goto leave;
result = gcry_calloc (strlen (algo_elems) + 1, sizeof (*result));
if (!result)
{
- rc = gpg_err_code_from_errno (errno);
+ rc = gpg_err_code_from_syserror ();
goto leave;
}
rc = pubkey_sign (module->mod_id, result, hash, skey);
if (rc)
goto leave;
- {
- char *string, *p;
- size_t nelem, needed = strlen (algo_name) + 20;
- void **arg_list;
+ if (ctx.encoding == PUBKEY_ENC_PSS
+ || ctx.encoding == PUBKEY_ENC_PKCS1)
+ {
+ /* We need to make sure to return the correct length to avoid
+ problems with missing leading zeroes. We know that this
+ encoding does only make sense with RSA thus we don't need to
+ build the S-expression on the fly. */
+ unsigned char *em;
+ size_t emlen = (ctx.nbits+7)/8;
+
+ rc = octet_string_from_mpi (&em, NULL, result[0], emlen);
+ if (rc)
+ goto leave;
+ rc = gcry_err_code (gcry_sexp_build (r_sig, NULL,
+ "(sig-val(%s(s%b)))",
+ algo_name, (int)emlen, em));
+ gcry_free (em);
+ if (rc)
+ goto leave;
+ }
+ else
+ {
+ /* General purpose output encoding. Do it on the fly. */
+ char *string, *p;
+ size_t nelem, needed = strlen (algo_name) + 20;
+ void **arg_list;
- nelem = strlen (algo_elems);
-
- /* Count elements, so that we can allocate enough space. */
- needed += 10 * nelem;
+ nelem = strlen (algo_elems);
- /* Build the string. */
- string = p = gcry_malloc (needed);
- if (!string)
- {
- rc = gpg_err_code_from_errno (errno);
- goto leave;
- }
- p = stpcpy (p, "(sig-val(");
- p = stpcpy (p, algo_name);
- for (i = 0; algo_elems[i]; i++)
- {
- *p++ = '(';
- *p++ = algo_elems[i];
- p = stpcpy (p, "%m)");
- }
- strcpy (p, "))");
+ /* Count elements, so that we can allocate enough space. */
+ needed += 10 * nelem;
- arg_list = malloc (nelem * sizeof *arg_list);
- if (!arg_list)
- {
- rc = gpg_err_code_from_errno (errno);
- goto leave;
- }
+ /* Build the string. */
+ string = p = gcry_malloc (needed);
+ if (!string)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
+ p = stpcpy (p, "(sig-val(");
+ p = stpcpy (p, algo_name);
+ for (i = 0; algo_elems[i]; i++)
+ {
+ *p++ = '(';
+ *p++ = algo_elems[i];
+ p = stpcpy (p, "%M)");
+ }
+ strcpy (p, "))");
+
+ arg_list = malloc (nelem * sizeof *arg_list);
+ if (!arg_list)
+ {
+ rc = gpg_err_code_from_syserror ();
+ goto leave;
+ }
- for (i = 0; i < nelem; i++)
- arg_list[i] = result + i;
+ for (i = 0; i < nelem; i++)
+ arg_list[i] = result + i;
- rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
- free (arg_list);
- if (rc)
- BUG ();
- gcry_free (string);
- }
+ rc = gcry_sexp_build_array (r_sig, NULL, string, arg_list);
+ free (arg_list);
+ if (rc)
+ BUG ();
+ gcry_free (string);
+ }
leave:
if (skey)
{
gcry_module_t module_key = NULL, module_sig = NULL;
gcry_mpi_t *pkey = NULL, hash = NULL, *sig = NULL;
+ struct pk_encoding_ctx ctx;
gcry_err_code_t rc;
REGISTER_DEFAULT_PUBKEYS;
-
- rc = sexp_to_key (s_pkey, 0, &pkey, &module_key);
+
+ rc = sexp_to_key (s_pkey, 0, NULL, &pkey, &module_key);
if (rc)
goto leave;
goto leave;
}
- rc = sexp_data_to_mpi (s_hash, gcry_pk_get_nbits (s_pkey), &hash, 0, 0);
+ /* Get the stuff we want to verify. */
+ init_encoding_ctx (&ctx, PUBKEY_OP_VERIFY, gcry_pk_get_nbits (s_pkey));
+ rc = sexp_data_to_mpi (s_hash, &hash, &ctx);
if (rc)
goto leave;
- rc = pubkey_verify (module_key->mod_id, hash, sig, pkey, NULL, NULL);
+ rc = pubkey_verify (module_key->mod_id, hash, sig, pkey,
+ ctx.verify_cmp, &ctx);
leave:
if (pkey)
This may be used either for a public or a secret key to see whether
the internal structure is okay.
-
+
Returns: 0 or an errorcode.
-
+
s_key = <key-as-defined-in-sexp_to_key> */
gcry_error_t
gcry_pk_testkey (gcry_sexp_t s_key)
gcry_module_t module = NULL;
gcry_mpi_t *key = NULL;
gcry_err_code_t rc;
-
+
REGISTER_DEFAULT_PUBKEYS;
/* Note we currently support only secret key checking. */
- rc = sexp_to_key (s_key, 1, &key, &module);
+ rc = sexp_to_key (s_key, 1, NULL, &key, &module);
if (! rc)
{
rc = pubkey_check_secret_key (module->mod_id, key);
char *name = NULL;
size_t n;
gcry_err_code_t rc = GPG_ERR_NO_ERROR;
- int i;
+ int i, j;
const char *algo_name = NULL;
int algo;
const char *sec_elems = NULL, *pub_elems = NULL;
rc = GPG_ERR_INV_OBJ; /* Algo string missing. */
goto leave;
}
-
+
ath_mutex_lock (&pubkeys_registered_lock);
module = gcry_pk_lookup_name (name);
ath_mutex_unlock (&pubkeys_registered_lock);
rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */
goto leave;
}
-
+
pubkey = (gcry_pk_spec_t *) module->spec;
algo = module->mod_id;
algo_name = pubkey->aliases? *pubkey->aliases : NULL;
nbits = (unsigned int)strtoul (buf, NULL, 0);
gcry_sexp_release (l2); l2 = NULL;
}
- else
+ else
nbits = 0;
/* Pass control to the algorithm module. */
- rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
+ rc = pubkey_generate (module->mod_id, nbits, use_e, list, skey,
&factors, &extrainfo);
gcry_sexp_release (list); list = NULL;
if (rc)
char *string, *p;
size_t nelem=0, nelem_cp = 0, needed=0;
gcry_mpi_t mpis[30];
-
+ int percent_s_idx = -1;
+
/* Estimate size of format string. */
nelem = strlen (pub_elems) + strlen (sec_elems);
if (factors)
string = p = gcry_malloc (needed);
if (!string)
{
- rc = gpg_err_code_from_errno (errno);
+ rc = gpg_err_code_from_syserror ();
goto leave;
}
p = stpcpy (p, "(key-data");
p = stpcpy (p, "%m)");
mpis[nelem++] = skey[i];
}
+ if (extrainfo && (algo == GCRY_PK_ECDSA || algo == GCRY_PK_ECDH))
+ {
+ /* Very ugly hack to insert the used curve parameter into the
+ list of public key parameters. */
+ percent_s_idx = nelem;
+ p = stpcpy (p, "%S");
+ }
p = stpcpy (p, "))");
p = stpcpy (p, "(private-key(");
p = stpcpy (p, algo_name);
/* Hack to make release_mpi_array() work. */
skey[i] = NULL;
- if (extrainfo)
+ if (extrainfo && percent_s_idx == -1)
{
/* If we have extrainfo we should not have any factors. */
p = stpcpy (p, "%S");
arg_list = gcry_calloc (nelem_cp+1, sizeof *arg_list);
if (!arg_list)
{
- rc = gpg_err_code_from_errno (errno);
+ rc = gpg_err_code_from_syserror ();
goto leave;
}
- for (i = 0; i < elem_n; i++)
- arg_list[i] = mpis + i;
- if (extrainfo)
- arg_list[i] = &extrainfo;
+ for (i = j = 0; i < elem_n; i++)
+ {
+ if (i == percent_s_idx)
+ arg_list[j++] = &extrainfo;
+ arg_list[j++] = mpis + i;
+ }
+ if (extrainfo && percent_s_idx == -1)
+ arg_list[j] = &extrainfo;
else if (factors && factors[0])
{
for (; i < nelem_cp; i++)
- arg_list[i] = factors + i - elem_n;
+ arg_list[j++] = factors + i - elem_n;
}
-
rc = gcry_sexp_build_array (r_key, NULL, string, arg_list);
gcry_free (arg_list);
if (rc)
release_mpi_array ( factors );
gcry_free (factors);
}
-
+
gcry_sexp_release (l3);
gcry_sexp_release (l2);
gcry_sexp_release (list);
}
-/*
+/*
Get the number of nbits from the public key.
Hmmm: Should we have really this function or is it better to have a
REGISTER_DEFAULT_PUBKEYS;
- rc = sexp_to_key (key, 0, &keyarr, &module);
+ rc = sexp_to_key (key, 0, NULL, &keyarr, &module);
if (rc == GPG_ERR_INV_OBJ)
- rc = sexp_to_key (key, 1, &keyarr, &module);
+ rc = sexp_to_key (key, 1, NULL, &keyarr, &module);
if (rc)
return 0; /* Error - 0 is a suitable indication for that. */
pubkey = (gcry_pk_spec_t *) module->spec;
nbits = (*pubkey->get_nbits) (module->mod_id, keyarr);
-
+
ath_mutex_lock (&pubkeys_registered_lock);
_gcry_module_release (module);
ath_mutex_unlock (&pubkeys_registered_lock);
int idx;
const char *elems;
gcry_md_hd_t md = NULL;
+ int okay = 0;
REGISTER_DEFAULT_PUBKEYS;
elems = pubkey->elements_grip;
if (!elems)
goto fail; /* No grip parameter. */
-
+
if (gcry_md_open (&md, GCRY_MD_SHA1, 0))
goto fail;
const char *data;
size_t datalen;
char buf[30];
-
+
l2 = gcry_sexp_find_token (list, s, 1);
if (! l2)
goto fail;
data = gcry_sexp_nth_data (l2, 1, &datalen);
if (! data)
goto fail;
-
+
snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen);
gcry_md_write (md, buf, strlen (buf));
gcry_md_write (md, data, datalen);
gcry_sexp_release (l2);
+ l2 = NULL;
gcry_md_write (md, ")", 1);
}
}
-
+
if (!array)
{
array = gcry_malloc (20);
}
memcpy (array, gcry_md_read (md, GCRY_MD_SHA1), 20);
- gcry_md_close (md);
- gcry_sexp_release (list);
- return array;
+ okay = 1;
fail:
gcry_free (name);
gcry_sexp_release (l2);
gcry_md_close (md);
gcry_sexp_release (list);
- return NULL;
+ return okay? array : NULL;
+}
+
+
+\f
+const char *
+gcry_pk_get_curve (gcry_sexp_t key, int iterator, unsigned int *r_nbits)
+{
+ gcry_mpi_t *pkey = NULL;
+ gcry_sexp_t list = NULL;
+ gcry_sexp_t l2;
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec;
+ char *name = NULL;
+ const char *result = NULL;
+ int want_private = 1;
+
+ if (r_nbits)
+ *r_nbits = 0;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ if (key)
+ {
+ iterator = 0;
+
+ /* Check that the first element is valid. */
+ list = gcry_sexp_find_token (key, "public-key", 0);
+ if (list)
+ want_private = 0;
+ if (!list)
+ list = gcry_sexp_find_token (key, "private-key", 0);
+ if (!list)
+ return NULL; /* No public- or private-key object. */
+
+ l2 = gcry_sexp_cadr (list);
+ gcry_sexp_release (list);
+ list = l2;
+ l2 = NULL;
+
+ name = _gcry_sexp_nth_string (list, 0);
+ if (!name)
+ goto leave; /* Invalid structure of object. */
+
+ /* Get the key. We pass the names of the parameters for
+ override_elems; this allows to call this function without the
+ actual public key parameter. */
+ if (sexp_to_key (key, want_private, "pabgn", &pkey, &module))
+ goto leave;
+ }
+ else
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name ("ecc");
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ if (!module)
+ goto leave;
+ }
+
+ extraspec = module->extraspec;
+ if (!extraspec || !extraspec->get_curve)
+ goto leave;
+
+ result = extraspec->get_curve (pkey, iterator, r_nbits);
+
+ leave:
+ if (pkey)
+ {
+ release_mpi_array (pkey);
+ gcry_free (pkey);
+ }
+ if (module)
+ {
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ gcry_free (name);
+ gcry_sexp_release (list);
+ return result;
+}
+
+
+\f
+gcry_sexp_t
+gcry_pk_get_param (int algo, const char *name)
+{
+ gcry_module_t module = NULL;
+ pk_extra_spec_t *extraspec;
+ gcry_sexp_t result = NULL;
+
+ if (algo != GCRY_PK_ECDSA && algo != GCRY_PK_ECDH)
+ return NULL;
+
+ REGISTER_DEFAULT_PUBKEYS;
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ module = gcry_pk_lookup_name ("ecc");
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ if (module)
+ {
+ extraspec = module->extraspec;
+ if (extraspec && extraspec->get_curve_param)
+ result = extraspec->get_curve_param (name);
+
+ ath_mutex_lock (&pubkeys_registered_lock);
+ _gcry_module_release (module);
+ ath_mutex_unlock (&pubkeys_registered_lock);
+ }
+ return result;
}
+\f
gcry_error_t
gcry_pk_ctl (int cmd, void *buffer, size_t buflen)
{
returns 0. Disabled algos are ignored here because we
only want to know whether the algo is at all capable of
the usage.
-
+
Note: Because this function is in most cases used to return an
integer value, we can make it easier for the caller to just look at
the return value. The caller will in all cases consult the value
{
ec = GPG_ERR_PUBKEY_ALGO;
if (report)
- report ("pubkey", algo, "module",
+ report ("pubkey", algo, "module",
module && !(module->flags & FLAG_MODULE_DISABLED)?
"no selftest available" :
module? "algorithm disabled" : "algorithm not found");
enc_cp = strdup (spec->elements_enc);
if (! enc_cp)
{
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
goto out;
}
}
-
+
if (sig)
{
sig_cp = strdup (spec->elements_sig);
if (! sig_cp)
{
- err = gpg_err_code_from_errno (errno);
+ err = gpg_err_code_from_syserror ();
goto out;
}
}
#define RFC2268_BLOCKSIZE 8
-typedef struct
+typedef struct
{
u16 S[64];
} RFC2268_context;
-static const unsigned char rfc2268_sbox[] = {
- 217, 120, 249, 196, 25, 221, 181, 237,
+static const unsigned char rfc2268_sbox[] = {
+ 217, 120, 249, 196, 25, 221, 181, 237,
40, 233, 253, 121, 74, 160, 216, 157,
- 198, 126, 55, 131, 43, 118, 83, 142,
+ 198, 126, 55, 131, 43, 118, 83, 142,
98, 76, 100, 136, 68, 139, 251, 162,
23, 154, 89, 245, 135, 179, 79, 19,
97, 69, 109, 141, 9, 129, 125, 50,
/* For some reason I cannot combine those steps. */
word0 += (word1 & ~word3) + (word2 & word3) + ctx->S[j];
word0 = rotl16(word0, 1);
-
+
word1 += (word2 & ~word0) + (word3 & word0) + ctx->S[j + 1];
word1 = rotl16(word1, 2);
-
+
word2 += (word3 & ~word1) + (word0 & word1) + ctx->S[j + 2];
word2 = rotl16(word2, 3);
word3 = (word3 << 8) | inbuf[7];
word3 = (word3 << 8) | inbuf[6];
- for (i = 15; i >= 0; i--)
+ for (i = 15; i >= 0; i--)
{
j = i * 4;
word0 = rotr16(word0, 1);
word0 -= (word1 & ~word3) + (word2 & word3) + ctx->S[j];
- if (i == 5 || i == 11)
+ if (i == 5 || i == 11)
{
word3 = word3 - ctx->S[word2 & 63];
word2 = word2 - ctx->S[word1 & 63];
return GPG_ERR_INV_KEYLEN;
S = (unsigned char *) ctx->S;
-
+
for (i = 0; i < keylen; i++)
S[i] = key[i];
i = 128 - len;
x = rfc2268_sbox[S[i] & (255 >> (7 & -bits))];
S[i] = x;
-
- while (i--)
+
+ while (i--)
{
x = rfc2268_sbox[x ^ S[i + len]];
S[i] = x;
}
/* Make the expanded key, endian independent. */
- for (i = 0; i < 64; i++)
+ for (i = 0; i < 64; i++)
ctx->S[i] = ( (u16) S[i * 2] | (((u16) S[i * 2 + 1]) << 8));
return 0;
return "RFC2268 encryption test 1 failed.";
setkey_core (&ctx, key_1, sizeof(key_1), 0);
- do_decrypt (&ctx, scratch, scratch);
+ do_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_1, sizeof(plaintext_1)))
return "RFC2268 decryption test 1 failed.";
return "RFC2268 encryption test 2 failed.";
setkey_core (&ctx, key_2, sizeof(key_2), 0);
- do_decrypt (&ctx, scratch, scratch);
+ do_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_2, sizeof(plaintext_2)))
return "RFC2268 decryption test 2 failed.";
return "RFC2268 encryption test 3 failed.";
setkey_core (&ctx, key_3, sizeof(key_3), 0);
- do_decrypt (&ctx, scratch, scratch);
+ do_decrypt (&ctx, scratch, scratch);
if (memcmp(scratch, plaintext_3, sizeof(plaintext_3)))
return "RFC2268 decryption test 3 failed.";
RFC2268_BLOCKSIZE, 40, sizeof(RFC2268_context),
do_setkey, do_encrypt, do_decrypt
};
-
-/* rijndael-tables.h - Rijndael (AES) for GnuPG,
+/* rijndael-tables.h - Rijndael (AES) for GnuPG,
* Copyright (C) 2000, 2001, 2002, 2003, 2007,
* 2008 Free Software Foundation, Inc.
*
/* To keep the actual implementation at a readable size we use this
include file to define the tables. */
-static const unsigned char S[256] =
+static const unsigned char S[256] =
{
99, 124, 119, 123, 242, 107, 111, 197,
- 48, 1, 103, 43, 254, 215, 171, 118,
+ 48, 1, 103, 43, 254, 215, 171, 118,
202, 130, 201, 125, 250, 89, 71, 240,
- 173, 212, 162, 175, 156, 164, 114, 192,
+ 173, 212, 162, 175, 156, 164, 114, 192,
183, 253, 147, 38, 54, 63, 247, 204,
- 52, 165, 229, 241, 113, 216, 49, 21,
+ 52, 165, 229, 241, 113, 216, 49, 21,
4, 199, 35, 195, 24, 150, 5, 154,
- 7, 18, 128, 226, 235, 39, 178, 117,
- 9, 131, 44, 26, 27, 110, 90, 160,
- 82, 59, 214, 179, 41, 227, 47, 132,
+ 7, 18, 128, 226, 235, 39, 178, 117,
+ 9, 131, 44, 26, 27, 110, 90, 160,
+ 82, 59, 214, 179, 41, 227, 47, 132,
83, 209, 0, 237, 32, 252, 177, 91,
- 106, 203, 190, 57, 74, 76, 88, 207,
+ 106, 203, 190, 57, 74, 76, 88, 207,
208, 239, 170, 251, 67, 77, 51, 133,
- 69, 249, 2, 127, 80, 60, 159, 168,
+ 69, 249, 2, 127, 80, 60, 159, 168,
81, 163, 64, 143, 146, 157, 56, 245,
- 188, 182, 218, 33, 16, 255, 243, 210,
+ 188, 182, 218, 33, 16, 255, 243, 210,
205, 12, 19, 236, 95, 151, 68, 23,
- 196, 167, 126, 61, 100, 93, 25, 115,
+ 196, 167, 126, 61, 100, 93, 25, 115,
96, 129, 79, 220, 34, 42, 144, 136,
- 70, 238, 184, 20, 222, 94, 11, 219,
+ 70, 238, 184, 20, 222, 94, 11, 219,
224, 50, 58, 10, 73, 6, 36, 92,
- 194, 211, 172, 98, 145, 149, 228, 121,
- 231, 200, 55, 109, 141, 213, 78, 169,
- 108, 86, 244, 234, 101, 122, 174, 8,
- 186, 120, 37, 46, 28, 166, 180, 198,
- 232, 221, 116, 31, 75, 189, 139, 138,
+ 194, 211, 172, 98, 145, 149, 228, 121,
+ 231, 200, 55, 109, 141, 213, 78, 169,
+ 108, 86, 244, 234, 101, 122, 174, 8,
+ 186, 120, 37, 46, 28, 166, 180, 198,
+ 232, 221, 116, 31, 75, 189, 139, 138,
112, 62, 181, 102, 72, 3, 246, 14,
- 97, 53, 87, 185, 134, 193, 29, 158,
+ 97, 53, 87, 185, 134, 193, 29, 158,
225, 248, 152, 17, 105, 217, 142, 148,
- 155, 30, 135, 233, 206, 85, 40, 223,
- 140, 161, 137, 13, 191, 230, 66, 104,
+ 155, 30, 135, 233, 206, 85, 40, 223,
+ 140, 161, 137, 13, 191, 230, 66, 104,
65, 153, 45, 15, 176, 84, 187, 22
};
-static const unsigned char T1[256][4] =
+static const unsigned char T1[256][4] =
{
{ 0xc6,0x63,0x63,0xa5 }, { 0xf8,0x7c,0x7c,0x84 },
- { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d },
+ { 0xee,0x77,0x77,0x99 }, { 0xf6,0x7b,0x7b,0x8d },
{ 0xff,0xf2,0xf2,0x0d }, { 0xd6,0x6b,0x6b,0xbd },
- { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 },
+ { 0xde,0x6f,0x6f,0xb1 }, { 0x91,0xc5,0xc5,0x54 },
{ 0x60,0x30,0x30,0x50 }, { 0x02,0x01,0x01,0x03 },
- { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d },
+ { 0xce,0x67,0x67,0xa9 }, { 0x56,0x2b,0x2b,0x7d },
{ 0xe7,0xfe,0xfe,0x19 }, { 0xb5,0xd7,0xd7,0x62 },
- { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a },
+ { 0x4d,0xab,0xab,0xe6 }, { 0xec,0x76,0x76,0x9a },
{ 0x8f,0xca,0xca,0x45 }, { 0x1f,0x82,0x82,0x9d },
- { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 },
- { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb },
- { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b },
+ { 0x89,0xc9,0xc9,0x40 }, { 0xfa,0x7d,0x7d,0x87 },
+ { 0xef,0xfa,0xfa,0x15 }, { 0xb2,0x59,0x59,0xeb },
+ { 0x8e,0x47,0x47,0xc9 }, { 0xfb,0xf0,0xf0,0x0b },
{ 0x41,0xad,0xad,0xec }, { 0xb3,0xd4,0xd4,0x67 },
- { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea },
+ { 0x5f,0xa2,0xa2,0xfd }, { 0x45,0xaf,0xaf,0xea },
{ 0x23,0x9c,0x9c,0xbf }, { 0x53,0xa4,0xa4,0xf7 },
- { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b },
+ { 0xe4,0x72,0x72,0x96 }, { 0x9b,0xc0,0xc0,0x5b },
{ 0x75,0xb7,0xb7,0xc2 }, { 0xe1,0xfd,0xfd,0x1c },
- { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a },
+ { 0x3d,0x93,0x93,0xae }, { 0x4c,0x26,0x26,0x6a },
{ 0x6c,0x36,0x36,0x5a }, { 0x7e,0x3f,0x3f,0x41 },
- { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f },
- { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 },
- { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 },
+ { 0xf5,0xf7,0xf7,0x02 }, { 0x83,0xcc,0xcc,0x4f },
+ { 0x68,0x34,0x34,0x5c }, { 0x51,0xa5,0xa5,0xf4 },
+ { 0xd1,0xe5,0xe5,0x34 }, { 0xf9,0xf1,0xf1,0x08 },
{ 0xe2,0x71,0x71,0x93 }, { 0xab,0xd8,0xd8,0x73 },
- { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f },
+ { 0x62,0x31,0x31,0x53 }, { 0x2a,0x15,0x15,0x3f },
{ 0x08,0x04,0x04,0x0c }, { 0x95,0xc7,0xc7,0x52 },
- { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e },
+ { 0x46,0x23,0x23,0x65 }, { 0x9d,0xc3,0xc3,0x5e },
{ 0x30,0x18,0x18,0x28 }, { 0x37,0x96,0x96,0xa1 },
- { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 },
+ { 0x0a,0x05,0x05,0x0f }, { 0x2f,0x9a,0x9a,0xb5 },
{ 0x0e,0x07,0x07,0x09 }, { 0x24,0x12,0x12,0x36 },
- { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d },
+ { 0x1b,0x80,0x80,0x9b }, { 0xdf,0xe2,0xe2,0x3d },
{ 0xcd,0xeb,0xeb,0x26 }, { 0x4e,0x27,0x27,0x69 },
- { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f },
+ { 0x7f,0xb2,0xb2,0xcd }, { 0xea,0x75,0x75,0x9f },
{ 0x12,0x09,0x09,0x1b }, { 0x1d,0x83,0x83,0x9e },
- { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e },
- { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 },
- { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb },
+ { 0x58,0x2c,0x2c,0x74 }, { 0x34,0x1a,0x1a,0x2e },
+ { 0x36,0x1b,0x1b,0x2d }, { 0xdc,0x6e,0x6e,0xb2 },
+ { 0xb4,0x5a,0x5a,0xee }, { 0x5b,0xa0,0xa0,0xfb },
{ 0xa4,0x52,0x52,0xf6 }, { 0x76,0x3b,0x3b,0x4d },
- { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce },
- { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e },
- { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 },
- { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 },
- { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c },
+ { 0xb7,0xd6,0xd6,0x61 }, { 0x7d,0xb3,0xb3,0xce },
+ { 0x52,0x29,0x29,0x7b }, { 0xdd,0xe3,0xe3,0x3e },
+ { 0x5e,0x2f,0x2f,0x71 }, { 0x13,0x84,0x84,0x97 },
+ { 0xa6,0x53,0x53,0xf5 }, { 0xb9,0xd1,0xd1,0x68 },
+ { 0x00,0x00,0x00,0x00 }, { 0xc1,0xed,0xed,0x2c },
{ 0x40,0x20,0x20,0x60 }, { 0xe3,0xfc,0xfc,0x1f },
- { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed },
+ { 0x79,0xb1,0xb1,0xc8 }, { 0xb6,0x5b,0x5b,0xed },
{ 0xd4,0x6a,0x6a,0xbe }, { 0x8d,0xcb,0xcb,0x46 },
- { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b },
+ { 0x67,0xbe,0xbe,0xd9 }, { 0x72,0x39,0x39,0x4b },
{ 0x94,0x4a,0x4a,0xde }, { 0x98,0x4c,0x4c,0xd4 },
- { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a },
+ { 0xb0,0x58,0x58,0xe8 }, { 0x85,0xcf,0xcf,0x4a },
{ 0xbb,0xd0,0xd0,0x6b }, { 0xc5,0xef,0xef,0x2a },
- { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 },
+ { 0x4f,0xaa,0xaa,0xe5 }, { 0xed,0xfb,0xfb,0x16 },
{ 0x86,0x43,0x43,0xc5 }, { 0x9a,0x4d,0x4d,0xd7 },
- { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 },
+ { 0x66,0x33,0x33,0x55 }, { 0x11,0x85,0x85,0x94 },
{ 0x8a,0x45,0x45,0xcf }, { 0xe9,0xf9,0xf9,0x10 },
- { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 },
+ { 0x04,0x02,0x02,0x06 }, { 0xfe,0x7f,0x7f,0x81 },
{ 0xa0,0x50,0x50,0xf0 }, { 0x78,0x3c,0x3c,0x44 },
- { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 },
+ { 0x25,0x9f,0x9f,0xba }, { 0x4b,0xa8,0xa8,0xe3 },
{ 0xa2,0x51,0x51,0xf3 }, { 0x5d,0xa3,0xa3,0xfe },
- { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a },
+ { 0x80,0x40,0x40,0xc0 }, { 0x05,0x8f,0x8f,0x8a },
{ 0x3f,0x92,0x92,0xad }, { 0x21,0x9d,0x9d,0xbc },
- { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 },
+ { 0x70,0x38,0x38,0x48 }, { 0xf1,0xf5,0xf5,0x04 },
{ 0x63,0xbc,0xbc,0xdf }, { 0x77,0xb6,0xb6,0xc1 },
- { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 },
+ { 0xaf,0xda,0xda,0x75 }, { 0x42,0x21,0x21,0x63 },
{ 0x20,0x10,0x10,0x30 }, { 0xe5,0xff,0xff,0x1a },
- { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d },
+ { 0xfd,0xf3,0xf3,0x0e }, { 0xbf,0xd2,0xd2,0x6d },
{ 0x81,0xcd,0xcd,0x4c }, { 0x18,0x0c,0x0c,0x14 },
- { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f },
+ { 0x26,0x13,0x13,0x35 }, { 0xc3,0xec,0xec,0x2f },
{ 0xbe,0x5f,0x5f,0xe1 }, { 0x35,0x97,0x97,0xa2 },
- { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 },
+ { 0x88,0x44,0x44,0xcc }, { 0x2e,0x17,0x17,0x39 },
{ 0x93,0xc4,0xc4,0x57 }, { 0x55,0xa7,0xa7,0xf2 },
- { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 },
+ { 0xfc,0x7e,0x7e,0x82 }, { 0x7a,0x3d,0x3d,0x47 },
{ 0xc8,0x64,0x64,0xac }, { 0xba,0x5d,0x5d,0xe7 },
- { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 },
+ { 0x32,0x19,0x19,0x2b }, { 0xe6,0x73,0x73,0x95 },
{ 0xc0,0x60,0x60,0xa0 }, { 0x19,0x81,0x81,0x98 },
- { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f },
+ { 0x9e,0x4f,0x4f,0xd1 }, { 0xa3,0xdc,0xdc,0x7f },
{ 0x44,0x22,0x22,0x66 }, { 0x54,0x2a,0x2a,0x7e },
- { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 },
+ { 0x3b,0x90,0x90,0xab }, { 0x0b,0x88,0x88,0x83 },
{ 0x8c,0x46,0x46,0xca }, { 0xc7,0xee,0xee,0x29 },
- { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c },
+ { 0x6b,0xb8,0xb8,0xd3 }, { 0x28,0x14,0x14,0x3c },
{ 0xa7,0xde,0xde,0x79 }, { 0xbc,0x5e,0x5e,0xe2 },
- { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 },
+ { 0x16,0x0b,0x0b,0x1d }, { 0xad,0xdb,0xdb,0x76 },
{ 0xdb,0xe0,0xe0,0x3b }, { 0x64,0x32,0x32,0x56 },
- { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e },
+ { 0x74,0x3a,0x3a,0x4e }, { 0x14,0x0a,0x0a,0x1e },
{ 0x92,0x49,0x49,0xdb }, { 0x0c,0x06,0x06,0x0a },
- { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 },
+ { 0x48,0x24,0x24,0x6c }, { 0xb8,0x5c,0x5c,0xe4 },
{ 0x9f,0xc2,0xc2,0x5d }, { 0xbd,0xd3,0xd3,0x6e },
- { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 },
+ { 0x43,0xac,0xac,0xef }, { 0xc4,0x62,0x62,0xa6 },
{ 0x39,0x91,0x91,0xa8 }, { 0x31,0x95,0x95,0xa4 },
- { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b },
+ { 0xd3,0xe4,0xe4,0x37 }, { 0xf2,0x79,0x79,0x8b },
{ 0xd5,0xe7,0xe7,0x32 }, { 0x8b,0xc8,0xc8,0x43 },
- { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 },
+ { 0x6e,0x37,0x37,0x59 }, { 0xda,0x6d,0x6d,0xb7 },
{ 0x01,0x8d,0x8d,0x8c }, { 0xb1,0xd5,0xd5,0x64 },
- { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 },
+ { 0x9c,0x4e,0x4e,0xd2 }, { 0x49,0xa9,0xa9,0xe0 },
{ 0xd8,0x6c,0x6c,0xb4 }, { 0xac,0x56,0x56,0xfa },
- { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 },
+ { 0xf3,0xf4,0xf4,0x07 }, { 0xcf,0xea,0xea,0x25 },
{ 0xca,0x65,0x65,0xaf }, { 0xf4,0x7a,0x7a,0x8e },
- { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 },
+ { 0x47,0xae,0xae,0xe9 }, { 0x10,0x08,0x08,0x18 },
{ 0x6f,0xba,0xba,0xd5 }, { 0xf0,0x78,0x78,0x88 },
- { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 },
+ { 0x4a,0x25,0x25,0x6f }, { 0x5c,0x2e,0x2e,0x72 },
{ 0x38,0x1c,0x1c,0x24 }, { 0x57,0xa6,0xa6,0xf1 },
- { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 },
+ { 0x73,0xb4,0xb4,0xc7 }, { 0x97,0xc6,0xc6,0x51 },
{ 0xcb,0xe8,0xe8,0x23 }, { 0xa1,0xdd,0xdd,0x7c },
- { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 },
- { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc },
- { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 },
+ { 0xe8,0x74,0x74,0x9c }, { 0x3e,0x1f,0x1f,0x21 },
+ { 0x96,0x4b,0x4b,0xdd }, { 0x61,0xbd,0xbd,0xdc },
+ { 0x0d,0x8b,0x8b,0x86 }, { 0x0f,0x8a,0x8a,0x85 },
{ 0xe0,0x70,0x70,0x90 }, { 0x7c,0x3e,0x3e,0x42 },
- { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa },
+ { 0x71,0xb5,0xb5,0xc4 }, { 0xcc,0x66,0x66,0xaa },
{ 0x90,0x48,0x48,0xd8 }, { 0x06,0x03,0x03,0x05 },
- { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 },
+ { 0xf7,0xf6,0xf6,0x01 }, { 0x1c,0x0e,0x0e,0x12 },
{ 0xc2,0x61,0x61,0xa3 }, { 0x6a,0x35,0x35,0x5f },
- { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 },
+ { 0xae,0x57,0x57,0xf9 }, { 0x69,0xb9,0xb9,0xd0 },
{ 0x17,0x86,0x86,0x91 }, { 0x99,0xc1,0xc1,0x58 },
- { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 },
+ { 0x3a,0x1d,0x1d,0x27 }, { 0x27,0x9e,0x9e,0xb9 },
{ 0xd9,0xe1,0xe1,0x38 }, { 0xeb,0xf8,0xf8,0x13 },
- { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 },
+ { 0x2b,0x98,0x98,0xb3 }, { 0x22,0x11,0x11,0x33 },
{ 0xd2,0x69,0x69,0xbb }, { 0xa9,0xd9,0xd9,0x70 },
- { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 },
+ { 0x07,0x8e,0x8e,0x89 }, { 0x33,0x94,0x94,0xa7 },
{ 0x2d,0x9b,0x9b,0xb6 }, { 0x3c,0x1e,0x1e,0x22 },
- { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 },
+ { 0x15,0x87,0x87,0x92 }, { 0xc9,0xe9,0xe9,0x20 },
{ 0x87,0xce,0xce,0x49 }, { 0xaa,0x55,0x55,0xff },
- { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a },
+ { 0x50,0x28,0x28,0x78 }, { 0xa5,0xdf,0xdf,0x7a },
{ 0x03,0x8c,0x8c,0x8f }, { 0x59,0xa1,0xa1,0xf8 },
- { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 },
+ { 0x09,0x89,0x89,0x80 }, { 0x1a,0x0d,0x0d,0x17 },
{ 0x65,0xbf,0xbf,0xda }, { 0xd7,0xe6,0xe6,0x31 },
- { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 },
+ { 0x84,0x42,0x42,0xc6 }, { 0xd0,0x68,0x68,0xb8 },
{ 0x82,0x41,0x41,0xc3 }, { 0x29,0x99,0x99,0xb0 },
- { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 },
+ { 0x5a,0x2d,0x2d,0x77 }, { 0x1e,0x0f,0x0f,0x11 },
{ 0x7b,0xb0,0xb0,0xcb }, { 0xa8,0x54,0x54,0xfc },
{ 0x6d,0xbb,0xbb,0xd6 }, { 0x2c,0x16,0x16,0x3a }
};
-static const unsigned char T2[256][4] =
+static const unsigned char T2[256][4] =
{
{ 0xa5,0xc6,0x63,0x63 }, { 0x84,0xf8,0x7c,0x7c },
- { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b },
+ { 0x99,0xee,0x77,0x77 }, { 0x8d,0xf6,0x7b,0x7b },
{ 0x0d,0xff,0xf2,0xf2 }, { 0xbd,0xd6,0x6b,0x6b },
- { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 },
+ { 0xb1,0xde,0x6f,0x6f }, { 0x54,0x91,0xc5,0xc5 },
{ 0x50,0x60,0x30,0x30 }, { 0x03,0x02,0x01,0x01 },
- { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b },
- { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 },
- { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 },
- { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 },
- { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d },
- { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 },
- { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 },
- { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 },
- { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf },
- { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 },
- { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 },
- { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd },
- { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 },
+ { 0xa9,0xce,0x67,0x67 }, { 0x7d,0x56,0x2b,0x2b },
+ { 0x19,0xe7,0xfe,0xfe }, { 0x62,0xb5,0xd7,0xd7 },
+ { 0xe6,0x4d,0xab,0xab }, { 0x9a,0xec,0x76,0x76 },
+ { 0x45,0x8f,0xca,0xca }, { 0x9d,0x1f,0x82,0x82 },
+ { 0x40,0x89,0xc9,0xc9 }, { 0x87,0xfa,0x7d,0x7d },
+ { 0x15,0xef,0xfa,0xfa }, { 0xeb,0xb2,0x59,0x59 },
+ { 0xc9,0x8e,0x47,0x47 }, { 0x0b,0xfb,0xf0,0xf0 },
+ { 0xec,0x41,0xad,0xad }, { 0x67,0xb3,0xd4,0xd4 },
+ { 0xfd,0x5f,0xa2,0xa2 }, { 0xea,0x45,0xaf,0xaf },
+ { 0xbf,0x23,0x9c,0x9c }, { 0xf7,0x53,0xa4,0xa4 },
+ { 0x96,0xe4,0x72,0x72 }, { 0x5b,0x9b,0xc0,0xc0 },
+ { 0xc2,0x75,0xb7,0xb7 }, { 0x1c,0xe1,0xfd,0xfd },
+ { 0xae,0x3d,0x93,0x93 }, { 0x6a,0x4c,0x26,0x26 },
{ 0x5a,0x6c,0x36,0x36 }, { 0x41,0x7e,0x3f,0x3f },
- { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc },
+ { 0x02,0xf5,0xf7,0xf7 }, { 0x4f,0x83,0xcc,0xcc },
{ 0x5c,0x68,0x34,0x34 }, { 0xf4,0x51,0xa5,0xa5 },
- { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 },
+ { 0x34,0xd1,0xe5,0xe5 }, { 0x08,0xf9,0xf1,0xf1 },
{ 0x93,0xe2,0x71,0x71 }, { 0x73,0xab,0xd8,0xd8 },
- { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 },
- { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 },
- { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 },
- { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 },
- { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a },
+ { 0x53,0x62,0x31,0x31 }, { 0x3f,0x2a,0x15,0x15 },
+ { 0x0c,0x08,0x04,0x04 }, { 0x52,0x95,0xc7,0xc7 },
+ { 0x65,0x46,0x23,0x23 }, { 0x5e,0x9d,0xc3,0xc3 },
+ { 0x28,0x30,0x18,0x18 }, { 0xa1,0x37,0x96,0x96 },
+ { 0x0f,0x0a,0x05,0x05 }, { 0xb5,0x2f,0x9a,0x9a },
{ 0x09,0x0e,0x07,0x07 }, { 0x36,0x24,0x12,0x12 },
- { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 },
- { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 },
- { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 },
+ { 0x9b,0x1b,0x80,0x80 }, { 0x3d,0xdf,0xe2,0xe2 },
+ { 0x26,0xcd,0xeb,0xeb }, { 0x69,0x4e,0x27,0x27 },
+ { 0xcd,0x7f,0xb2,0xb2 }, { 0x9f,0xea,0x75,0x75 },
{ 0x1b,0x12,0x09,0x09 }, { 0x9e,0x1d,0x83,0x83 },
- { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a },
+ { 0x74,0x58,0x2c,0x2c }, { 0x2e,0x34,0x1a,0x1a },
{ 0x2d,0x36,0x1b,0x1b }, { 0xb2,0xdc,0x6e,0x6e },
- { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 },
+ { 0xee,0xb4,0x5a,0x5a }, { 0xfb,0x5b,0xa0,0xa0 },
{ 0xf6,0xa4,0x52,0x52 }, { 0x4d,0x76,0x3b,0x3b },
- { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 },
- { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 },
- { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 },
- { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 },
- { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed },
- { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc },
- { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b },
- { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb },
- { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 },
- { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c },
- { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf },
+ { 0x61,0xb7,0xd6,0xd6 }, { 0xce,0x7d,0xb3,0xb3 },
+ { 0x7b,0x52,0x29,0x29 }, { 0x3e,0xdd,0xe3,0xe3 },
+ { 0x71,0x5e,0x2f,0x2f }, { 0x97,0x13,0x84,0x84 },
+ { 0xf5,0xa6,0x53,0x53 }, { 0x68,0xb9,0xd1,0xd1 },
+ { 0x00,0x00,0x00,0x00 }, { 0x2c,0xc1,0xed,0xed },
+ { 0x60,0x40,0x20,0x20 }, { 0x1f,0xe3,0xfc,0xfc },
+ { 0xc8,0x79,0xb1,0xb1 }, { 0xed,0xb6,0x5b,0x5b },
+ { 0xbe,0xd4,0x6a,0x6a }, { 0x46,0x8d,0xcb,0xcb },
+ { 0xd9,0x67,0xbe,0xbe }, { 0x4b,0x72,0x39,0x39 },
+ { 0xde,0x94,0x4a,0x4a }, { 0xd4,0x98,0x4c,0x4c },
+ { 0xe8,0xb0,0x58,0x58 }, { 0x4a,0x85,0xcf,0xcf },
{ 0x6b,0xbb,0xd0,0xd0 }, { 0x2a,0xc5,0xef,0xef },
- { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb },
- { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d },
- { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 },
- { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 },
- { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f },
+ { 0xe5,0x4f,0xaa,0xaa }, { 0x16,0xed,0xfb,0xfb },
+ { 0xc5,0x86,0x43,0x43 }, { 0xd7,0x9a,0x4d,0x4d },
+ { 0x55,0x66,0x33,0x33 }, { 0x94,0x11,0x85,0x85 },
+ { 0xcf,0x8a,0x45,0x45 }, { 0x10,0xe9,0xf9,0xf9 },
+ { 0x06,0x04,0x02,0x02 }, { 0x81,0xfe,0x7f,0x7f },
{ 0xf0,0xa0,0x50,0x50 }, { 0x44,0x78,0x3c,0x3c },
- { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 },
+ { 0xba,0x25,0x9f,0x9f }, { 0xe3,0x4b,0xa8,0xa8 },
{ 0xf3,0xa2,0x51,0x51 }, { 0xfe,0x5d,0xa3,0xa3 },
- { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f },
+ { 0xc0,0x80,0x40,0x40 }, { 0x8a,0x05,0x8f,0x8f },
{ 0xad,0x3f,0x92,0x92 }, { 0xbc,0x21,0x9d,0x9d },
- { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 },
+ { 0x48,0x70,0x38,0x38 }, { 0x04,0xf1,0xf5,0xf5 },
{ 0xdf,0x63,0xbc,0xbc }, { 0xc1,0x77,0xb6,0xb6 },
- { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 },
+ { 0x75,0xaf,0xda,0xda }, { 0x63,0x42,0x21,0x21 },
{ 0x30,0x20,0x10,0x10 }, { 0x1a,0xe5,0xff,0xff },
- { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 },
+ { 0x0e,0xfd,0xf3,0xf3 }, { 0x6d,0xbf,0xd2,0xd2 },
{ 0x4c,0x81,0xcd,0xcd }, { 0x14,0x18,0x0c,0x0c },
- { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec },
+ { 0x35,0x26,0x13,0x13 }, { 0x2f,0xc3,0xec,0xec },
{ 0xe1,0xbe,0x5f,0x5f }, { 0xa2,0x35,0x97,0x97 },
- { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 },
+ { 0xcc,0x88,0x44,0x44 }, { 0x39,0x2e,0x17,0x17 },
{ 0x57,0x93,0xc4,0xc4 }, { 0xf2,0x55,0xa7,0xa7 },
- { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d },
+ { 0x82,0xfc,0x7e,0x7e }, { 0x47,0x7a,0x3d,0x3d },
{ 0xac,0xc8,0x64,0x64 }, { 0xe7,0xba,0x5d,0x5d },
- { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 },
- { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 },
- { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc },
- { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a },
- { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 },
+ { 0x2b,0x32,0x19,0x19 }, { 0x95,0xe6,0x73,0x73 },
+ { 0xa0,0xc0,0x60,0x60 }, { 0x98,0x19,0x81,0x81 },
+ { 0xd1,0x9e,0x4f,0x4f }, { 0x7f,0xa3,0xdc,0xdc },
+ { 0x66,0x44,0x22,0x22 }, { 0x7e,0x54,0x2a,0x2a },
+ { 0xab,0x3b,0x90,0x90 }, { 0x83,0x0b,0x88,0x88 },
{ 0xca,0x8c,0x46,0x46 }, { 0x29,0xc7,0xee,0xee },
- { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 },
+ { 0xd3,0x6b,0xb8,0xb8 }, { 0x3c,0x28,0x14,0x14 },
{ 0x79,0xa7,0xde,0xde }, { 0xe2,0xbc,0x5e,0x5e },
- { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb },
+ { 0x1d,0x16,0x0b,0x0b }, { 0x76,0xad,0xdb,0xdb },
{ 0x3b,0xdb,0xe0,0xe0 }, { 0x56,0x64,0x32,0x32 },
- { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a },
+ { 0x4e,0x74,0x3a,0x3a }, { 0x1e,0x14,0x0a,0x0a },
{ 0xdb,0x92,0x49,0x49 }, { 0x0a,0x0c,0x06,0x06 },
- { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c },
- { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 },
- { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 },
+ { 0x6c,0x48,0x24,0x24 }, { 0xe4,0xb8,0x5c,0x5c },
+ { 0x5d,0x9f,0xc2,0xc2 }, { 0x6e,0xbd,0xd3,0xd3 },
+ { 0xef,0x43,0xac,0xac }, { 0xa6,0xc4,0x62,0x62 },
{ 0xa8,0x39,0x91,0x91 }, { 0xa4,0x31,0x95,0x95 },
- { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 },
+ { 0x37,0xd3,0xe4,0xe4 }, { 0x8b,0xf2,0x79,0x79 },
{ 0x32,0xd5,0xe7,0xe7 }, { 0x43,0x8b,0xc8,0xc8 },
- { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d },
+ { 0x59,0x6e,0x37,0x37 }, { 0xb7,0xda,0x6d,0x6d },
{ 0x8c,0x01,0x8d,0x8d }, { 0x64,0xb1,0xd5,0xd5 },
- { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 },
+ { 0xd2,0x9c,0x4e,0x4e }, { 0xe0,0x49,0xa9,0xa9 },
{ 0xb4,0xd8,0x6c,0x6c }, { 0xfa,0xac,0x56,0x56 },
- { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea },
+ { 0x07,0xf3,0xf4,0xf4 }, { 0x25,0xcf,0xea,0xea },
{ 0xaf,0xca,0x65,0x65 }, { 0x8e,0xf4,0x7a,0x7a },
- { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 },
- { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 },
- { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e },
- { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 },
- { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 },
+ { 0xe9,0x47,0xae,0xae }, { 0x18,0x10,0x08,0x08 },
+ { 0xd5,0x6f,0xba,0xba }, { 0x88,0xf0,0x78,0x78 },
+ { 0x6f,0x4a,0x25,0x25 }, { 0x72,0x5c,0x2e,0x2e },
+ { 0x24,0x38,0x1c,0x1c }, { 0xf1,0x57,0xa6,0xa6 },
+ { 0xc7,0x73,0xb4,0xb4 }, { 0x51,0x97,0xc6,0xc6 },
{ 0x23,0xcb,0xe8,0xe8 }, { 0x7c,0xa1,0xdd,0xdd },
- { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f },
+ { 0x9c,0xe8,0x74,0x74 }, { 0x21,0x3e,0x1f,0x1f },
{ 0xdd,0x96,0x4b,0x4b }, { 0xdc,0x61,0xbd,0xbd },
- { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a },
- { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e },
- { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 },
+ { 0x86,0x0d,0x8b,0x8b }, { 0x85,0x0f,0x8a,0x8a },
+ { 0x90,0xe0,0x70,0x70 }, { 0x42,0x7c,0x3e,0x3e },
+ { 0xc4,0x71,0xb5,0xb5 }, { 0xaa,0xcc,0x66,0x66 },
{ 0xd8,0x90,0x48,0x48 }, { 0x05,0x06,0x03,0x03 },
- { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e },
+ { 0x01,0xf7,0xf6,0xf6 }, { 0x12,0x1c,0x0e,0x0e },
{ 0xa3,0xc2,0x61,0x61 }, { 0x5f,0x6a,0x35,0x35 },
- { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 },
- { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 },
- { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e },
+ { 0xf9,0xae,0x57,0x57 }, { 0xd0,0x69,0xb9,0xb9 },
+ { 0x91,0x17,0x86,0x86 }, { 0x58,0x99,0xc1,0xc1 },
+ { 0x27,0x3a,0x1d,0x1d }, { 0xb9,0x27,0x9e,0x9e },
{ 0x38,0xd9,0xe1,0xe1 }, { 0x13,0xeb,0xf8,0xf8 },
- { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 },
+ { 0xb3,0x2b,0x98,0x98 }, { 0x33,0x22,0x11,0x11 },
{ 0xbb,0xd2,0x69,0x69 }, { 0x70,0xa9,0xd9,0xd9 },
- { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 },
+ { 0x89,0x07,0x8e,0x8e }, { 0xa7,0x33,0x94,0x94 },
{ 0xb6,0x2d,0x9b,0x9b }, { 0x22,0x3c,0x1e,0x1e },
- { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 },
+ { 0x92,0x15,0x87,0x87 }, { 0x20,0xc9,0xe9,0xe9 },
{ 0x49,0x87,0xce,0xce }, { 0xff,0xaa,0x55,0x55 },
- { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf },
- { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 },
- { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d },
+ { 0x78,0x50,0x28,0x28 }, { 0x7a,0xa5,0xdf,0xdf },
+ { 0x8f,0x03,0x8c,0x8c }, { 0xf8,0x59,0xa1,0xa1 },
+ { 0x80,0x09,0x89,0x89 }, { 0x17,0x1a,0x0d,0x0d },
{ 0xda,0x65,0xbf,0xbf }, { 0x31,0xd7,0xe6,0xe6 },
- { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 },
- { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 },
- { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f },
- { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 },
+ { 0xc6,0x84,0x42,0x42 }, { 0xb8,0xd0,0x68,0x68 },
+ { 0xc3,0x82,0x41,0x41 }, { 0xb0,0x29,0x99,0x99 },
+ { 0x77,0x5a,0x2d,0x2d }, { 0x11,0x1e,0x0f,0x0f },
+ { 0xcb,0x7b,0xb0,0xb0 }, { 0xfc,0xa8,0x54,0x54 },
{ 0xd6,0x6d,0xbb,0xbb }, { 0x3a,0x2c,0x16,0x16 }
};
-static const unsigned char T3[256][4] =
+static const unsigned char T3[256][4] =
{
{ 0x63,0xa5,0xc6,0x63 }, { 0x7c,0x84,0xf8,0x7c },
- { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b },
+ { 0x77,0x99,0xee,0x77 }, { 0x7b,0x8d,0xf6,0x7b },
{ 0xf2,0x0d,0xff,0xf2 }, { 0x6b,0xbd,0xd6,0x6b },
- { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 },
+ { 0x6f,0xb1,0xde,0x6f }, { 0xc5,0x54,0x91,0xc5 },
{ 0x30,0x50,0x60,0x30 }, { 0x01,0x03,0x02,0x01 },
- { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b },
- { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 },
- { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 },
+ { 0x67,0xa9,0xce,0x67 }, { 0x2b,0x7d,0x56,0x2b },
+ { 0xfe,0x19,0xe7,0xfe }, { 0xd7,0x62,0xb5,0xd7 },
+ { 0xab,0xe6,0x4d,0xab }, { 0x76,0x9a,0xec,0x76 },
{ 0xca,0x45,0x8f,0xca }, { 0x82,0x9d,0x1f,0x82 },
- { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d },
- { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 },
- { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 },
- { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 },
- { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf },
+ { 0xc9,0x40,0x89,0xc9 }, { 0x7d,0x87,0xfa,0x7d },
+ { 0xfa,0x15,0xef,0xfa }, { 0x59,0xeb,0xb2,0x59 },
+ { 0x47,0xc9,0x8e,0x47 }, { 0xf0,0x0b,0xfb,0xf0 },
+ { 0xad,0xec,0x41,0xad }, { 0xd4,0x67,0xb3,0xd4 },
+ { 0xa2,0xfd,0x5f,0xa2 }, { 0xaf,0xea,0x45,0xaf },
{ 0x9c,0xbf,0x23,0x9c }, { 0xa4,0xf7,0x53,0xa4 },
- { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 },
- { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd },
- { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 },
+ { 0x72,0x96,0xe4,0x72 }, { 0xc0,0x5b,0x9b,0xc0 },
+ { 0xb7,0xc2,0x75,0xb7 }, { 0xfd,0x1c,0xe1,0xfd },
+ { 0x93,0xae,0x3d,0x93 }, { 0x26,0x6a,0x4c,0x26 },
{ 0x36,0x5a,0x6c,0x36 }, { 0x3f,0x41,0x7e,0x3f },
- { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc },
+ { 0xf7,0x02,0xf5,0xf7 }, { 0xcc,0x4f,0x83,0xcc },
{ 0x34,0x5c,0x68,0x34 }, { 0xa5,0xf4,0x51,0xa5 },
- { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 },
+ { 0xe5,0x34,0xd1,0xe5 }, { 0xf1,0x08,0xf9,0xf1 },
{ 0x71,0x93,0xe2,0x71 }, { 0xd8,0x73,0xab,0xd8 },
- { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 },
- { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 },
- { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 },
+ { 0x31,0x53,0x62,0x31 }, { 0x15,0x3f,0x2a,0x15 },
+ { 0x04,0x0c,0x08,0x04 }, { 0xc7,0x52,0x95,0xc7 },
+ { 0x23,0x65,0x46,0x23 }, { 0xc3,0x5e,0x9d,0xc3 },
{ 0x18,0x28,0x30,0x18 }, { 0x96,0xa1,0x37,0x96 },
- { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a },
- { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 },
- { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 },
+ { 0x05,0x0f,0x0a,0x05 }, { 0x9a,0xb5,0x2f,0x9a },
+ { 0x07,0x09,0x0e,0x07 }, { 0x12,0x36,0x24,0x12 },
+ { 0x80,0x9b,0x1b,0x80 }, { 0xe2,0x3d,0xdf,0xe2 },
{ 0xeb,0x26,0xcd,0xeb }, { 0x27,0x69,0x4e,0x27 },
- { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 },
+ { 0xb2,0xcd,0x7f,0xb2 }, { 0x75,0x9f,0xea,0x75 },
{ 0x09,0x1b,0x12,0x09 }, { 0x83,0x9e,0x1d,0x83 },
- { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a },
+ { 0x2c,0x74,0x58,0x2c }, { 0x1a,0x2e,0x34,0x1a },
{ 0x1b,0x2d,0x36,0x1b }, { 0x6e,0xb2,0xdc,0x6e },
- { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 },
+ { 0x5a,0xee,0xb4,0x5a }, { 0xa0,0xfb,0x5b,0xa0 },
{ 0x52,0xf6,0xa4,0x52 }, { 0x3b,0x4d,0x76,0x3b },
- { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 },
- { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 },
- { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 },
+ { 0xd6,0x61,0xb7,0xd6 }, { 0xb3,0xce,0x7d,0xb3 },
+ { 0x29,0x7b,0x52,0x29 }, { 0xe3,0x3e,0xdd,0xe3 },
+ { 0x2f,0x71,0x5e,0x2f }, { 0x84,0x97,0x13,0x84 },
{ 0x53,0xf5,0xa6,0x53 }, { 0xd1,0x68,0xb9,0xd1 },
- { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed },
+ { 0x00,0x00,0x00,0x00 }, { 0xed,0x2c,0xc1,0xed },
{ 0x20,0x60,0x40,0x20 }, { 0xfc,0x1f,0xe3,0xfc },
- { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b },
+ { 0xb1,0xc8,0x79,0xb1 }, { 0x5b,0xed,0xb6,0x5b },
{ 0x6a,0xbe,0xd4,0x6a }, { 0xcb,0x46,0x8d,0xcb },
- { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 },
+ { 0xbe,0xd9,0x67,0xbe }, { 0x39,0x4b,0x72,0x39 },
{ 0x4a,0xde,0x94,0x4a }, { 0x4c,0xd4,0x98,0x4c },
- { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf },
+ { 0x58,0xe8,0xb0,0x58 }, { 0xcf,0x4a,0x85,0xcf },
{ 0xd0,0x6b,0xbb,0xd0 }, { 0xef,0x2a,0xc5,0xef },
- { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb },
+ { 0xaa,0xe5,0x4f,0xaa }, { 0xfb,0x16,0xed,0xfb },
{ 0x43,0xc5,0x86,0x43 }, { 0x4d,0xd7,0x9a,0x4d },
- { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 },
+ { 0x33,0x55,0x66,0x33 }, { 0x85,0x94,0x11,0x85 },
{ 0x45,0xcf,0x8a,0x45 }, { 0xf9,0x10,0xe9,0xf9 },
- { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f },
+ { 0x02,0x06,0x04,0x02 }, { 0x7f,0x81,0xfe,0x7f },
{ 0x50,0xf0,0xa0,0x50 }, { 0x3c,0x44,0x78,0x3c },
- { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 },
+ { 0x9f,0xba,0x25,0x9f }, { 0xa8,0xe3,0x4b,0xa8 },
{ 0x51,0xf3,0xa2,0x51 }, { 0xa3,0xfe,0x5d,0xa3 },
- { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f },
+ { 0x40,0xc0,0x80,0x40 }, { 0x8f,0x8a,0x05,0x8f },
{ 0x92,0xad,0x3f,0x92 }, { 0x9d,0xbc,0x21,0x9d },
- { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 },
+ { 0x38,0x48,0x70,0x38 }, { 0xf5,0x04,0xf1,0xf5 },
{ 0xbc,0xdf,0x63,0xbc }, { 0xb6,0xc1,0x77,0xb6 },
- { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 },
+ { 0xda,0x75,0xaf,0xda }, { 0x21,0x63,0x42,0x21 },
{ 0x10,0x30,0x20,0x10 }, { 0xff,0x1a,0xe5,0xff },
- { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 },
- { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c },
- { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec },
+ { 0xf3,0x0e,0xfd,0xf3 }, { 0xd2,0x6d,0xbf,0xd2 },
+ { 0xcd,0x4c,0x81,0xcd }, { 0x0c,0x14,0x18,0x0c },
+ { 0x13,0x35,0x26,0x13 }, { 0xec,0x2f,0xc3,0xec },
{ 0x5f,0xe1,0xbe,0x5f }, { 0x97,0xa2,0x35,0x97 },
- { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 },
+ { 0x44,0xcc,0x88,0x44 }, { 0x17,0x39,0x2e,0x17 },
{ 0xc4,0x57,0x93,0xc4 }, { 0xa7,0xf2,0x55,0xa7 },
- { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d },
+ { 0x7e,0x82,0xfc,0x7e }, { 0x3d,0x47,0x7a,0x3d },
{ 0x64,0xac,0xc8,0x64 }, { 0x5d,0xe7,0xba,0x5d },
- { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 },
+ { 0x19,0x2b,0x32,0x19 }, { 0x73,0x95,0xe6,0x73 },
{ 0x60,0xa0,0xc0,0x60 }, { 0x81,0x98,0x19,0x81 },
- { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc },
+ { 0x4f,0xd1,0x9e,0x4f }, { 0xdc,0x7f,0xa3,0xdc },
{ 0x22,0x66,0x44,0x22 }, { 0x2a,0x7e,0x54,0x2a },
- { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 },
+ { 0x90,0xab,0x3b,0x90 }, { 0x88,0x83,0x0b,0x88 },
{ 0x46,0xca,0x8c,0x46 }, { 0xee,0x29,0xc7,0xee },
- { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 },
- { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e },
- { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb },
+ { 0xb8,0xd3,0x6b,0xb8 }, { 0x14,0x3c,0x28,0x14 },
+ { 0xde,0x79,0xa7,0xde }, { 0x5e,0xe2,0xbc,0x5e },
+ { 0x0b,0x1d,0x16,0x0b }, { 0xdb,0x76,0xad,0xdb },
{ 0xe0,0x3b,0xdb,0xe0 }, { 0x32,0x56,0x64,0x32 },
- { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a },
+ { 0x3a,0x4e,0x74,0x3a }, { 0x0a,0x1e,0x14,0x0a },
{ 0x49,0xdb,0x92,0x49 }, { 0x06,0x0a,0x0c,0x06 },
- { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c },
+ { 0x24,0x6c,0x48,0x24 }, { 0x5c,0xe4,0xb8,0x5c },
{ 0xc2,0x5d,0x9f,0xc2 }, { 0xd3,0x6e,0xbd,0xd3 },
- { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 },
+ { 0xac,0xef,0x43,0xac }, { 0x62,0xa6,0xc4,0x62 },
{ 0x91,0xa8,0x39,0x91 }, { 0x95,0xa4,0x31,0x95 },
- { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 },
- { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 },
- { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d },
- { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 },
- { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 },
+ { 0xe4,0x37,0xd3,0xe4 }, { 0x79,0x8b,0xf2,0x79 },
+ { 0xe7,0x32,0xd5,0xe7 }, { 0xc8,0x43,0x8b,0xc8 },
+ { 0x37,0x59,0x6e,0x37 }, { 0x6d,0xb7,0xda,0x6d },
+ { 0x8d,0x8c,0x01,0x8d }, { 0xd5,0x64,0xb1,0xd5 },
+ { 0x4e,0xd2,0x9c,0x4e }, { 0xa9,0xe0,0x49,0xa9 },
{ 0x6c,0xb4,0xd8,0x6c }, { 0x56,0xfa,0xac,0x56 },
- { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea },
- { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a },
- { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 },
- { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 },
- { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e },
- { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 },
- { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 },
+ { 0xf4,0x07,0xf3,0xf4 }, { 0xea,0x25,0xcf,0xea },
+ { 0x65,0xaf,0xca,0x65 }, { 0x7a,0x8e,0xf4,0x7a },
+ { 0xae,0xe9,0x47,0xae }, { 0x08,0x18,0x10,0x08 },
+ { 0xba,0xd5,0x6f,0xba }, { 0x78,0x88,0xf0,0x78 },
+ { 0x25,0x6f,0x4a,0x25 }, { 0x2e,0x72,0x5c,0x2e },
+ { 0x1c,0x24,0x38,0x1c }, { 0xa6,0xf1,0x57,0xa6 },
+ { 0xb4,0xc7,0x73,0xb4 }, { 0xc6,0x51,0x97,0xc6 },
{ 0xe8,0x23,0xcb,0xe8 }, { 0xdd,0x7c,0xa1,0xdd },
- { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f },
+ { 0x74,0x9c,0xe8,0x74 }, { 0x1f,0x21,0x3e,0x1f },
{ 0x4b,0xdd,0x96,0x4b }, { 0xbd,0xdc,0x61,0xbd },
- { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a },
+ { 0x8b,0x86,0x0d,0x8b }, { 0x8a,0x85,0x0f,0x8a },
{ 0x70,0x90,0xe0,0x70 }, { 0x3e,0x42,0x7c,0x3e },
- { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 },
+ { 0xb5,0xc4,0x71,0xb5 }, { 0x66,0xaa,0xcc,0x66 },
{ 0x48,0xd8,0x90,0x48 }, { 0x03,0x05,0x06,0x03 },
- { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e },
+ { 0xf6,0x01,0xf7,0xf6 }, { 0x0e,0x12,0x1c,0x0e },
{ 0x61,0xa3,0xc2,0x61 }, { 0x35,0x5f,0x6a,0x35 },
- { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 },
- { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 },
- { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e },
+ { 0x57,0xf9,0xae,0x57 }, { 0xb9,0xd0,0x69,0xb9 },
+ { 0x86,0x91,0x17,0x86 }, { 0xc1,0x58,0x99,0xc1 },
+ { 0x1d,0x27,0x3a,0x1d }, { 0x9e,0xb9,0x27,0x9e },
{ 0xe1,0x38,0xd9,0xe1 }, { 0xf8,0x13,0xeb,0xf8 },
- { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 },
+ { 0x98,0xb3,0x2b,0x98 }, { 0x11,0x33,0x22,0x11 },
{ 0x69,0xbb,0xd2,0x69 }, { 0xd9,0x70,0xa9,0xd9 },
- { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 },
+ { 0x8e,0x89,0x07,0x8e }, { 0x94,0xa7,0x33,0x94 },
{ 0x9b,0xb6,0x2d,0x9b }, { 0x1e,0x22,0x3c,0x1e },
- { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 },
+ { 0x87,0x92,0x15,0x87 }, { 0xe9,0x20,0xc9,0xe9 },
{ 0xce,0x49,0x87,0xce }, { 0x55,0xff,0xaa,0x55 },
- { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf },
+ { 0x28,0x78,0x50,0x28 }, { 0xdf,0x7a,0xa5,0xdf },
{ 0x8c,0x8f,0x03,0x8c }, { 0xa1,0xf8,0x59,0xa1 },
- { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d },
+ { 0x89,0x80,0x09,0x89 }, { 0x0d,0x17,0x1a,0x0d },
{ 0xbf,0xda,0x65,0xbf }, { 0xe6,0x31,0xd7,0xe6 },
- { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 },
+ { 0x42,0xc6,0x84,0x42 }, { 0x68,0xb8,0xd0,0x68 },
{ 0x41,0xc3,0x82,0x41 }, { 0x99,0xb0,0x29,0x99 },
- { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f },
+ { 0x2d,0x77,0x5a,0x2d }, { 0x0f,0x11,0x1e,0x0f },
{ 0xb0,0xcb,0x7b,0xb0 }, { 0x54,0xfc,0xa8,0x54 },
{ 0xbb,0xd6,0x6d,0xbb }, { 0x16,0x3a,0x2c,0x16 }
};
-static const unsigned char T4[256][4] =
+static const unsigned char T4[256][4] =
{
{ 0x63,0x63,0xa5,0xc6 }, { 0x7c,0x7c,0x84,0xf8 },
- { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 },
- { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 },
- { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 },
+ { 0x77,0x77,0x99,0xee }, { 0x7b,0x7b,0x8d,0xf6 },
+ { 0xf2,0xf2,0x0d,0xff }, { 0x6b,0x6b,0xbd,0xd6 },
+ { 0x6f,0x6f,0xb1,0xde }, { 0xc5,0xc5,0x54,0x91 },
{ 0x30,0x30,0x50,0x60 }, { 0x01,0x01,0x03,0x02 },
- { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 },
+ { 0x67,0x67,0xa9,0xce }, { 0x2b,0x2b,0x7d,0x56 },
{ 0xfe,0xfe,0x19,0xe7 }, { 0xd7,0xd7,0x62,0xb5 },
- { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec },
+ { 0xab,0xab,0xe6,0x4d }, { 0x76,0x76,0x9a,0xec },
{ 0xca,0xca,0x45,0x8f }, { 0x82,0x82,0x9d,0x1f },
- { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa },
+ { 0xc9,0xc9,0x40,0x89 }, { 0x7d,0x7d,0x87,0xfa },
{ 0xfa,0xfa,0x15,0xef }, { 0x59,0x59,0xeb,0xb2 },
- { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb },
+ { 0x47,0x47,0xc9,0x8e }, { 0xf0,0xf0,0x0b,0xfb },
{ 0xad,0xad,0xec,0x41 }, { 0xd4,0xd4,0x67,0xb3 },
- { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 },
+ { 0xa2,0xa2,0xfd,0x5f }, { 0xaf,0xaf,0xea,0x45 },
{ 0x9c,0x9c,0xbf,0x23 }, { 0xa4,0xa4,0xf7,0x53 },
- { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b },
+ { 0x72,0x72,0x96,0xe4 }, { 0xc0,0xc0,0x5b,0x9b },
{ 0xb7,0xb7,0xc2,0x75 }, { 0xfd,0xfd,0x1c,0xe1 },
- { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c },
+ { 0x93,0x93,0xae,0x3d }, { 0x26,0x26,0x6a,0x4c },
{ 0x36,0x36,0x5a,0x6c }, { 0x3f,0x3f,0x41,0x7e },
- { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 },
+ { 0xf7,0xf7,0x02,0xf5 }, { 0xcc,0xcc,0x4f,0x83 },
{ 0x34,0x34,0x5c,0x68 }, { 0xa5,0xa5,0xf4,0x51 },
- { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 },
+ { 0xe5,0xe5,0x34,0xd1 }, { 0xf1,0xf1,0x08,0xf9 },
{ 0x71,0x71,0x93,0xe2 }, { 0xd8,0xd8,0x73,0xab },
- { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a },
+ { 0x31,0x31,0x53,0x62 }, { 0x15,0x15,0x3f,0x2a },
{ 0x04,0x04,0x0c,0x08 }, { 0xc7,0xc7,0x52,0x95 },
- { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d },
+ { 0x23,0x23,0x65,0x46 }, { 0xc3,0xc3,0x5e,0x9d },
{ 0x18,0x18,0x28,0x30 }, { 0x96,0x96,0xa1,0x37 },
- { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f },
+ { 0x05,0x05,0x0f,0x0a }, { 0x9a,0x9a,0xb5,0x2f },
{ 0x07,0x07,0x09,0x0e }, { 0x12,0x12,0x36,0x24 },
- { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf },
+ { 0x80,0x80,0x9b,0x1b }, { 0xe2,0xe2,0x3d,0xdf },
{ 0xeb,0xeb,0x26,0xcd }, { 0x27,0x27,0x69,0x4e },
- { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea },
+ { 0xb2,0xb2,0xcd,0x7f }, { 0x75,0x75,0x9f,0xea },
{ 0x09,0x09,0x1b,0x12 }, { 0x83,0x83,0x9e,0x1d },
- { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 },
+ { 0x2c,0x2c,0x74,0x58 }, { 0x1a,0x1a,0x2e,0x34 },
{ 0x1b,0x1b,0x2d,0x36 }, { 0x6e,0x6e,0xb2,0xdc },
- { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b },
+ { 0x5a,0x5a,0xee,0xb4 }, { 0xa0,0xa0,0xfb,0x5b },
{ 0x52,0x52,0xf6,0xa4 }, { 0x3b,0x3b,0x4d,0x76 },
- { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d },
+ { 0xd6,0xd6,0x61,0xb7 }, { 0xb3,0xb3,0xce,0x7d },
{ 0x29,0x29,0x7b,0x52 }, { 0xe3,0xe3,0x3e,0xdd },
- { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 },
+ { 0x2f,0x2f,0x71,0x5e }, { 0x84,0x84,0x97,0x13 },
{ 0x53,0x53,0xf5,0xa6 }, { 0xd1,0xd1,0x68,0xb9 },
- { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 },
+ { 0x00,0x00,0x00,0x00 }, { 0xed,0xed,0x2c,0xc1 },
{ 0x20,0x20,0x60,0x40 }, { 0xfc,0xfc,0x1f,0xe3 },
- { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 },
+ { 0xb1,0xb1,0xc8,0x79 }, { 0x5b,0x5b,0xed,0xb6 },
{ 0x6a,0x6a,0xbe,0xd4 }, { 0xcb,0xcb,0x46,0x8d },
- { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 },
+ { 0xbe,0xbe,0xd9,0x67 }, { 0x39,0x39,0x4b,0x72 },
{ 0x4a,0x4a,0xde,0x94 }, { 0x4c,0x4c,0xd4,0x98 },
- { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 },
+ { 0x58,0x58,0xe8,0xb0 }, { 0xcf,0xcf,0x4a,0x85 },
{ 0xd0,0xd0,0x6b,0xbb }, { 0xef,0xef,0x2a,0xc5 },
- { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed },
+ { 0xaa,0xaa,0xe5,0x4f }, { 0xfb,0xfb,0x16,0xed },
{ 0x43,0x43,0xc5,0x86 }, { 0x4d,0x4d,0xd7,0x9a },
- { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 },
+ { 0x33,0x33,0x55,0x66 }, { 0x85,0x85,0x94,0x11 },
{ 0x45,0x45,0xcf,0x8a }, { 0xf9,0xf9,0x10,0xe9 },
- { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe },
+ { 0x02,0x02,0x06,0x04 }, { 0x7f,0x7f,0x81,0xfe },
{ 0x50,0x50,0xf0,0xa0 }, { 0x3c,0x3c,0x44,0x78 },
- { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b },
+ { 0x9f,0x9f,0xba,0x25 }, { 0xa8,0xa8,0xe3,0x4b },
{ 0x51,0x51,0xf3,0xa2 }, { 0xa3,0xa3,0xfe,0x5d },
- { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 },
+ { 0x40,0x40,0xc0,0x80 }, { 0x8f,0x8f,0x8a,0x05 },
{ 0x92,0x92,0xad,0x3f }, { 0x9d,0x9d,0xbc,0x21 },
- { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 },
+ { 0x38,0x38,0x48,0x70 }, { 0xf5,0xf5,0x04,0xf1 },
{ 0xbc,0xbc,0xdf,0x63 }, { 0xb6,0xb6,0xc1,0x77 },
- { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 },
+ { 0xda,0xda,0x75,0xaf }, { 0x21,0x21,0x63,0x42 },
{ 0x10,0x10,0x30,0x20 }, { 0xff,0xff,0x1a,0xe5 },
- { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf },
+ { 0xf3,0xf3,0x0e,0xfd }, { 0xd2,0xd2,0x6d,0xbf },
{ 0xcd,0xcd,0x4c,0x81 }, { 0x0c,0x0c,0x14,0x18 },
- { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 },
+ { 0x13,0x13,0x35,0x26 }, { 0xec,0xec,0x2f,0xc3 },
{ 0x5f,0x5f,0xe1,0xbe }, { 0x97,0x97,0xa2,0x35 },
- { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e },
+ { 0x44,0x44,0xcc,0x88 }, { 0x17,0x17,0x39,0x2e },
{ 0xc4,0xc4,0x57,0x93 }, { 0xa7,0xa7,0xf2,0x55 },
- { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a },
+ { 0x7e,0x7e,0x82,0xfc }, { 0x3d,0x3d,0x47,0x7a },
{ 0x64,0x64,0xac,0xc8 }, { 0x5d,0x5d,0xe7,0xba },
- { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 },
+ { 0x19,0x19,0x2b,0x32 }, { 0x73,0x73,0x95,0xe6 },
{ 0x60,0x60,0xa0,0xc0 }, { 0x81,0x81,0x98,0x19 },
- { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 },
+ { 0x4f,0x4f,0xd1,0x9e }, { 0xdc,0xdc,0x7f,0xa3 },
{ 0x22,0x22,0x66,0x44 }, { 0x2a,0x2a,0x7e,0x54 },
- { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b },
+ { 0x90,0x90,0xab,0x3b }, { 0x88,0x88,0x83,0x0b },
{ 0x46,0x46,0xca,0x8c }, { 0xee,0xee,0x29,0xc7 },
- { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 },
+ { 0xb8,0xb8,0xd3,0x6b }, { 0x14,0x14,0x3c,0x28 },
{ 0xde,0xde,0x79,0xa7 }, { 0x5e,0x5e,0xe2,0xbc },
- { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad },
+ { 0x0b,0x0b,0x1d,0x16 }, { 0xdb,0xdb,0x76,0xad },
{ 0xe0,0xe0,0x3b,0xdb }, { 0x32,0x32,0x56,0x64 },
- { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 },
+ { 0x3a,0x3a,0x4e,0x74 }, { 0x0a,0x0a,0x1e,0x14 },
{ 0x49,0x49,0xdb,0x92 }, { 0x06,0x06,0x0a,0x0c },
- { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 },
+ { 0x24,0x24,0x6c,0x48 }, { 0x5c,0x5c,0xe4,0xb8 },
{ 0xc2,0xc2,0x5d,0x9f }, { 0xd3,0xd3,0x6e,0xbd },
- { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 },
+ { 0xac,0xac,0xef,0x43 }, { 0x62,0x62,0xa6,0xc4 },
{ 0x91,0x91,0xa8,0x39 }, { 0x95,0x95,0xa4,0x31 },
- { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 },
+ { 0xe4,0xe4,0x37,0xd3 }, { 0x79,0x79,0x8b,0xf2 },
{ 0xe7,0xe7,0x32,0xd5 }, { 0xc8,0xc8,0x43,0x8b },
- { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda },
- { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 },
- { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 },
- { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac },
- { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf },
- { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 },
- { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 },
- { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 },
- { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c },
+ { 0x37,0x37,0x59,0x6e }, { 0x6d,0x6d,0xb7,0xda },
+ { 0x8d,0x8d,0x8c,0x01 }, { 0xd5,0xd5,0x64,0xb1 },
+ { 0x4e,0x4e,0xd2,0x9c }, { 0xa9,0xa9,0xe0,0x49 },
+ { 0x6c,0x6c,0xb4,0xd8 }, { 0x56,0x56,0xfa,0xac },
+ { 0xf4,0xf4,0x07,0xf3 }, { 0xea,0xea,0x25,0xcf },
+ { 0x65,0x65,0xaf,0xca }, { 0x7a,0x7a,0x8e,0xf4 },
+ { 0xae,0xae,0xe9,0x47 }, { 0x08,0x08,0x18,0x10 },
+ { 0xba,0xba,0xd5,0x6f }, { 0x78,0x78,0x88,0xf0 },
+ { 0x25,0x25,0x6f,0x4a }, { 0x2e,0x2e,0x72,0x5c },
{ 0x1c,0x1c,0x24,0x38 }, { 0xa6,0xa6,0xf1,0x57 },
- { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 },
+ { 0xb4,0xb4,0xc7,0x73 }, { 0xc6,0xc6,0x51,0x97 },
{ 0xe8,0xe8,0x23,0xcb }, { 0xdd,0xdd,0x7c,0xa1 },
- { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e },
+ { 0x74,0x74,0x9c,0xe8 }, { 0x1f,0x1f,0x21,0x3e },
{ 0x4b,0x4b,0xdd,0x96 }, { 0xbd,0xbd,0xdc,0x61 },
- { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f },
+ { 0x8b,0x8b,0x86,0x0d }, { 0x8a,0x8a,0x85,0x0f },
{ 0x70,0x70,0x90,0xe0 }, { 0x3e,0x3e,0x42,0x7c },
- { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc },
+ { 0xb5,0xb5,0xc4,0x71 }, { 0x66,0x66,0xaa,0xcc },
{ 0x48,0x48,0xd8,0x90 }, { 0x03,0x03,0x05,0x06 },
- { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c },
+ { 0xf6,0xf6,0x01,0xf7 }, { 0x0e,0x0e,0x12,0x1c },
{ 0x61,0x61,0xa3,0xc2 }, { 0x35,0x35,0x5f,0x6a },
- { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 },
+ { 0x57,0x57,0xf9,0xae }, { 0xb9,0xb9,0xd0,0x69 },
{ 0x86,0x86,0x91,0x17 }, { 0xc1,0xc1,0x58,0x99 },
- { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 },
+ { 0x1d,0x1d,0x27,0x3a }, { 0x9e,0x9e,0xb9,0x27 },
{ 0xe1,0xe1,0x38,0xd9 }, { 0xf8,0xf8,0x13,0xeb },
- { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 },
+ { 0x98,0x98,0xb3,0x2b }, { 0x11,0x11,0x33,0x22 },
{ 0x69,0x69,0xbb,0xd2 }, { 0xd9,0xd9,0x70,0xa9 },
- { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 },
+ { 0x8e,0x8e,0x89,0x07 }, { 0x94,0x94,0xa7,0x33 },
{ 0x9b,0x9b,0xb6,0x2d }, { 0x1e,0x1e,0x22,0x3c },
- { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 },
+ { 0x87,0x87,0x92,0x15 }, { 0xe9,0xe9,0x20,0xc9 },
{ 0xce,0xce,0x49,0x87 }, { 0x55,0x55,0xff,0xaa },
- { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 },
+ { 0x28,0x28,0x78,0x50 }, { 0xdf,0xdf,0x7a,0xa5 },
{ 0x8c,0x8c,0x8f,0x03 }, { 0xa1,0xa1,0xf8,0x59 },
- { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a },
- { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 },
- { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 },
+ { 0x89,0x89,0x80,0x09 }, { 0x0d,0x0d,0x17,0x1a },
+ { 0xbf,0xbf,0xda,0x65 }, { 0xe6,0xe6,0x31,0xd7 },
+ { 0x42,0x42,0xc6,0x84 }, { 0x68,0x68,0xb8,0xd0 },
{ 0x41,0x41,0xc3,0x82 }, { 0x99,0x99,0xb0,0x29 },
- { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e },
+ { 0x2d,0x2d,0x77,0x5a }, { 0x0f,0x0f,0x11,0x1e },
{ 0xb0,0xb0,0xcb,0x7b }, { 0x54,0x54,0xfc,0xa8 },
{ 0xbb,0xbb,0xd6,0x6d }, { 0x16,0x16,0x3a,0x2c }
};
-static const unsigned char T5[256][4] =
+static const unsigned char T5[256][4] =
{
- { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 },
- { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 },
+ { 0x51,0xf4,0xa7,0x50 }, { 0x7e,0x41,0x65,0x53 },
+ { 0x1a,0x17,0xa4,0xc3 }, { 0x3a,0x27,0x5e,0x96 },
{ 0x3b,0xab,0x6b,0xcb }, { 0x1f,0x9d,0x45,0xf1 },
- { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 },
+ { 0xac,0xfa,0x58,0xab }, { 0x4b,0xe3,0x03,0x93 },
{ 0x20,0x30,0xfa,0x55 }, { 0xad,0x76,0x6d,0xf6 },
- { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 },
+ { 0x88,0xcc,0x76,0x91 }, { 0xf5,0x02,0x4c,0x25 },
{ 0x4f,0xe5,0xd7,0xfc }, { 0xc5,0x2a,0xcb,0xd7 },
- { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f },
+ { 0x26,0x35,0x44,0x80 }, { 0xb5,0x62,0xa3,0x8f },
{ 0xde,0xb1,0x5a,0x49 }, { 0x25,0xba,0x1b,0x67 },
- { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 },
+ { 0x45,0xea,0x0e,0x98 }, { 0x5d,0xfe,0xc0,0xe1 },
{ 0xc3,0x2f,0x75,0x02 }, { 0x81,0x4c,0xf0,0x12 },
- { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 },
+ { 0x8d,0x46,0x97,0xa3 }, { 0x6b,0xd3,0xf9,0xc6 },
{ 0x03,0x8f,0x5f,0xe7 }, { 0x15,0x92,0x9c,0x95 },
- { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda },
+ { 0xbf,0x6d,0x7a,0xeb }, { 0x95,0x52,0x59,0xda },
{ 0xd4,0xbe,0x83,0x2d }, { 0x58,0x74,0x21,0xd3 },
- { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 },
+ { 0x49,0xe0,0x69,0x29 }, { 0x8e,0xc9,0xc8,0x44 },
{ 0x75,0xc2,0x89,0x6a }, { 0xf4,0x8e,0x79,0x78 },
- { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd },
+ { 0x99,0x58,0x3e,0x6b }, { 0x27,0xb9,0x71,0xdd },
{ 0xbe,0xe1,0x4f,0xb6 }, { 0xf0,0x88,0xad,0x17 },
- { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 },
+ { 0xc9,0x20,0xac,0x66 }, { 0x7d,0xce,0x3a,0xb4 },
{ 0x63,0xdf,0x4a,0x18 }, { 0xe5,0x1a,0x31,0x82 },
- { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 },
- { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 },
- { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 },
- { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 },
- { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 },
+ { 0x97,0x51,0x33,0x60 }, { 0x62,0x53,0x7f,0x45 },
+ { 0xb1,0x64,0x77,0xe0 }, { 0xbb,0x6b,0xae,0x84 },
+ { 0xfe,0x81,0xa0,0x1c }, { 0xf9,0x08,0x2b,0x94 },
+ { 0x70,0x48,0x68,0x58 }, { 0x8f,0x45,0xfd,0x19 },
+ { 0x94,0xde,0x6c,0x87 }, { 0x52,0x7b,0xf8,0xb7 },
{ 0xab,0x73,0xd3,0x23 }, { 0x72,0x4b,0x02,0xe2 },
- { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a },
+ { 0xe3,0x1f,0x8f,0x57 }, { 0x66,0x55,0xab,0x2a },
{ 0xb2,0xeb,0x28,0x07 }, { 0x2f,0xb5,0xc2,0x03 },
- { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 },
+ { 0x86,0xc5,0x7b,0x9a }, { 0xd3,0x37,0x08,0xa5 },
{ 0x30,0x28,0x87,0xf2 }, { 0x23,0xbf,0xa5,0xb2 },
- { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c },
+ { 0x02,0x03,0x6a,0xba }, { 0xed,0x16,0x82,0x5c },
{ 0x8a,0xcf,0x1c,0x2b }, { 0xa7,0x79,0xb4,0x92 },
- { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 },
+ { 0xf3,0x07,0xf2,0xf0 }, { 0x4e,0x69,0xe2,0xa1 },
{ 0x65,0xda,0xf4,0xcd }, { 0x06,0x05,0xbe,0xd5 },
- { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a },
+ { 0xd1,0x34,0x62,0x1f }, { 0xc4,0xa6,0xfe,0x8a },
{ 0x34,0x2e,0x53,0x9d }, { 0xa2,0xf3,0x55,0xa0 },
- { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 },
+ { 0x05,0x8a,0xe1,0x32 }, { 0xa4,0xf6,0xeb,0x75 },
{ 0x0b,0x83,0xec,0x39 }, { 0x40,0x60,0xef,0xaa },
- { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 },
- { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d },
- { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 },
- { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 },
- { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff },
+ { 0x5e,0x71,0x9f,0x06 }, { 0xbd,0x6e,0x10,0x51 },
+ { 0x3e,0x21,0x8a,0xf9 }, { 0x96,0xdd,0x06,0x3d },
+ { 0xdd,0x3e,0x05,0xae }, { 0x4d,0xe6,0xbd,0x46 },
+ { 0x91,0x54,0x8d,0xb5 }, { 0x71,0xc4,0x5d,0x05 },
+ { 0x04,0x06,0xd4,0x6f }, { 0x60,0x50,0x15,0xff },
{ 0x19,0x98,0xfb,0x24 }, { 0xd6,0xbd,0xe9,0x97 },
- { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 },
+ { 0x89,0x40,0x43,0xcc }, { 0x67,0xd9,0x9e,0x77 },
{ 0xb0,0xe8,0x42,0xbd }, { 0x07,0x89,0x8b,0x88 },
- { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb },
+ { 0xe7,0x19,0x5b,0x38 }, { 0x79,0xc8,0xee,0xdb },
{ 0xa1,0x7c,0x0a,0x47 }, { 0x7c,0x42,0x0f,0xe9 },
- { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 },
+ { 0xf8,0x84,0x1e,0xc9 }, { 0x00,0x00,0x00,0x00 },
{ 0x09,0x80,0x86,0x83 }, { 0x32,0x2b,0xed,0x48 },
- { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e },
+ { 0x1e,0x11,0x70,0xac }, { 0x6c,0x5a,0x72,0x4e },
{ 0xfd,0x0e,0xff,0xfb }, { 0x0f,0x85,0x38,0x56 },
- { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 },
+ { 0x3d,0xae,0xd5,0x1e }, { 0x36,0x2d,0x39,0x27 },
{ 0x0a,0x0f,0xd9,0x64 }, { 0x68,0x5c,0xa6,0x21 },
- { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a },
+ { 0x9b,0x5b,0x54,0xd1 }, { 0x24,0x36,0x2e,0x3a },
{ 0x0c,0x0a,0x67,0xb1 }, { 0x93,0x57,0xe7,0x0f },
- { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e },
+ { 0xb4,0xee,0x96,0xd2 }, { 0x1b,0x9b,0x91,0x9e },
{ 0x80,0xc0,0xc5,0x4f }, { 0x61,0xdc,0x20,0xa2 },
- { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 },
- { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 },
- { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d },
- { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad },
- { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 },
- { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c },
- { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd },
+ { 0x5a,0x77,0x4b,0x69 }, { 0x1c,0x12,0x1a,0x16 },
+ { 0xe2,0x93,0xba,0x0a }, { 0xc0,0xa0,0x2a,0xe5 },
+ { 0x3c,0x22,0xe0,0x43 }, { 0x12,0x1b,0x17,0x1d },
+ { 0x0e,0x09,0x0d,0x0b }, { 0xf2,0x8b,0xc7,0xad },
+ { 0x2d,0xb6,0xa8,0xb9 }, { 0x14,0x1e,0xa9,0xc8 },
+ { 0x57,0xf1,0x19,0x85 }, { 0xaf,0x75,0x07,0x4c },
+ { 0xee,0x99,0xdd,0xbb }, { 0xa3,0x7f,0x60,0xfd },
{ 0xf7,0x01,0x26,0x9f }, { 0x5c,0x72,0xf5,0xbc },
- { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 },
+ { 0x44,0x66,0x3b,0xc5 }, { 0x5b,0xfb,0x7e,0x34 },
{ 0x8b,0x43,0x29,0x76 }, { 0xcb,0x23,0xc6,0xdc },
- { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 },
+ { 0xb6,0xed,0xfc,0x68 }, { 0xb8,0xe4,0xf1,0x63 },
{ 0xd7,0x31,0xdc,0xca }, { 0x42,0x63,0x85,0x10 },
- { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 },
- { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 },
- { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d },
+ { 0x13,0x97,0x22,0x40 }, { 0x84,0xc6,0x11,0x20 },
+ { 0x85,0x4a,0x24,0x7d }, { 0xd2,0xbb,0x3d,0xf8 },
+ { 0xae,0xf9,0x32,0x11 }, { 0xc7,0x29,0xa1,0x6d },
{ 0x1d,0x9e,0x2f,0x4b }, { 0xdc,0xb2,0x30,0xf3 },
- { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 },
+ { 0x0d,0x86,0x52,0xec }, { 0x77,0xc1,0xe3,0xd0 },
{ 0x2b,0xb3,0x16,0x6c }, { 0xa9,0x70,0xb9,0x99 },
- { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 },
+ { 0x11,0x94,0x48,0xfa }, { 0x47,0xe9,0x64,0x22 },
{ 0xa8,0xfc,0x8c,0xc4 }, { 0xa0,0xf0,0x3f,0x1a },
- { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef },
- { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 },
- { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 },
- { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 },
- { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 },
- { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d },
- { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 },
- { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 },
- { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 },
+ { 0x56,0x7d,0x2c,0xd8 }, { 0x22,0x33,0x90,0xef },
+ { 0x87,0x49,0x4e,0xc7 }, { 0xd9,0x38,0xd1,0xc1 },
+ { 0x8c,0xca,0xa2,0xfe }, { 0x98,0xd4,0x0b,0x36 },
+ { 0xa6,0xf5,0x81,0xcf }, { 0xa5,0x7a,0xde,0x28 },
+ { 0xda,0xb7,0x8e,0x26 }, { 0x3f,0xad,0xbf,0xa4 },
+ { 0x2c,0x3a,0x9d,0xe4 }, { 0x50,0x78,0x92,0x0d },
+ { 0x6a,0x5f,0xcc,0x9b }, { 0x54,0x7e,0x46,0x62 },
+ { 0xf6,0x8d,0x13,0xc2 }, { 0x90,0xd8,0xb8,0xe8 },
+ { 0x2e,0x39,0xf7,0x5e }, { 0x82,0xc3,0xaf,0xf5 },
{ 0x9f,0x5d,0x80,0xbe }, { 0x69,0xd0,0x93,0x7c },
- { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 },
+ { 0x6f,0xd5,0x2d,0xa9 }, { 0xcf,0x25,0x12,0xb3 },
{ 0xc8,0xac,0x99,0x3b }, { 0x10,0x18,0x7d,0xa7 },
- { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b },
+ { 0xe8,0x9c,0x63,0x6e }, { 0xdb,0x3b,0xbb,0x7b },
{ 0xcd,0x26,0x78,0x09 }, { 0x6e,0x59,0x18,0xf4 },
- { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 },
- { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e },
- { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 },
- { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce },
- { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 },
- { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 },
- { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 },
- { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 },
- { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 },
+ { 0xec,0x9a,0xb7,0x01 }, { 0x83,0x4f,0x9a,0xa8 },
+ { 0xe6,0x95,0x6e,0x65 }, { 0xaa,0xff,0xe6,0x7e },
+ { 0x21,0xbc,0xcf,0x08 }, { 0xef,0x15,0xe8,0xe6 },
+ { 0xba,0xe7,0x9b,0xd9 }, { 0x4a,0x6f,0x36,0xce },
+ { 0xea,0x9f,0x09,0xd4 }, { 0x29,0xb0,0x7c,0xd6 },
+ { 0x31,0xa4,0xb2,0xaf }, { 0x2a,0x3f,0x23,0x31 },
+ { 0xc6,0xa5,0x94,0x30 }, { 0x35,0xa2,0x66,0xc0 },
+ { 0x74,0x4e,0xbc,0x37 }, { 0xfc,0x82,0xca,0xa6 },
+ { 0xe0,0x90,0xd0,0xb0 }, { 0x33,0xa7,0xd8,0x15 },
{ 0xf1,0x04,0x98,0x4a }, { 0x41,0xec,0xda,0xf7 },
- { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f },
+ { 0x7f,0xcd,0x50,0x0e }, { 0x17,0x91,0xf6,0x2f },
{ 0x76,0x4d,0xd6,0x8d }, { 0x43,0xef,0xb0,0x4d },
- { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf },
+ { 0xcc,0xaa,0x4d,0x54 }, { 0xe4,0x96,0x04,0xdf },
{ 0x9e,0xd1,0xb5,0xe3 }, { 0x4c,0x6a,0x88,0x1b },
- { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f },
+ { 0xc1,0x2c,0x1f,0xb8 }, { 0x46,0x65,0x51,0x7f },
{ 0x9d,0x5e,0xea,0x04 }, { 0x01,0x8c,0x35,0x5d },
- { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e },
+ { 0xfa,0x87,0x74,0x73 }, { 0xfb,0x0b,0x41,0x2e },
{ 0xb3,0x67,0x1d,0x5a }, { 0x92,0xdb,0xd2,0x52 },
- { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 },
+ { 0xe9,0x10,0x56,0x33 }, { 0x6d,0xd6,0x47,0x13 },
{ 0x9a,0xd7,0x61,0x8c }, { 0x37,0xa1,0x0c,0x7a },
- { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 },
+ { 0x59,0xf8,0x14,0x8e }, { 0xeb,0x13,0x3c,0x89 },
{ 0xce,0xa9,0x27,0xee }, { 0xb7,0x61,0xc9,0x35 },
- { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c },
- { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f },
- { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf },
+ { 0xe1,0x1c,0xe5,0xed }, { 0x7a,0x47,0xb1,0x3c },
+ { 0x9c,0xd2,0xdf,0x59 }, { 0x55,0xf2,0x73,0x3f },
+ { 0x18,0x14,0xce,0x79 }, { 0x73,0xc7,0x37,0xbf },
{ 0x53,0xf7,0xcd,0xea }, { 0x5f,0xfd,0xaa,0x5b },
- { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 },
- { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e },
- { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f },
- { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c },
- { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 },
- { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde },
- { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 },
+ { 0xdf,0x3d,0x6f,0x14 }, { 0x78,0x44,0xdb,0x86 },
+ { 0xca,0xaf,0xf3,0x81 }, { 0xb9,0x68,0xc4,0x3e },
+ { 0x38,0x24,0x34,0x2c }, { 0xc2,0xa3,0x40,0x5f },
+ { 0x16,0x1d,0xc3,0x72 }, { 0xbc,0xe2,0x25,0x0c },
+ { 0x28,0x3c,0x49,0x8b }, { 0xff,0x0d,0x95,0x41 },
+ { 0x39,0xa8,0x01,0x71 }, { 0x08,0x0c,0xb3,0xde },
+ { 0xd8,0xb4,0xe4,0x9c }, { 0x64,0x56,0xc1,0x90 },
{ 0x7b,0xcb,0x84,0x61 }, { 0xd5,0x32,0xb6,0x70 },
{ 0x48,0x6c,0x5c,0x74 }, { 0xd0,0xb8,0x57,0x42 }
};
-static const unsigned char T6[256][4] =
+static const unsigned char T6[256][4] =
{
- { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 },
- { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e },
+ { 0x50,0x51,0xf4,0xa7 }, { 0x53,0x7e,0x41,0x65 },
+ { 0xc3,0x1a,0x17,0xa4 }, { 0x96,0x3a,0x27,0x5e },
{ 0xcb,0x3b,0xab,0x6b }, { 0xf1,0x1f,0x9d,0x45 },
- { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 },
+ { 0xab,0xac,0xfa,0x58 }, { 0x93,0x4b,0xe3,0x03 },
{ 0x55,0x20,0x30,0xfa }, { 0xf6,0xad,0x76,0x6d },
- { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c },
+ { 0x91,0x88,0xcc,0x76 }, { 0x25,0xf5,0x02,0x4c },
{ 0xfc,0x4f,0xe5,0xd7 }, { 0xd7,0xc5,0x2a,0xcb },
- { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 },
- { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b },
- { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 },
+ { 0x80,0x26,0x35,0x44 }, { 0x8f,0xb5,0x62,0xa3 },
+ { 0x49,0xde,0xb1,0x5a }, { 0x67,0x25,0xba,0x1b },
+ { 0x98,0x45,0xea,0x0e }, { 0xe1,0x5d,0xfe,0xc0 },
{ 0x02,0xc3,0x2f,0x75 }, { 0x12,0x81,0x4c,0xf0 },
- { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 },
+ { 0xa3,0x8d,0x46,0x97 }, { 0xc6,0x6b,0xd3,0xf9 },
{ 0xe7,0x03,0x8f,0x5f }, { 0x95,0x15,0x92,0x9c },
- { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 },
+ { 0xeb,0xbf,0x6d,0x7a }, { 0xda,0x95,0x52,0x59 },
{ 0x2d,0xd4,0xbe,0x83 }, { 0xd3,0x58,0x74,0x21 },
- { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 },
+ { 0x29,0x49,0xe0,0x69 }, { 0x44,0x8e,0xc9,0xc8 },
{ 0x6a,0x75,0xc2,0x89 }, { 0x78,0xf4,0x8e,0x79 },
- { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 },
+ { 0x6b,0x99,0x58,0x3e }, { 0xdd,0x27,0xb9,0x71 },
{ 0xb6,0xbe,0xe1,0x4f }, { 0x17,0xf0,0x88,0xad },
- { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a },
+ { 0x66,0xc9,0x20,0xac }, { 0xb4,0x7d,0xce,0x3a },
{ 0x18,0x63,0xdf,0x4a }, { 0x82,0xe5,0x1a,0x31 },
- { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f },
+ { 0x60,0x97,0x51,0x33 }, { 0x45,0x62,0x53,0x7f },
{ 0xe0,0xb1,0x64,0x77 }, { 0x84,0xbb,0x6b,0xae },
- { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b },
+ { 0x1c,0xfe,0x81,0xa0 }, { 0x94,0xf9,0x08,0x2b },
{ 0x58,0x70,0x48,0x68 }, { 0x19,0x8f,0x45,0xfd },
- { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 },
+ { 0x87,0x94,0xde,0x6c }, { 0xb7,0x52,0x7b,0xf8 },
{ 0x23,0xab,0x73,0xd3 }, { 0xe2,0x72,0x4b,0x02 },
- { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab },
+ { 0x57,0xe3,0x1f,0x8f }, { 0x2a,0x66,0x55,0xab },
{ 0x07,0xb2,0xeb,0x28 }, { 0x03,0x2f,0xb5,0xc2 },
- { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 },
+ { 0x9a,0x86,0xc5,0x7b }, { 0xa5,0xd3,0x37,0x08 },
{ 0xf2,0x30,0x28,0x87 }, { 0xb2,0x23,0xbf,0xa5 },
- { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 },
+ { 0xba,0x02,0x03,0x6a }, { 0x5c,0xed,0x16,0x82 },
{ 0x2b,0x8a,0xcf,0x1c }, { 0x92,0xa7,0x79,0xb4 },
- { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 },
+ { 0xf0,0xf3,0x07,0xf2 }, { 0xa1,0x4e,0x69,0xe2 },
{ 0xcd,0x65,0xda,0xf4 }, { 0xd5,0x06,0x05,0xbe },
- { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe },
+ { 0x1f,0xd1,0x34,0x62 }, { 0x8a,0xc4,0xa6,0xfe },
{ 0x9d,0x34,0x2e,0x53 }, { 0xa0,0xa2,0xf3,0x55 },
- { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb },
+ { 0x32,0x05,0x8a,0xe1 }, { 0x75,0xa4,0xf6,0xeb },
{ 0x39,0x0b,0x83,0xec }, { 0xaa,0x40,0x60,0xef },
- { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 },
+ { 0x06,0x5e,0x71,0x9f }, { 0x51,0xbd,0x6e,0x10 },
{ 0xf9,0x3e,0x21,0x8a }, { 0x3d,0x96,0xdd,0x06 },
- { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd },
+ { 0xae,0xdd,0x3e,0x05 }, { 0x46,0x4d,0xe6,0xbd },
{ 0xb5,0x91,0x54,0x8d }, { 0x05,0x71,0xc4,0x5d },
- { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 },
+ { 0x6f,0x04,0x06,0xd4 }, { 0xff,0x60,0x50,0x15 },
{ 0x24,0x19,0x98,0xfb }, { 0x97,0xd6,0xbd,0xe9 },
- { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e },
+ { 0xcc,0x89,0x40,0x43 }, { 0x77,0x67,0xd9,0x9e },
{ 0xbd,0xb0,0xe8,0x42 }, { 0x88,0x07,0x89,0x8b },
- { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee },
+ { 0x38,0xe7,0x19,0x5b }, { 0xdb,0x79,0xc8,0xee },
{ 0x47,0xa1,0x7c,0x0a }, { 0xe9,0x7c,0x42,0x0f },
- { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 },
+ { 0xc9,0xf8,0x84,0x1e }, { 0x00,0x00,0x00,0x00 },
{ 0x83,0x09,0x80,0x86 }, { 0x48,0x32,0x2b,0xed },
- { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 },
+ { 0xac,0x1e,0x11,0x70 }, { 0x4e,0x6c,0x5a,0x72 },
{ 0xfb,0xfd,0x0e,0xff }, { 0x56,0x0f,0x85,0x38 },
- { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 },
+ { 0x1e,0x3d,0xae,0xd5 }, { 0x27,0x36,0x2d,0x39 },
{ 0x64,0x0a,0x0f,0xd9 }, { 0x21,0x68,0x5c,0xa6 },
- { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e },
+ { 0xd1,0x9b,0x5b,0x54 }, { 0x3a,0x24,0x36,0x2e },
{ 0xb1,0x0c,0x0a,0x67 }, { 0x0f,0x93,0x57,0xe7 },
- { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 },
- { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 },
- { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a },
+ { 0xd2,0xb4,0xee,0x96 }, { 0x9e,0x1b,0x9b,0x91 },
+ { 0x4f,0x80,0xc0,0xc5 }, { 0xa2,0x61,0xdc,0x20 },
+ { 0x69,0x5a,0x77,0x4b }, { 0x16,0x1c,0x12,0x1a },
{ 0x0a,0xe2,0x93,0xba }, { 0xe5,0xc0,0xa0,0x2a },
- { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 },
+ { 0x43,0x3c,0x22,0xe0 }, { 0x1d,0x12,0x1b,0x17 },
{ 0x0b,0x0e,0x09,0x0d }, { 0xad,0xf2,0x8b,0xc7 },
- { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 },
+ { 0xb9,0x2d,0xb6,0xa8 }, { 0xc8,0x14,0x1e,0xa9 },
{ 0x85,0x57,0xf1,0x19 }, { 0x4c,0xaf,0x75,0x07 },
- { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 },
+ { 0xbb,0xee,0x99,0xdd }, { 0xfd,0xa3,0x7f,0x60 },
{ 0x9f,0xf7,0x01,0x26 }, { 0xbc,0x5c,0x72,0xf5 },
- { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e },
+ { 0xc5,0x44,0x66,0x3b }, { 0x34,0x5b,0xfb,0x7e },
{ 0x76,0x8b,0x43,0x29 }, { 0xdc,0xcb,0x23,0xc6 },
- { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 },
+ { 0x68,0xb6,0xed,0xfc }, { 0x63,0xb8,0xe4,0xf1 },
{ 0xca,0xd7,0x31,0xdc }, { 0x10,0x42,0x63,0x85 },
- { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 },
+ { 0x40,0x13,0x97,0x22 }, { 0x20,0x84,0xc6,0x11 },
{ 0x7d,0x85,0x4a,0x24 }, { 0xf8,0xd2,0xbb,0x3d },
- { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 },
+ { 0x11,0xae,0xf9,0x32 }, { 0x6d,0xc7,0x29,0xa1 },
{ 0x4b,0x1d,0x9e,0x2f }, { 0xf3,0xdc,0xb2,0x30 },
- { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 },
- { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 },
- { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 },
- { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f },
- { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 },
+ { 0xec,0x0d,0x86,0x52 }, { 0xd0,0x77,0xc1,0xe3 },
+ { 0x6c,0x2b,0xb3,0x16 }, { 0x99,0xa9,0x70,0xb9 },
+ { 0xfa,0x11,0x94,0x48 }, { 0x22,0x47,0xe9,0x64 },
+ { 0xc4,0xa8,0xfc,0x8c }, { 0x1a,0xa0,0xf0,0x3f },
+ { 0xd8,0x56,0x7d,0x2c }, { 0xef,0x22,0x33,0x90 },
{ 0xc7,0x87,0x49,0x4e }, { 0xc1,0xd9,0x38,0xd1 },
- { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b },
- { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde },
- { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf },
- { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 },
- { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 },
- { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 },
- { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf },
+ { 0xfe,0x8c,0xca,0xa2 }, { 0x36,0x98,0xd4,0x0b },
+ { 0xcf,0xa6,0xf5,0x81 }, { 0x28,0xa5,0x7a,0xde },
+ { 0x26,0xda,0xb7,0x8e }, { 0xa4,0x3f,0xad,0xbf },
+ { 0xe4,0x2c,0x3a,0x9d }, { 0x0d,0x50,0x78,0x92 },
+ { 0x9b,0x6a,0x5f,0xcc }, { 0x62,0x54,0x7e,0x46 },
+ { 0xc2,0xf6,0x8d,0x13 }, { 0xe8,0x90,0xd8,0xb8 },
+ { 0x5e,0x2e,0x39,0xf7 }, { 0xf5,0x82,0xc3,0xaf },
{ 0xbe,0x9f,0x5d,0x80 }, { 0x7c,0x69,0xd0,0x93 },
- { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 },
- { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d },
- { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb },
+ { 0xa9,0x6f,0xd5,0x2d }, { 0xb3,0xcf,0x25,0x12 },
+ { 0x3b,0xc8,0xac,0x99 }, { 0xa7,0x10,0x18,0x7d },
+ { 0x6e,0xe8,0x9c,0x63 }, { 0x7b,0xdb,0x3b,0xbb },
{ 0x09,0xcd,0x26,0x78 }, { 0xf4,0x6e,0x59,0x18 },
- { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a },
- { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 },
- { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 },
+ { 0x01,0xec,0x9a,0xb7 }, { 0xa8,0x83,0x4f,0x9a },
+ { 0x65,0xe6,0x95,0x6e }, { 0x7e,0xaa,0xff,0xe6 },
+ { 0x08,0x21,0xbc,0xcf }, { 0xe6,0xef,0x15,0xe8 },
{ 0xd9,0xba,0xe7,0x9b }, { 0xce,0x4a,0x6f,0x36 },
- { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c },
+ { 0xd4,0xea,0x9f,0x09 }, { 0xd6,0x29,0xb0,0x7c },
{ 0xaf,0x31,0xa4,0xb2 }, { 0x31,0x2a,0x3f,0x23 },
- { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 },
- { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca },
- { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 },
+ { 0x30,0xc6,0xa5,0x94 }, { 0xc0,0x35,0xa2,0x66 },
+ { 0x37,0x74,0x4e,0xbc }, { 0xa6,0xfc,0x82,0xca },
+ { 0xb0,0xe0,0x90,0xd0 }, { 0x15,0x33,0xa7,0xd8 },
{ 0x4a,0xf1,0x04,0x98 }, { 0xf7,0x41,0xec,0xda },
- { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 },
+ { 0x0e,0x7f,0xcd,0x50 }, { 0x2f,0x17,0x91,0xf6 },
{ 0x8d,0x76,0x4d,0xd6 }, { 0x4d,0x43,0xef,0xb0 },
- { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 },
+ { 0x54,0xcc,0xaa,0x4d }, { 0xdf,0xe4,0x96,0x04 },
{ 0xe3,0x9e,0xd1,0xb5 }, { 0x1b,0x4c,0x6a,0x88 },
- { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 },
+ { 0xb8,0xc1,0x2c,0x1f }, { 0x7f,0x46,0x65,0x51 },
{ 0x04,0x9d,0x5e,0xea }, { 0x5d,0x01,0x8c,0x35 },
- { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 },
+ { 0x73,0xfa,0x87,0x74 }, { 0x2e,0xfb,0x0b,0x41 },
{ 0x5a,0xb3,0x67,0x1d }, { 0x52,0x92,0xdb,0xd2 },
- { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 },
- { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c },
- { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c },
+ { 0x33,0xe9,0x10,0x56 }, { 0x13,0x6d,0xd6,0x47 },
+ { 0x8c,0x9a,0xd7,0x61 }, { 0x7a,0x37,0xa1,0x0c },
+ { 0x8e,0x59,0xf8,0x14 }, { 0x89,0xeb,0x13,0x3c },
{ 0xee,0xce,0xa9,0x27 }, { 0x35,0xb7,0x61,0xc9 },
- { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 },
+ { 0xed,0xe1,0x1c,0xe5 }, { 0x3c,0x7a,0x47,0xb1 },
{ 0x59,0x9c,0xd2,0xdf }, { 0x3f,0x55,0xf2,0x73 },
- { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 },
+ { 0x79,0x18,0x14,0xce }, { 0xbf,0x73,0xc7,0x37 },
{ 0xea,0x53,0xf7,0xcd }, { 0x5b,0x5f,0xfd,0xaa },
- { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb },
+ { 0x14,0xdf,0x3d,0x6f }, { 0x86,0x78,0x44,0xdb },
{ 0x81,0xca,0xaf,0xf3 }, { 0x3e,0xb9,0x68,0xc4 },
- { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 },
+ { 0x2c,0x38,0x24,0x34 }, { 0x5f,0xc2,0xa3,0x40 },
{ 0x72,0x16,0x1d,0xc3 }, { 0x0c,0xbc,0xe2,0x25 },
- { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 },
+ { 0x8b,0x28,0x3c,0x49 }, { 0x41,0xff,0x0d,0x95 },
{ 0x71,0x39,0xa8,0x01 }, { 0xde,0x08,0x0c,0xb3 },
- { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 },
+ { 0x9c,0xd8,0xb4,0xe4 }, { 0x90,0x64,0x56,0xc1 },
{ 0x61,0x7b,0xcb,0x84 }, { 0x70,0xd5,0x32,0xb6 },
{ 0x74,0x48,0x6c,0x5c }, { 0x42,0xd0,0xb8,0x57 }
};
-static const unsigned char T7[256][4] =
+static const unsigned char T7[256][4] =
{
{ 0xa7,0x50,0x51,0xf4 }, { 0x65,0x53,0x7e,0x41 },
- { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 },
+ { 0xa4,0xc3,0x1a,0x17 }, { 0x5e,0x96,0x3a,0x27 },
{ 0x6b,0xcb,0x3b,0xab }, { 0x45,0xf1,0x1f,0x9d },
- { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 },
+ { 0x58,0xab,0xac,0xfa }, { 0x03,0x93,0x4b,0xe3 },
{ 0xfa,0x55,0x20,0x30 }, { 0x6d,0xf6,0xad,0x76 },
- { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 },
+ { 0x76,0x91,0x88,0xcc }, { 0x4c,0x25,0xf5,0x02 },
{ 0xd7,0xfc,0x4f,0xe5 }, { 0xcb,0xd7,0xc5,0x2a },
- { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 },
- { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba },
- { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe },
+ { 0x44,0x80,0x26,0x35 }, { 0xa3,0x8f,0xb5,0x62 },
+ { 0x5a,0x49,0xde,0xb1 }, { 0x1b,0x67,0x25,0xba },
+ { 0x0e,0x98,0x45,0xea }, { 0xc0,0xe1,0x5d,0xfe },
{ 0x75,0x02,0xc3,0x2f }, { 0xf0,0x12,0x81,0x4c },
- { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 },
+ { 0x97,0xa3,0x8d,0x46 }, { 0xf9,0xc6,0x6b,0xd3 },
{ 0x5f,0xe7,0x03,0x8f }, { 0x9c,0x95,0x15,0x92 },
- { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 },
+ { 0x7a,0xeb,0xbf,0x6d }, { 0x59,0xda,0x95,0x52 },
{ 0x83,0x2d,0xd4,0xbe }, { 0x21,0xd3,0x58,0x74 },
- { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 },
- { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e },
- { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 },
+ { 0x69,0x29,0x49,0xe0 }, { 0xc8,0x44,0x8e,0xc9 },
+ { 0x89,0x6a,0x75,0xc2 }, { 0x79,0x78,0xf4,0x8e },
+ { 0x3e,0x6b,0x99,0x58 }, { 0x71,0xdd,0x27,0xb9 },
{ 0x4f,0xb6,0xbe,0xe1 }, { 0xad,0x17,0xf0,0x88 },
- { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce },
+ { 0xac,0x66,0xc9,0x20 }, { 0x3a,0xb4,0x7d,0xce },
{ 0x4a,0x18,0x63,0xdf }, { 0x31,0x82,0xe5,0x1a },
- { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 },
+ { 0x33,0x60,0x97,0x51 }, { 0x7f,0x45,0x62,0x53 },
{ 0x77,0xe0,0xb1,0x64 }, { 0xae,0x84,0xbb,0x6b },
- { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 },
+ { 0xa0,0x1c,0xfe,0x81 }, { 0x2b,0x94,0xf9,0x08 },
{ 0x68,0x58,0x70,0x48 }, { 0xfd,0x19,0x8f,0x45 },
- { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b },
+ { 0x6c,0x87,0x94,0xde }, { 0xf8,0xb7,0x52,0x7b },
{ 0xd3,0x23,0xab,0x73 }, { 0x02,0xe2,0x72,0x4b },
- { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 },
+ { 0x8f,0x57,0xe3,0x1f }, { 0xab,0x2a,0x66,0x55 },
{ 0x28,0x07,0xb2,0xeb }, { 0xc2,0x03,0x2f,0xb5 },
- { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 },
+ { 0x7b,0x9a,0x86,0xc5 }, { 0x08,0xa5,0xd3,0x37 },
{ 0x87,0xf2,0x30,0x28 }, { 0xa5,0xb2,0x23,0xbf },
- { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 },
- { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 },
- { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 },
+ { 0x6a,0xba,0x02,0x03 }, { 0x82,0x5c,0xed,0x16 },
+ { 0x1c,0x2b,0x8a,0xcf }, { 0xb4,0x92,0xa7,0x79 },
+ { 0xf2,0xf0,0xf3,0x07 }, { 0xe2,0xa1,0x4e,0x69 },
{ 0xf4,0xcd,0x65,0xda }, { 0xbe,0xd5,0x06,0x05 },
- { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 },
+ { 0x62,0x1f,0xd1,0x34 }, { 0xfe,0x8a,0xc4,0xa6 },
{ 0x53,0x9d,0x34,0x2e }, { 0x55,0xa0,0xa2,0xf3 },
- { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 },
+ { 0xe1,0x32,0x05,0x8a }, { 0xeb,0x75,0xa4,0xf6 },
{ 0xec,0x39,0x0b,0x83 }, { 0xef,0xaa,0x40,0x60 },
- { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e },
+ { 0x9f,0x06,0x5e,0x71 }, { 0x10,0x51,0xbd,0x6e },
{ 0x8a,0xf9,0x3e,0x21 }, { 0x06,0x3d,0x96,0xdd },
- { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 },
+ { 0x05,0xae,0xdd,0x3e }, { 0xbd,0x46,0x4d,0xe6 },
{ 0x8d,0xb5,0x91,0x54 }, { 0x5d,0x05,0x71,0xc4 },
- { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 },
- { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd },
- { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 },
+ { 0xd4,0x6f,0x04,0x06 }, { 0x15,0xff,0x60,0x50 },
+ { 0xfb,0x24,0x19,0x98 }, { 0xe9,0x97,0xd6,0xbd },
+ { 0x43,0xcc,0x89,0x40 }, { 0x9e,0x77,0x67,0xd9 },
{ 0x42,0xbd,0xb0,0xe8 }, { 0x8b,0x88,0x07,0x89 },
- { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 },
+ { 0x5b,0x38,0xe7,0x19 }, { 0xee,0xdb,0x79,0xc8 },
{ 0x0a,0x47,0xa1,0x7c }, { 0x0f,0xe9,0x7c,0x42 },
- { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 },
+ { 0x1e,0xc9,0xf8,0x84 }, { 0x00,0x00,0x00,0x00 },
{ 0x86,0x83,0x09,0x80 }, { 0xed,0x48,0x32,0x2b },
- { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a },
+ { 0x70,0xac,0x1e,0x11 }, { 0x72,0x4e,0x6c,0x5a },
{ 0xff,0xfb,0xfd,0x0e }, { 0x38,0x56,0x0f,0x85 },
- { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d },
+ { 0xd5,0x1e,0x3d,0xae }, { 0x39,0x27,0x36,0x2d },
{ 0xd9,0x64,0x0a,0x0f }, { 0xa6,0x21,0x68,0x5c },
- { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 },
+ { 0x54,0xd1,0x9b,0x5b }, { 0x2e,0x3a,0x24,0x36 },
{ 0x67,0xb1,0x0c,0x0a }, { 0xe7,0x0f,0x93,0x57 },
- { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b },
+ { 0x96,0xd2,0xb4,0xee }, { 0x91,0x9e,0x1b,0x9b },
{ 0xc5,0x4f,0x80,0xc0 }, { 0x20,0xa2,0x61,0xdc },
- { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 },
+ { 0x4b,0x69,0x5a,0x77 }, { 0x1a,0x16,0x1c,0x12 },
{ 0xba,0x0a,0xe2,0x93 }, { 0x2a,0xe5,0xc0,0xa0 },
- { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b },
+ { 0xe0,0x43,0x3c,0x22 }, { 0x17,0x1d,0x12,0x1b },
{ 0x0d,0x0b,0x0e,0x09 }, { 0xc7,0xad,0xf2,0x8b },
- { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e },
+ { 0xa8,0xb9,0x2d,0xb6 }, { 0xa9,0xc8,0x14,0x1e },
{ 0x19,0x85,0x57,0xf1 }, { 0x07,0x4c,0xaf,0x75 },
- { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f },
+ { 0xdd,0xbb,0xee,0x99 }, { 0x60,0xfd,0xa3,0x7f },
{ 0x26,0x9f,0xf7,0x01 }, { 0xf5,0xbc,0x5c,0x72 },
- { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb },
+ { 0x3b,0xc5,0x44,0x66 }, { 0x7e,0x34,0x5b,0xfb },
{ 0x29,0x76,0x8b,0x43 }, { 0xc6,0xdc,0xcb,0x23 },
- { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 },
+ { 0xfc,0x68,0xb6,0xed }, { 0xf1,0x63,0xb8,0xe4 },
{ 0xdc,0xca,0xd7,0x31 }, { 0x85,0x10,0x42,0x63 },
- { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 },
+ { 0x22,0x40,0x13,0x97 }, { 0x11,0x20,0x84,0xc6 },
{ 0x24,0x7d,0x85,0x4a }, { 0x3d,0xf8,0xd2,0xbb },
- { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 },
+ { 0x32,0x11,0xae,0xf9 }, { 0xa1,0x6d,0xc7,0x29 },
{ 0x2f,0x4b,0x1d,0x9e }, { 0x30,0xf3,0xdc,0xb2 },
- { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 },
+ { 0x52,0xec,0x0d,0x86 }, { 0xe3,0xd0,0x77,0xc1 },
{ 0x16,0x6c,0x2b,0xb3 }, { 0xb9,0x99,0xa9,0x70 },
- { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 },
+ { 0x48,0xfa,0x11,0x94 }, { 0x64,0x22,0x47,0xe9 },
{ 0x8c,0xc4,0xa8,0xfc }, { 0x3f,0x1a,0xa0,0xf0 },
- { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 },
+ { 0x2c,0xd8,0x56,0x7d }, { 0x90,0xef,0x22,0x33 },
{ 0x4e,0xc7,0x87,0x49 }, { 0xd1,0xc1,0xd9,0x38 },
- { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 },
+ { 0xa2,0xfe,0x8c,0xca }, { 0x0b,0x36,0x98,0xd4 },
{ 0x81,0xcf,0xa6,0xf5 }, { 0xde,0x28,0xa5,0x7a },
- { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad },
+ { 0x8e,0x26,0xda,0xb7 }, { 0xbf,0xa4,0x3f,0xad },
{ 0x9d,0xe4,0x2c,0x3a }, { 0x92,0x0d,0x50,0x78 },
- { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e },
+ { 0xcc,0x9b,0x6a,0x5f }, { 0x46,0x62,0x54,0x7e },
{ 0x13,0xc2,0xf6,0x8d }, { 0xb8,0xe8,0x90,0xd8 },
- { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 },
+ { 0xf7,0x5e,0x2e,0x39 }, { 0xaf,0xf5,0x82,0xc3 },
{ 0x80,0xbe,0x9f,0x5d }, { 0x93,0x7c,0x69,0xd0 },
- { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 },
+ { 0x2d,0xa9,0x6f,0xd5 }, { 0x12,0xb3,0xcf,0x25 },
{ 0x99,0x3b,0xc8,0xac }, { 0x7d,0xa7,0x10,0x18 },
- { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b },
- { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 },
- { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f },
+ { 0x63,0x6e,0xe8,0x9c }, { 0xbb,0x7b,0xdb,0x3b },
+ { 0x78,0x09,0xcd,0x26 }, { 0x18,0xf4,0x6e,0x59 },
+ { 0xb7,0x01,0xec,0x9a }, { 0x9a,0xa8,0x83,0x4f },
{ 0x6e,0x65,0xe6,0x95 }, { 0xe6,0x7e,0xaa,0xff },
- { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 },
+ { 0xcf,0x08,0x21,0xbc }, { 0xe8,0xe6,0xef,0x15 },
{ 0x9b,0xd9,0xba,0xe7 }, { 0x36,0xce,0x4a,0x6f },
- { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 },
+ { 0x09,0xd4,0xea,0x9f }, { 0x7c,0xd6,0x29,0xb0 },
{ 0xb2,0xaf,0x31,0xa4 }, { 0x23,0x31,0x2a,0x3f },
- { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 },
+ { 0x94,0x30,0xc6,0xa5 }, { 0x66,0xc0,0x35,0xa2 },
{ 0xbc,0x37,0x74,0x4e }, { 0xca,0xa6,0xfc,0x82 },
- { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 },
+ { 0xd0,0xb0,0xe0,0x90 }, { 0xd8,0x15,0x33,0xa7 },
{ 0x98,0x4a,0xf1,0x04 }, { 0xda,0xf7,0x41,0xec },
- { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 },
- { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef },
- { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 },
+ { 0x50,0x0e,0x7f,0xcd }, { 0xf6,0x2f,0x17,0x91 },
+ { 0xd6,0x8d,0x76,0x4d }, { 0xb0,0x4d,0x43,0xef },
+ { 0x4d,0x54,0xcc,0xaa }, { 0x04,0xdf,0xe4,0x96 },
{ 0xb5,0xe3,0x9e,0xd1 }, { 0x88,0x1b,0x4c,0x6a },
- { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 },
+ { 0x1f,0xb8,0xc1,0x2c }, { 0x51,0x7f,0x46,0x65 },
{ 0xea,0x04,0x9d,0x5e }, { 0x35,0x5d,0x01,0x8c },
- { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b },
+ { 0x74,0x73,0xfa,0x87 }, { 0x41,0x2e,0xfb,0x0b },
{ 0x1d,0x5a,0xb3,0x67 }, { 0xd2,0x52,0x92,0xdb },
- { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 },
+ { 0x56,0x33,0xe9,0x10 }, { 0x47,0x13,0x6d,0xd6 },
{ 0x61,0x8c,0x9a,0xd7 }, { 0x0c,0x7a,0x37,0xa1 },
- { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 },
+ { 0x14,0x8e,0x59,0xf8 }, { 0x3c,0x89,0xeb,0x13 },
{ 0x27,0xee,0xce,0xa9 }, { 0xc9,0x35,0xb7,0x61 },
- { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 },
+ { 0xe5,0xed,0xe1,0x1c }, { 0xb1,0x3c,0x7a,0x47 },
{ 0xdf,0x59,0x9c,0xd2 }, { 0x73,0x3f,0x55,0xf2 },
- { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 },
+ { 0xce,0x79,0x18,0x14 }, { 0x37,0xbf,0x73,0xc7 },
{ 0xcd,0xea,0x53,0xf7 }, { 0xaa,0x5b,0x5f,0xfd },
- { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 },
+ { 0x6f,0x14,0xdf,0x3d }, { 0xdb,0x86,0x78,0x44 },
{ 0xf3,0x81,0xca,0xaf }, { 0xc4,0x3e,0xb9,0x68 },
- { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 },
+ { 0x34,0x2c,0x38,0x24 }, { 0x40,0x5f,0xc2,0xa3 },
{ 0xc3,0x72,0x16,0x1d }, { 0x25,0x0c,0xbc,0xe2 },
- { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d },
+ { 0x49,0x8b,0x28,0x3c }, { 0x95,0x41,0xff,0x0d },
{ 0x01,0x71,0x39,0xa8 }, { 0xb3,0xde,0x08,0x0c },
- { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 },
+ { 0xe4,0x9c,0xd8,0xb4 }, { 0xc1,0x90,0x64,0x56 },
{ 0x84,0x61,0x7b,0xcb }, { 0xb6,0x70,0xd5,0x32 },
{ 0x5c,0x74,0x48,0x6c }, { 0x57,0x42,0xd0,0xb8 }
};
-static const unsigned char T8[256][4] =
+static const unsigned char T8[256][4] =
{
{ 0xf4,0xa7,0x50,0x51 }, { 0x41,0x65,0x53,0x7e },
- { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a },
+ { 0x17,0xa4,0xc3,0x1a }, { 0x27,0x5e,0x96,0x3a },
{ 0xab,0x6b,0xcb,0x3b }, { 0x9d,0x45,0xf1,0x1f },
- { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b },
+ { 0xfa,0x58,0xab,0xac }, { 0xe3,0x03,0x93,0x4b },
{ 0x30,0xfa,0x55,0x20 }, { 0x76,0x6d,0xf6,0xad },
- { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 },
+ { 0xcc,0x76,0x91,0x88 }, { 0x02,0x4c,0x25,0xf5 },
{ 0xe5,0xd7,0xfc,0x4f }, { 0x2a,0xcb,0xd7,0xc5 },
- { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 },
+ { 0x35,0x44,0x80,0x26 }, { 0x62,0xa3,0x8f,0xb5 },
{ 0xb1,0x5a,0x49,0xde }, { 0xba,0x1b,0x67,0x25 },
- { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d },
+ { 0xea,0x0e,0x98,0x45 }, { 0xfe,0xc0,0xe1,0x5d },
{ 0x2f,0x75,0x02,0xc3 }, { 0x4c,0xf0,0x12,0x81 },
- { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b },
+ { 0x46,0x97,0xa3,0x8d }, { 0xd3,0xf9,0xc6,0x6b },
{ 0x8f,0x5f,0xe7,0x03 }, { 0x92,0x9c,0x95,0x15 },
- { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 },
+ { 0x6d,0x7a,0xeb,0xbf }, { 0x52,0x59,0xda,0x95 },
{ 0xbe,0x83,0x2d,0xd4 }, { 0x74,0x21,0xd3,0x58 },
- { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e },
+ { 0xe0,0x69,0x29,0x49 }, { 0xc9,0xc8,0x44,0x8e },
{ 0xc2,0x89,0x6a,0x75 }, { 0x8e,0x79,0x78,0xf4 },
- { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 },
+ { 0x58,0x3e,0x6b,0x99 }, { 0xb9,0x71,0xdd,0x27 },
{ 0xe1,0x4f,0xb6,0xbe }, { 0x88,0xad,0x17,0xf0 },
- { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d },
+ { 0x20,0xac,0x66,0xc9 }, { 0xce,0x3a,0xb4,0x7d },
{ 0xdf,0x4a,0x18,0x63 }, { 0x1a,0x31,0x82,0xe5 },
- { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 },
+ { 0x51,0x33,0x60,0x97 }, { 0x53,0x7f,0x45,0x62 },
{ 0x64,0x77,0xe0,0xb1 }, { 0x6b,0xae,0x84,0xbb },
- { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 },
+ { 0x81,0xa0,0x1c,0xfe }, { 0x08,0x2b,0x94,0xf9 },
{ 0x48,0x68,0x58,0x70 }, { 0x45,0xfd,0x19,0x8f },
- { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 },
+ { 0xde,0x6c,0x87,0x94 }, { 0x7b,0xf8,0xb7,0x52 },
{ 0x73,0xd3,0x23,0xab }, { 0x4b,0x02,0xe2,0x72 },
- { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 },
+ { 0x1f,0x8f,0x57,0xe3 }, { 0x55,0xab,0x2a,0x66 },
{ 0xeb,0x28,0x07,0xb2 }, { 0xb5,0xc2,0x03,0x2f },
- { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 },
+ { 0xc5,0x7b,0x9a,0x86 }, { 0x37,0x08,0xa5,0xd3 },
{ 0x28,0x87,0xf2,0x30 }, { 0xbf,0xa5,0xb2,0x23 },
- { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed },
+ { 0x03,0x6a,0xba,0x02 }, { 0x16,0x82,0x5c,0xed },
{ 0xcf,0x1c,0x2b,0x8a }, { 0x79,0xb4,0x92,0xa7 },
- { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e },
+ { 0x07,0xf2,0xf0,0xf3 }, { 0x69,0xe2,0xa1,0x4e },
{ 0xda,0xf4,0xcd,0x65 }, { 0x05,0xbe,0xd5,0x06 },
- { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 },
+ { 0x34,0x62,0x1f,0xd1 }, { 0xa6,0xfe,0x8a,0xc4 },
{ 0x2e,0x53,0x9d,0x34 }, { 0xf3,0x55,0xa0,0xa2 },
- { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 },
+ { 0x8a,0xe1,0x32,0x05 }, { 0xf6,0xeb,0x75,0xa4 },
{ 0x83,0xec,0x39,0x0b }, { 0x60,0xef,0xaa,0x40 },
- { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd },
+ { 0x71,0x9f,0x06,0x5e }, { 0x6e,0x10,0x51,0xbd },
{ 0x21,0x8a,0xf9,0x3e }, { 0xdd,0x06,0x3d,0x96 },
- { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d },
+ { 0x3e,0x05,0xae,0xdd }, { 0xe6,0xbd,0x46,0x4d },
{ 0x54,0x8d,0xb5,0x91 }, { 0xc4,0x5d,0x05,0x71 },
- { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 },
+ { 0x06,0xd4,0x6f,0x04 }, { 0x50,0x15,0xff,0x60 },
{ 0x98,0xfb,0x24,0x19 }, { 0xbd,0xe9,0x97,0xd6 },
- { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 },
+ { 0x40,0x43,0xcc,0x89 }, { 0xd9,0x9e,0x77,0x67 },
{ 0xe8,0x42,0xbd,0xb0 }, { 0x89,0x8b,0x88,0x07 },
- { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 },
+ { 0x19,0x5b,0x38,0xe7 }, { 0xc8,0xee,0xdb,0x79 },
{ 0x7c,0x0a,0x47,0xa1 }, { 0x42,0x0f,0xe9,0x7c },
- { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 },
+ { 0x84,0x1e,0xc9,0xf8 }, { 0x00,0x00,0x00,0x00 },
{ 0x80,0x86,0x83,0x09 }, { 0x2b,0xed,0x48,0x32 },
- { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c },
- { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f },
- { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 },
+ { 0x11,0x70,0xac,0x1e }, { 0x5a,0x72,0x4e,0x6c },
+ { 0x0e,0xff,0xfb,0xfd }, { 0x85,0x38,0x56,0x0f },
+ { 0xae,0xd5,0x1e,0x3d }, { 0x2d,0x39,0x27,0x36 },
{ 0x0f,0xd9,0x64,0x0a }, { 0x5c,0xa6,0x21,0x68 },
- { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 },
+ { 0x5b,0x54,0xd1,0x9b }, { 0x36,0x2e,0x3a,0x24 },
{ 0x0a,0x67,0xb1,0x0c }, { 0x57,0xe7,0x0f,0x93 },
- { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b },
+ { 0xee,0x96,0xd2,0xb4 }, { 0x9b,0x91,0x9e,0x1b },
{ 0xc0,0xc5,0x4f,0x80 }, { 0xdc,0x20,0xa2,0x61 },
- { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c },
+ { 0x77,0x4b,0x69,0x5a }, { 0x12,0x1a,0x16,0x1c },
{ 0x93,0xba,0x0a,0xe2 }, { 0xa0,0x2a,0xe5,0xc0 },
- { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 },
+ { 0x22,0xe0,0x43,0x3c }, { 0x1b,0x17,0x1d,0x12 },
{ 0x09,0x0d,0x0b,0x0e }, { 0x8b,0xc7,0xad,0xf2 },
- { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 },
+ { 0xb6,0xa8,0xb9,0x2d }, { 0x1e,0xa9,0xc8,0x14 },
{ 0xf1,0x19,0x85,0x57 }, { 0x75,0x07,0x4c,0xaf },
- { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 },
+ { 0x99,0xdd,0xbb,0xee }, { 0x7f,0x60,0xfd,0xa3 },
{ 0x01,0x26,0x9f,0xf7 }, { 0x72,0xf5,0xbc,0x5c },
- { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b },
+ { 0x66,0x3b,0xc5,0x44 }, { 0xfb,0x7e,0x34,0x5b },
{ 0x43,0x29,0x76,0x8b }, { 0x23,0xc6,0xdc,0xcb },
- { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 },
+ { 0xed,0xfc,0x68,0xb6 }, { 0xe4,0xf1,0x63,0xb8 },
{ 0x31,0xdc,0xca,0xd7 }, { 0x63,0x85,0x10,0x42 },
- { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 },
- { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 },
- { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 },
+ { 0x97,0x22,0x40,0x13 }, { 0xc6,0x11,0x20,0x84 },
+ { 0x4a,0x24,0x7d,0x85 }, { 0xbb,0x3d,0xf8,0xd2 },
+ { 0xf9,0x32,0x11,0xae }, { 0x29,0xa1,0x6d,0xc7 },
{ 0x9e,0x2f,0x4b,0x1d }, { 0xb2,0x30,0xf3,0xdc },
- { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 },
+ { 0x86,0x52,0xec,0x0d }, { 0xc1,0xe3,0xd0,0x77 },
{ 0xb3,0x16,0x6c,0x2b }, { 0x70,0xb9,0x99,0xa9 },
- { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 },
+ { 0x94,0x48,0xfa,0x11 }, { 0xe9,0x64,0x22,0x47 },
{ 0xfc,0x8c,0xc4,0xa8 }, { 0xf0,0x3f,0x1a,0xa0 },
- { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 },
+ { 0x7d,0x2c,0xd8,0x56 }, { 0x33,0x90,0xef,0x22 },
{ 0x49,0x4e,0xc7,0x87 }, { 0x38,0xd1,0xc1,0xd9 },
- { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 },
+ { 0xca,0xa2,0xfe,0x8c }, { 0xd4,0x0b,0x36,0x98 },
{ 0xf5,0x81,0xcf,0xa6 }, { 0x7a,0xde,0x28,0xa5 },
- { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f },
+ { 0xb7,0x8e,0x26,0xda }, { 0xad,0xbf,0xa4,0x3f },
{ 0x3a,0x9d,0xe4,0x2c }, { 0x78,0x92,0x0d,0x50 },
- { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 },
+ { 0x5f,0xcc,0x9b,0x6a }, { 0x7e,0x46,0x62,0x54 },
{ 0x8d,0x13,0xc2,0xf6 }, { 0xd8,0xb8,0xe8,0x90 },
- { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 },
+ { 0x39,0xf7,0x5e,0x2e }, { 0xc3,0xaf,0xf5,0x82 },
{ 0x5d,0x80,0xbe,0x9f }, { 0xd0,0x93,0x7c,0x69 },
- { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf },
+ { 0xd5,0x2d,0xa9,0x6f }, { 0x25,0x12,0xb3,0xcf },
{ 0xac,0x99,0x3b,0xc8 }, { 0x18,0x7d,0xa7,0x10 },
- { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb },
+ { 0x9c,0x63,0x6e,0xe8 }, { 0x3b,0xbb,0x7b,0xdb },
{ 0x26,0x78,0x09,0xcd }, { 0x59,0x18,0xf4,0x6e },
- { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 },
+ { 0x9a,0xb7,0x01,0xec }, { 0x4f,0x9a,0xa8,0x83 },
{ 0x95,0x6e,0x65,0xe6 }, { 0xff,0xe6,0x7e,0xaa },
- { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef },
+ { 0xbc,0xcf,0x08,0x21 }, { 0x15,0xe8,0xe6,0xef },
{ 0xe7,0x9b,0xd9,0xba }, { 0x6f,0x36,0xce,0x4a },
- { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 },
+ { 0x9f,0x09,0xd4,0xea }, { 0xb0,0x7c,0xd6,0x29 },
{ 0xa4,0xb2,0xaf,0x31 }, { 0x3f,0x23,0x31,0x2a },
- { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 },
+ { 0xa5,0x94,0x30,0xc6 }, { 0xa2,0x66,0xc0,0x35 },
{ 0x4e,0xbc,0x37,0x74 }, { 0x82,0xca,0xa6,0xfc },
- { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 },
+ { 0x90,0xd0,0xb0,0xe0 }, { 0xa7,0xd8,0x15,0x33 },
{ 0x04,0x98,0x4a,0xf1 }, { 0xec,0xda,0xf7,0x41 },
- { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 },
- { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 },
- { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 },
+ { 0xcd,0x50,0x0e,0x7f }, { 0x91,0xf6,0x2f,0x17 },
+ { 0x4d,0xd6,0x8d,0x76 }, { 0xef,0xb0,0x4d,0x43 },
+ { 0xaa,0x4d,0x54,0xcc }, { 0x96,0x04,0xdf,0xe4 },
{ 0xd1,0xb5,0xe3,0x9e }, { 0x6a,0x88,0x1b,0x4c },
- { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 },
+ { 0x2c,0x1f,0xb8,0xc1 }, { 0x65,0x51,0x7f,0x46 },
{ 0x5e,0xea,0x04,0x9d }, { 0x8c,0x35,0x5d,0x01 },
- { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb },
+ { 0x87,0x74,0x73,0xfa }, { 0x0b,0x41,0x2e,0xfb },
{ 0x67,0x1d,0x5a,0xb3 }, { 0xdb,0xd2,0x52,0x92 },
- { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d },
+ { 0x10,0x56,0x33,0xe9 }, { 0xd6,0x47,0x13,0x6d },
{ 0xd7,0x61,0x8c,0x9a }, { 0xa1,0x0c,0x7a,0x37 },
- { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb },
+ { 0xf8,0x14,0x8e,0x59 }, { 0x13,0x3c,0x89,0xeb },
{ 0xa9,0x27,0xee,0xce }, { 0x61,0xc9,0x35,0xb7 },
- { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a },
+ { 0x1c,0xe5,0xed,0xe1 }, { 0x47,0xb1,0x3c,0x7a },
{ 0xd2,0xdf,0x59,0x9c }, { 0xf2,0x73,0x3f,0x55 },
- { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 },
+ { 0x14,0xce,0x79,0x18 }, { 0xc7,0x37,0xbf,0x73 },
{ 0xf7,0xcd,0xea,0x53 }, { 0xfd,0xaa,0x5b,0x5f },
- { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 },
+ { 0x3d,0x6f,0x14,0xdf }, { 0x44,0xdb,0x86,0x78 },
{ 0xaf,0xf3,0x81,0xca }, { 0x68,0xc4,0x3e,0xb9 },
- { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 },
+ { 0x24,0x34,0x2c,0x38 }, { 0xa3,0x40,0x5f,0xc2 },
{ 0x1d,0xc3,0x72,0x16 }, { 0xe2,0x25,0x0c,0xbc },
- { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff },
+ { 0x3c,0x49,0x8b,0x28 }, { 0x0d,0x95,0x41,0xff },
{ 0xa8,0x01,0x71,0x39 }, { 0x0c,0xb3,0xde,0x08 },
- { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 },
+ { 0xb4,0xe4,0x9c,0xd8 }, { 0x56,0xc1,0x90,0x64 },
{ 0xcb,0x84,0x61,0x7b }, { 0x32,0xb6,0x70,0xd5 },
{ 0x6c,0x5c,0x74,0x48 }, { 0xb8,0x57,0x42,0xd0 }
};
-static const unsigned char S5[256] =
+static const unsigned char S5[256] =
{
0x52,0x09,0x6a,0xd5,0x30,0x36,0xa5,0x38,
0xbf,0x40,0xa3,0x9e,0x81,0xf3,0xd7,0xfb,
0xe1,0x69,0x14,0x63,0x55,0x21,0x0c,0x7d
};
-static const unsigned char U1[256][4] =
+static const unsigned char U1[256][4] =
{
{ 0x00,0x00,0x00,0x00 }, { 0x0e,0x09,0x0d,0x0b },
- { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d },
+ { 0x1c,0x12,0x1a,0x16 }, { 0x12,0x1b,0x17,0x1d },
{ 0x38,0x24,0x34,0x2c }, { 0x36,0x2d,0x39,0x27 },
- { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 },
+ { 0x24,0x36,0x2e,0x3a }, { 0x2a,0x3f,0x23,0x31 },
{ 0x70,0x48,0x68,0x58 }, { 0x7e,0x41,0x65,0x53 },
- { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 },
+ { 0x6c,0x5a,0x72,0x4e }, { 0x62,0x53,0x7f,0x45 },
{ 0x48,0x6c,0x5c,0x74 }, { 0x46,0x65,0x51,0x7f },
- { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 },
+ { 0x54,0x7e,0x46,0x62 }, { 0x5a,0x77,0x4b,0x69 },
{ 0xe0,0x90,0xd0,0xb0 }, { 0xee,0x99,0xdd,0xbb },
- { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad },
+ { 0xfc,0x82,0xca,0xa6 }, { 0xf2,0x8b,0xc7,0xad },
{ 0xd8,0xb4,0xe4,0x9c }, { 0xd6,0xbd,0xe9,0x97 },
- { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 },
+ { 0xc4,0xa6,0xfe,0x8a }, { 0xca,0xaf,0xf3,0x81 },
{ 0x90,0xd8,0xb8,0xe8 }, { 0x9e,0xd1,0xb5,0xe3 },
- { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 },
+ { 0x8c,0xca,0xa2,0xfe }, { 0x82,0xc3,0xaf,0xf5 },
{ 0xa8,0xfc,0x8c,0xc4 }, { 0xa6,0xf5,0x81,0xcf },
- { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 },
+ { 0xb4,0xee,0x96,0xd2 }, { 0xba,0xe7,0x9b,0xd9 },
{ 0xdb,0x3b,0xbb,0x7b }, { 0xd5,0x32,0xb6,0x70 },
- { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 },
+ { 0xc7,0x29,0xa1,0x6d }, { 0xc9,0x20,0xac,0x66 },
{ 0xe3,0x1f,0x8f,0x57 }, { 0xed,0x16,0x82,0x5c },
- { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a },
+ { 0xff,0x0d,0x95,0x41 }, { 0xf1,0x04,0x98,0x4a },
{ 0xab,0x73,0xd3,0x23 }, { 0xa5,0x7a,0xde,0x28 },
- { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e },
+ { 0xb7,0x61,0xc9,0x35 }, { 0xb9,0x68,0xc4,0x3e },
{ 0x93,0x57,0xe7,0x0f }, { 0x9d,0x5e,0xea,0x04 },
- { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 },
+ { 0x8f,0x45,0xfd,0x19 }, { 0x81,0x4c,0xf0,0x12 },
{ 0x3b,0xab,0x6b,0xcb }, { 0x35,0xa2,0x66,0xc0 },
- { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 },
+ { 0x27,0xb9,0x71,0xdd }, { 0x29,0xb0,0x7c,0xd6 },
{ 0x03,0x8f,0x5f,0xe7 }, { 0x0d,0x86,0x52,0xec },
- { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa },
+ { 0x1f,0x9d,0x45,0xf1 }, { 0x11,0x94,0x48,0xfa },
{ 0x4b,0xe3,0x03,0x93 }, { 0x45,0xea,0x0e,0x98 },
- { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e },
+ { 0x57,0xf1,0x19,0x85 }, { 0x59,0xf8,0x14,0x8e },
{ 0x73,0xc7,0x37,0xbf }, { 0x7d,0xce,0x3a,0xb4 },
- { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 },
+ { 0x6f,0xd5,0x2d,0xa9 }, { 0x61,0xdc,0x20,0xa2 },
{ 0xad,0x76,0x6d,0xf6 }, { 0xa3,0x7f,0x60,0xfd },
- { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb },
+ { 0xb1,0x64,0x77,0xe0 }, { 0xbf,0x6d,0x7a,0xeb },
{ 0x95,0x52,0x59,0xda }, { 0x9b,0x5b,0x54,0xd1 },
- { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 },
+ { 0x89,0x40,0x43,0xcc }, { 0x87,0x49,0x4e,0xc7 },
{ 0xdd,0x3e,0x05,0xae }, { 0xd3,0x37,0x08,0xa5 },
- { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 },
+ { 0xc1,0x2c,0x1f,0xb8 }, { 0xcf,0x25,0x12,0xb3 },
{ 0xe5,0x1a,0x31,0x82 }, { 0xeb,0x13,0x3c,0x89 },
- { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f },
+ { 0xf9,0x08,0x2b,0x94 }, { 0xf7,0x01,0x26,0x9f },
{ 0x4d,0xe6,0xbd,0x46 }, { 0x43,0xef,0xb0,0x4d },
- { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b },
+ { 0x51,0xf4,0xa7,0x50 }, { 0x5f,0xfd,0xaa,0x5b },
{ 0x75,0xc2,0x89,0x6a }, { 0x7b,0xcb,0x84,0x61 },
- { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 },
+ { 0x69,0xd0,0x93,0x7c }, { 0x67,0xd9,0x9e,0x77 },
{ 0x3d,0xae,0xd5,0x1e }, { 0x33,0xa7,0xd8,0x15 },
- { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 },
+ { 0x21,0xbc,0xcf,0x08 }, { 0x2f,0xb5,0xc2,0x03 },
{ 0x05,0x8a,0xe1,0x32 }, { 0x0b,0x83,0xec,0x39 },
- { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f },
+ { 0x19,0x98,0xfb,0x24 }, { 0x17,0x91,0xf6,0x2f },
{ 0x76,0x4d,0xd6,0x8d }, { 0x78,0x44,0xdb,0x86 },
- { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 },
+ { 0x6a,0x5f,0xcc,0x9b }, { 0x64,0x56,0xc1,0x90 },
{ 0x4e,0x69,0xe2,0xa1 }, { 0x40,0x60,0xef,0xaa },
- { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc },
+ { 0x52,0x7b,0xf8,0xb7 }, { 0x5c,0x72,0xf5,0xbc },
{ 0x06,0x05,0xbe,0xd5 }, { 0x08,0x0c,0xb3,0xde },
- { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 },
+ { 0x1a,0x17,0xa4,0xc3 }, { 0x14,0x1e,0xa9,0xc8 },
{ 0x3e,0x21,0x8a,0xf9 }, { 0x30,0x28,0x87,0xf2 },
- { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 },
+ { 0x22,0x33,0x90,0xef }, { 0x2c,0x3a,0x9d,0xe4 },
{ 0x96,0xdd,0x06,0x3d }, { 0x98,0xd4,0x0b,0x36 },
- { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 },
+ { 0x8a,0xcf,0x1c,0x2b }, { 0x84,0xc6,0x11,0x20 },
{ 0xae,0xf9,0x32,0x11 }, { 0xa0,0xf0,0x3f,0x1a },
- { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c },
+ { 0xb2,0xeb,0x28,0x07 }, { 0xbc,0xe2,0x25,0x0c },
{ 0xe6,0x95,0x6e,0x65 }, { 0xe8,0x9c,0x63,0x6e },
- { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 },
+ { 0xfa,0x87,0x74,0x73 }, { 0xf4,0x8e,0x79,0x78 },
{ 0xde,0xb1,0x5a,0x49 }, { 0xd0,0xb8,0x57,0x42 },
- { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 },
+ { 0xc2,0xa3,0x40,0x5f }, { 0xcc,0xaa,0x4d,0x54 },
{ 0x41,0xec,0xda,0xf7 }, { 0x4f,0xe5,0xd7,0xfc },
- { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea },
+ { 0x5d,0xfe,0xc0,0xe1 }, { 0x53,0xf7,0xcd,0xea },
{ 0x79,0xc8,0xee,0xdb }, { 0x77,0xc1,0xe3,0xd0 },
- { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 },
+ { 0x65,0xda,0xf4,0xcd }, { 0x6b,0xd3,0xf9,0xc6 },
{ 0x31,0xa4,0xb2,0xaf }, { 0x3f,0xad,0xbf,0xa4 },
- { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 },
+ { 0x2d,0xb6,0xa8,0xb9 }, { 0x23,0xbf,0xa5,0xb2 },
{ 0x09,0x80,0x86,0x83 }, { 0x07,0x89,0x8b,0x88 },
- { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e },
+ { 0x15,0x92,0x9c,0x95 }, { 0x1b,0x9b,0x91,0x9e },
{ 0xa1,0x7c,0x0a,0x47 }, { 0xaf,0x75,0x07,0x4c },
- { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a },
+ { 0xbd,0x6e,0x10,0x51 }, { 0xb3,0x67,0x1d,0x5a },
{ 0x99,0x58,0x3e,0x6b }, { 0x97,0x51,0x33,0x60 },
- { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 },
+ { 0x85,0x4a,0x24,0x7d }, { 0x8b,0x43,0x29,0x76 },
{ 0xd1,0x34,0x62,0x1f }, { 0xdf,0x3d,0x6f,0x14 },
- { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 },
+ { 0xcd,0x26,0x78,0x09 }, { 0xc3,0x2f,0x75,0x02 },
{ 0xe9,0x10,0x56,0x33 }, { 0xe7,0x19,0x5b,0x38 },
- { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e },
- { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 },
- { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 },
+ { 0xf5,0x02,0x4c,0x25 }, { 0xfb,0x0b,0x41,0x2e },
+ { 0x9a,0xd7,0x61,0x8c }, { 0x94,0xde,0x6c,0x87 },
+ { 0x86,0xc5,0x7b,0x9a }, { 0x88,0xcc,0x76,0x91 },
{ 0xa2,0xf3,0x55,0xa0 }, { 0xac,0xfa,0x58,0xab },
- { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd },
+ { 0xbe,0xe1,0x4f,0xb6 }, { 0xb0,0xe8,0x42,0xbd },
{ 0xea,0x9f,0x09,0xd4 }, { 0xe4,0x96,0x04,0xdf },
- { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 },
+ { 0xf6,0x8d,0x13,0xc2 }, { 0xf8,0x84,0x1e,0xc9 },
{ 0xd2,0xbb,0x3d,0xf8 }, { 0xdc,0xb2,0x30,0xf3 },
- { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 },
- { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 },
- { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 },
+ { 0xce,0xa9,0x27,0xee }, { 0xc0,0xa0,0x2a,0xe5 },
+ { 0x7a,0x47,0xb1,0x3c }, { 0x74,0x4e,0xbc,0x37 },
+ { 0x66,0x55,0xab,0x2a }, { 0x68,0x5c,0xa6,0x21 },
{ 0x42,0x63,0x85,0x10 }, { 0x4c,0x6a,0x88,0x1b },
- { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d },
+ { 0x5e,0x71,0x9f,0x06 }, { 0x50,0x78,0x92,0x0d },
{ 0x0a,0x0f,0xd9,0x64 }, { 0x04,0x06,0xd4,0x6f },
- { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 },
+ { 0x16,0x1d,0xc3,0x72 }, { 0x18,0x14,0xce,0x79 },
{ 0x32,0x2b,0xed,0x48 }, { 0x3c,0x22,0xe0,0x43 },
- { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 },
+ { 0x2e,0x39,0xf7,0x5e }, { 0x20,0x30,0xfa,0x55 },
{ 0xec,0x9a,0xb7,0x01 }, { 0xe2,0x93,0xba,0x0a },
- { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c },
+ { 0xf0,0x88,0xad,0x17 }, { 0xfe,0x81,0xa0,0x1c },
{ 0xd4,0xbe,0x83,0x2d }, { 0xda,0xb7,0x8e,0x26 },
- { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 },
+ { 0xc8,0xac,0x99,0x3b }, { 0xc6,0xa5,0x94,0x30 },
{ 0x9c,0xd2,0xdf,0x59 }, { 0x92,0xdb,0xd2,0x52 },
- { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 },
+ { 0x80,0xc0,0xc5,0x4f }, { 0x8e,0xc9,0xc8,0x44 },
{ 0xa4,0xf6,0xeb,0x75 }, { 0xaa,0xff,0xe6,0x7e },
- { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 },
+ { 0xb8,0xe4,0xf1,0x63 }, { 0xb6,0xed,0xfc,0x68 },
{ 0x0c,0x0a,0x67,0xb1 }, { 0x02,0x03,0x6a,0xba },
- { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac },
+ { 0x10,0x18,0x7d,0xa7 }, { 0x1e,0x11,0x70,0xac },
{ 0x34,0x2e,0x53,0x9d }, { 0x3a,0x27,0x5e,0x96 },
- { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 },
+ { 0x28,0x3c,0x49,0x8b }, { 0x26,0x35,0x44,0x80 },
{ 0x7c,0x42,0x0f,0xe9 }, { 0x72,0x4b,0x02,0xe2 },
- { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 },
+ { 0x60,0x50,0x15,0xff }, { 0x6e,0x59,0x18,0xf4 },
{ 0x44,0x66,0x3b,0xc5 }, { 0x4a,0x6f,0x36,0xce },
- { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 },
+ { 0x58,0x74,0x21,0xd3 }, { 0x56,0x7d,0x2c,0xd8 },
{ 0x37,0xa1,0x0c,0x7a }, { 0x39,0xa8,0x01,0x71 },
- { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 },
+ { 0x2b,0xb3,0x16,0x6c }, { 0x25,0xba,0x1b,0x67 },
{ 0x0f,0x85,0x38,0x56 }, { 0x01,0x8c,0x35,0x5d },
- { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b },
+ { 0x13,0x97,0x22,0x40 }, { 0x1d,0x9e,0x2f,0x4b },
{ 0x47,0xe9,0x64,0x22 }, { 0x49,0xe0,0x69,0x29 },
- { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f },
+ { 0x5b,0xfb,0x7e,0x34 }, { 0x55,0xf2,0x73,0x3f },
{ 0x7f,0xcd,0x50,0x0e }, { 0x71,0xc4,0x5d,0x05 },
- { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 },
+ { 0x63,0xdf,0x4a,0x18 }, { 0x6d,0xd6,0x47,0x13 },
{ 0xd7,0x31,0xdc,0xca }, { 0xd9,0x38,0xd1,0xc1 },
- { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 },
+ { 0xcb,0x23,0xc6,0xdc }, { 0xc5,0x2a,0xcb,0xd7 },
{ 0xef,0x15,0xe8,0xe6 }, { 0xe1,0x1c,0xe5,0xed },
- { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb },
+ { 0xf3,0x07,0xf2,0xf0 }, { 0xfd,0x0e,0xff,0xfb },
{ 0xa7,0x79,0xb4,0x92 }, { 0xa9,0x70,0xb9,0x99 },
- { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f },
+ { 0xbb,0x6b,0xae,0x84 }, { 0xb5,0x62,0xa3,0x8f },
{ 0x9f,0x5d,0x80,0xbe }, { 0x91,0x54,0x8d,0xb5 },
{ 0x83,0x4f,0x9a,0xa8 }, { 0x8d,0x46,0x97,0xa3 }
};
-static const unsigned char U2[256][4] =
+static const unsigned char U2[256][4] =
{
{ 0x00,0x00,0x00,0x00 }, { 0x0b,0x0e,0x09,0x0d },
- { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 },
+ { 0x16,0x1c,0x12,0x1a }, { 0x1d,0x12,0x1b,0x17 },
{ 0x2c,0x38,0x24,0x34 }, { 0x27,0x36,0x2d,0x39 },
- { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 },
- { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 },
- { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f },
+ { 0x3a,0x24,0x36,0x2e }, { 0x31,0x2a,0x3f,0x23 },
+ { 0x58,0x70,0x48,0x68 }, { 0x53,0x7e,0x41,0x65 },
+ { 0x4e,0x6c,0x5a,0x72 }, { 0x45,0x62,0x53,0x7f },
{ 0x74,0x48,0x6c,0x5c }, { 0x7f,0x46,0x65,0x51 },
- { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b },
- { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd },
- { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 },
- { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 },
- { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 },
+ { 0x62,0x54,0x7e,0x46 }, { 0x69,0x5a,0x77,0x4b },
+ { 0xb0,0xe0,0x90,0xd0 }, { 0xbb,0xee,0x99,0xdd },
+ { 0xa6,0xfc,0x82,0xca }, { 0xad,0xf2,0x8b,0xc7 },
+ { 0x9c,0xd8,0xb4,0xe4 }, { 0x97,0xd6,0xbd,0xe9 },
+ { 0x8a,0xc4,0xa6,0xfe }, { 0x81,0xca,0xaf,0xf3 },
{ 0xe8,0x90,0xd8,0xb8 }, { 0xe3,0x9e,0xd1,0xb5 },
- { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf },
- { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 },
- { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b },
- { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 },
- { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac },
- { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 },
- { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 },
+ { 0xfe,0x8c,0xca,0xa2 }, { 0xf5,0x82,0xc3,0xaf },
+ { 0xc4,0xa8,0xfc,0x8c }, { 0xcf,0xa6,0xf5,0x81 },
+ { 0xd2,0xb4,0xee,0x96 }, { 0xd9,0xba,0xe7,0x9b },
+ { 0x7b,0xdb,0x3b,0xbb }, { 0x70,0xd5,0x32,0xb6 },
+ { 0x6d,0xc7,0x29,0xa1 }, { 0x66,0xc9,0x20,0xac },
+ { 0x57,0xe3,0x1f,0x8f }, { 0x5c,0xed,0x16,0x82 },
+ { 0x41,0xff,0x0d,0x95 }, { 0x4a,0xf1,0x04,0x98 },
{ 0x23,0xab,0x73,0xd3 }, { 0x28,0xa5,0x7a,0xde },
- { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 },
+ { 0x35,0xb7,0x61,0xc9 }, { 0x3e,0xb9,0x68,0xc4 },
{ 0x0f,0x93,0x57,0xe7 }, { 0x04,0x9d,0x5e,0xea },
- { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 },
+ { 0x19,0x8f,0x45,0xfd }, { 0x12,0x81,0x4c,0xf0 },
{ 0xcb,0x3b,0xab,0x6b }, { 0xc0,0x35,0xa2,0x66 },
- { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c },
+ { 0xdd,0x27,0xb9,0x71 }, { 0xd6,0x29,0xb0,0x7c },
{ 0xe7,0x03,0x8f,0x5f }, { 0xec,0x0d,0x86,0x52 },
- { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 },
- { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e },
- { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 },
+ { 0xf1,0x1f,0x9d,0x45 }, { 0xfa,0x11,0x94,0x48 },
+ { 0x93,0x4b,0xe3,0x03 }, { 0x98,0x45,0xea,0x0e },
+ { 0x85,0x57,0xf1,0x19 }, { 0x8e,0x59,0xf8,0x14 },
{ 0xbf,0x73,0xc7,0x37 }, { 0xb4,0x7d,0xce,0x3a },
- { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 },
- { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 },
- { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a },
- { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 },
- { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e },
+ { 0xa9,0x6f,0xd5,0x2d }, { 0xa2,0x61,0xdc,0x20 },
+ { 0xf6,0xad,0x76,0x6d }, { 0xfd,0xa3,0x7f,0x60 },
+ { 0xe0,0xb1,0x64,0x77 }, { 0xeb,0xbf,0x6d,0x7a },
+ { 0xda,0x95,0x52,0x59 }, { 0xd1,0x9b,0x5b,0x54 },
+ { 0xcc,0x89,0x40,0x43 }, { 0xc7,0x87,0x49,0x4e },
{ 0xae,0xdd,0x3e,0x05 }, { 0xa5,0xd3,0x37,0x08 },
- { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 },
+ { 0xb8,0xc1,0x2c,0x1f }, { 0xb3,0xcf,0x25,0x12 },
{ 0x82,0xe5,0x1a,0x31 }, { 0x89,0xeb,0x13,0x3c },
- { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 },
+ { 0x94,0xf9,0x08,0x2b }, { 0x9f,0xf7,0x01,0x26 },
{ 0x46,0x4d,0xe6,0xbd }, { 0x4d,0x43,0xef,0xb0 },
- { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa },
+ { 0x50,0x51,0xf4,0xa7 }, { 0x5b,0x5f,0xfd,0xaa },
{ 0x6a,0x75,0xc2,0x89 }, { 0x61,0x7b,0xcb,0x84 },
- { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e },
+ { 0x7c,0x69,0xd0,0x93 }, { 0x77,0x67,0xd9,0x9e },
{ 0x1e,0x3d,0xae,0xd5 }, { 0x15,0x33,0xa7,0xd8 },
- { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 },
+ { 0x08,0x21,0xbc,0xcf }, { 0x03,0x2f,0xb5,0xc2 },
{ 0x32,0x05,0x8a,0xe1 }, { 0x39,0x0b,0x83,0xec },
- { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 },
+ { 0x24,0x19,0x98,0xfb }, { 0x2f,0x17,0x91,0xf6 },
{ 0x8d,0x76,0x4d,0xd6 }, { 0x86,0x78,0x44,0xdb },
- { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 },
+ { 0x9b,0x6a,0x5f,0xcc }, { 0x90,0x64,0x56,0xc1 },
{ 0xa1,0x4e,0x69,0xe2 }, { 0xaa,0x40,0x60,0xef },
- { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 },
+ { 0xb7,0x52,0x7b,0xf8 }, { 0xbc,0x5c,0x72,0xf5 },
{ 0xd5,0x06,0x05,0xbe }, { 0xde,0x08,0x0c,0xb3 },
- { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 },
+ { 0xc3,0x1a,0x17,0xa4 }, { 0xc8,0x14,0x1e,0xa9 },
{ 0xf9,0x3e,0x21,0x8a }, { 0xf2,0x30,0x28,0x87 },
- { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d },
+ { 0xef,0x22,0x33,0x90 }, { 0xe4,0x2c,0x3a,0x9d },
{ 0x3d,0x96,0xdd,0x06 }, { 0x36,0x98,0xd4,0x0b },
- { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 },
+ { 0x2b,0x8a,0xcf,0x1c }, { 0x20,0x84,0xc6,0x11 },
{ 0x11,0xae,0xf9,0x32 }, { 0x1a,0xa0,0xf0,0x3f },
- { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 },
+ { 0x07,0xb2,0xeb,0x28 }, { 0x0c,0xbc,0xe2,0x25 },
{ 0x65,0xe6,0x95,0x6e }, { 0x6e,0xe8,0x9c,0x63 },
- { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 },
+ { 0x73,0xfa,0x87,0x74 }, { 0x78,0xf4,0x8e,0x79 },
{ 0x49,0xde,0xb1,0x5a }, { 0x42,0xd0,0xb8,0x57 },
- { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d },
+ { 0x5f,0xc2,0xa3,0x40 }, { 0x54,0xcc,0xaa,0x4d },
{ 0xf7,0x41,0xec,0xda }, { 0xfc,0x4f,0xe5,0xd7 },
- { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd },
+ { 0xe1,0x5d,0xfe,0xc0 }, { 0xea,0x53,0xf7,0xcd },
{ 0xdb,0x79,0xc8,0xee }, { 0xd0,0x77,0xc1,0xe3 },
- { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 },
+ { 0xcd,0x65,0xda,0xf4 }, { 0xc6,0x6b,0xd3,0xf9 },
{ 0xaf,0x31,0xa4,0xb2 }, { 0xa4,0x3f,0xad,0xbf },
- { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 },
+ { 0xb9,0x2d,0xb6,0xa8 }, { 0xb2,0x23,0xbf,0xa5 },
{ 0x83,0x09,0x80,0x86 }, { 0x88,0x07,0x89,0x8b },
- { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 },
+ { 0x95,0x15,0x92,0x9c }, { 0x9e,0x1b,0x9b,0x91 },
{ 0x47,0xa1,0x7c,0x0a }, { 0x4c,0xaf,0x75,0x07 },
- { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d },
+ { 0x51,0xbd,0x6e,0x10 }, { 0x5a,0xb3,0x67,0x1d },
{ 0x6b,0x99,0x58,0x3e }, { 0x60,0x97,0x51,0x33 },
- { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 },
+ { 0x7d,0x85,0x4a,0x24 }, { 0x76,0x8b,0x43,0x29 },
{ 0x1f,0xd1,0x34,0x62 }, { 0x14,0xdf,0x3d,0x6f },
- { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 },
+ { 0x09,0xcd,0x26,0x78 }, { 0x02,0xc3,0x2f,0x75 },
{ 0x33,0xe9,0x10,0x56 }, { 0x38,0xe7,0x19,0x5b },
- { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 },
+ { 0x25,0xf5,0x02,0x4c }, { 0x2e,0xfb,0x0b,0x41 },
{ 0x8c,0x9a,0xd7,0x61 }, { 0x87,0x94,0xde,0x6c },
- { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 },
+ { 0x9a,0x86,0xc5,0x7b }, { 0x91,0x88,0xcc,0x76 },
{ 0xa0,0xa2,0xf3,0x55 }, { 0xab,0xac,0xfa,0x58 },
- { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 },
+ { 0xb6,0xbe,0xe1,0x4f }, { 0xbd,0xb0,0xe8,0x42 },
{ 0xd4,0xea,0x9f,0x09 }, { 0xdf,0xe4,0x96,0x04 },
- { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e },
+ { 0xc2,0xf6,0x8d,0x13 }, { 0xc9,0xf8,0x84,0x1e },
{ 0xf8,0xd2,0xbb,0x3d }, { 0xf3,0xdc,0xb2,0x30 },
- { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a },
+ { 0xee,0xce,0xa9,0x27 }, { 0xe5,0xc0,0xa0,0x2a },
{ 0x3c,0x7a,0x47,0xb1 }, { 0x37,0x74,0x4e,0xbc },
- { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 },
+ { 0x2a,0x66,0x55,0xab }, { 0x21,0x68,0x5c,0xa6 },
{ 0x10,0x42,0x63,0x85 }, { 0x1b,0x4c,0x6a,0x88 },
- { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 },
+ { 0x06,0x5e,0x71,0x9f }, { 0x0d,0x50,0x78,0x92 },
{ 0x64,0x0a,0x0f,0xd9 }, { 0x6f,0x04,0x06,0xd4 },
- { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce },
+ { 0x72,0x16,0x1d,0xc3 }, { 0x79,0x18,0x14,0xce },
{ 0x48,0x32,0x2b,0xed }, { 0x43,0x3c,0x22,0xe0 },
- { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa },
+ { 0x5e,0x2e,0x39,0xf7 }, { 0x55,0x20,0x30,0xfa },
{ 0x01,0xec,0x9a,0xb7 }, { 0x0a,0xe2,0x93,0xba },
- { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 },
+ { 0x17,0xf0,0x88,0xad }, { 0x1c,0xfe,0x81,0xa0 },
{ 0x2d,0xd4,0xbe,0x83 }, { 0x26,0xda,0xb7,0x8e },
- { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 },
+ { 0x3b,0xc8,0xac,0x99 }, { 0x30,0xc6,0xa5,0x94 },
{ 0x59,0x9c,0xd2,0xdf }, { 0x52,0x92,0xdb,0xd2 },
- { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 },
+ { 0x4f,0x80,0xc0,0xc5 }, { 0x44,0x8e,0xc9,0xc8 },
{ 0x75,0xa4,0xf6,0xeb }, { 0x7e,0xaa,0xff,0xe6 },
- { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc },
+ { 0x63,0xb8,0xe4,0xf1 }, { 0x68,0xb6,0xed,0xfc },
{ 0xb1,0x0c,0x0a,0x67 }, { 0xba,0x02,0x03,0x6a },
- { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 },
+ { 0xa7,0x10,0x18,0x7d }, { 0xac,0x1e,0x11,0x70 },
{ 0x9d,0x34,0x2e,0x53 }, { 0x96,0x3a,0x27,0x5e },
- { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 },
+ { 0x8b,0x28,0x3c,0x49 }, { 0x80,0x26,0x35,0x44 },
{ 0xe9,0x7c,0x42,0x0f }, { 0xe2,0x72,0x4b,0x02 },
- { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 },
+ { 0xff,0x60,0x50,0x15 }, { 0xf4,0x6e,0x59,0x18 },
{ 0xc5,0x44,0x66,0x3b }, { 0xce,0x4a,0x6f,0x36 },
- { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c },
+ { 0xd3,0x58,0x74,0x21 }, { 0xd8,0x56,0x7d,0x2c },
{ 0x7a,0x37,0xa1,0x0c }, { 0x71,0x39,0xa8,0x01 },
- { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b },
+ { 0x6c,0x2b,0xb3,0x16 }, { 0x67,0x25,0xba,0x1b },
{ 0x56,0x0f,0x85,0x38 }, { 0x5d,0x01,0x8c,0x35 },
- { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f },
+ { 0x40,0x13,0x97,0x22 }, { 0x4b,0x1d,0x9e,0x2f },
{ 0x22,0x47,0xe9,0x64 }, { 0x29,0x49,0xe0,0x69 },
- { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 },
+ { 0x34,0x5b,0xfb,0x7e }, { 0x3f,0x55,0xf2,0x73 },
{ 0x0e,0x7f,0xcd,0x50 }, { 0x05,0x71,0xc4,0x5d },
- { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 },
+ { 0x18,0x63,0xdf,0x4a }, { 0x13,0x6d,0xd6,0x47 },
{ 0xca,0xd7,0x31,0xdc }, { 0xc1,0xd9,0x38,0xd1 },
- { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb },
+ { 0xdc,0xcb,0x23,0xc6 }, { 0xd7,0xc5,0x2a,0xcb },
{ 0xe6,0xef,0x15,0xe8 }, { 0xed,0xe1,0x1c,0xe5 },
- { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff },
+ { 0xf0,0xf3,0x07,0xf2 }, { 0xfb,0xfd,0x0e,0xff },
{ 0x92,0xa7,0x79,0xb4 }, { 0x99,0xa9,0x70,0xb9 },
- { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 },
+ { 0x84,0xbb,0x6b,0xae }, { 0x8f,0xb5,0x62,0xa3 },
{ 0xbe,0x9f,0x5d,0x80 }, { 0xb5,0x91,0x54,0x8d },
{ 0xa8,0x83,0x4f,0x9a }, { 0xa3,0x8d,0x46,0x97 }
};
-static const unsigned char U3[256][4] =
+static const unsigned char U3[256][4] =
{
{ 0x00,0x00,0x00,0x00 }, { 0x0d,0x0b,0x0e,0x09 },
- { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b },
+ { 0x1a,0x16,0x1c,0x12 }, { 0x17,0x1d,0x12,0x1b },
{ 0x34,0x2c,0x38,0x24 }, { 0x39,0x27,0x36,0x2d },
- { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f },
+ { 0x2e,0x3a,0x24,0x36 }, { 0x23,0x31,0x2a,0x3f },
{ 0x68,0x58,0x70,0x48 }, { 0x65,0x53,0x7e,0x41 },
- { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 },
+ { 0x72,0x4e,0x6c,0x5a }, { 0x7f,0x45,0x62,0x53 },
{ 0x5c,0x74,0x48,0x6c }, { 0x51,0x7f,0x46,0x65 },
- { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 },
+ { 0x46,0x62,0x54,0x7e }, { 0x4b,0x69,0x5a,0x77 },
{ 0xd0,0xb0,0xe0,0x90 }, { 0xdd,0xbb,0xee,0x99 },
- { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b },
+ { 0xca,0xa6,0xfc,0x82 }, { 0xc7,0xad,0xf2,0x8b },
{ 0xe4,0x9c,0xd8,0xb4 }, { 0xe9,0x97,0xd6,0xbd },
- { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf },
+ { 0xfe,0x8a,0xc4,0xa6 }, { 0xf3,0x81,0xca,0xaf },
{ 0xb8,0xe8,0x90,0xd8 }, { 0xb5,0xe3,0x9e,0xd1 },
- { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 },
+ { 0xa2,0xfe,0x8c,0xca }, { 0xaf,0xf5,0x82,0xc3 },
{ 0x8c,0xc4,0xa8,0xfc }, { 0x81,0xcf,0xa6,0xf5 },
- { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 },
+ { 0x96,0xd2,0xb4,0xee }, { 0x9b,0xd9,0xba,0xe7 },
{ 0xbb,0x7b,0xdb,0x3b }, { 0xb6,0x70,0xd5,0x32 },
- { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 },
+ { 0xa1,0x6d,0xc7,0x29 }, { 0xac,0x66,0xc9,0x20 },
{ 0x8f,0x57,0xe3,0x1f }, { 0x82,0x5c,0xed,0x16 },
- { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 },
+ { 0x95,0x41,0xff,0x0d }, { 0x98,0x4a,0xf1,0x04 },
{ 0xd3,0x23,0xab,0x73 }, { 0xde,0x28,0xa5,0x7a },
- { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 },
+ { 0xc9,0x35,0xb7,0x61 }, { 0xc4,0x3e,0xb9,0x68 },
{ 0xe7,0x0f,0x93,0x57 }, { 0xea,0x04,0x9d,0x5e },
- { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c },
+ { 0xfd,0x19,0x8f,0x45 }, { 0xf0,0x12,0x81,0x4c },
{ 0x6b,0xcb,0x3b,0xab }, { 0x66,0xc0,0x35,0xa2 },
- { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 },
+ { 0x71,0xdd,0x27,0xb9 }, { 0x7c,0xd6,0x29,0xb0 },
{ 0x5f,0xe7,0x03,0x8f }, { 0x52,0xec,0x0d,0x86 },
- { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 },
+ { 0x45,0xf1,0x1f,0x9d }, { 0x48,0xfa,0x11,0x94 },
{ 0x03,0x93,0x4b,0xe3 }, { 0x0e,0x98,0x45,0xea },
- { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 },
- { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce },
- { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc },
+ { 0x19,0x85,0x57,0xf1 }, { 0x14,0x8e,0x59,0xf8 },
+ { 0x37,0xbf,0x73,0xc7 }, { 0x3a,0xb4,0x7d,0xce },
+ { 0x2d,0xa9,0x6f,0xd5 }, { 0x20,0xa2,0x61,0xdc },
{ 0x6d,0xf6,0xad,0x76 }, { 0x60,0xfd,0xa3,0x7f },
- { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d },
+ { 0x77,0xe0,0xb1,0x64 }, { 0x7a,0xeb,0xbf,0x6d },
{ 0x59,0xda,0x95,0x52 }, { 0x54,0xd1,0x9b,0x5b },
- { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 },
+ { 0x43,0xcc,0x89,0x40 }, { 0x4e,0xc7,0x87,0x49 },
{ 0x05,0xae,0xdd,0x3e }, { 0x08,0xa5,0xd3,0x37 },
- { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 },
- { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 },
- { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 },
- { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef },
- { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd },
- { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb },
- { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 },
+ { 0x1f,0xb8,0xc1,0x2c }, { 0x12,0xb3,0xcf,0x25 },
+ { 0x31,0x82,0xe5,0x1a }, { 0x3c,0x89,0xeb,0x13 },
+ { 0x2b,0x94,0xf9,0x08 }, { 0x26,0x9f,0xf7,0x01 },
+ { 0xbd,0x46,0x4d,0xe6 }, { 0xb0,0x4d,0x43,0xef },
+ { 0xa7,0x50,0x51,0xf4 }, { 0xaa,0x5b,0x5f,0xfd },
+ { 0x89,0x6a,0x75,0xc2 }, { 0x84,0x61,0x7b,0xcb },
+ { 0x93,0x7c,0x69,0xd0 }, { 0x9e,0x77,0x67,0xd9 },
{ 0xd5,0x1e,0x3d,0xae }, { 0xd8,0x15,0x33,0xa7 },
- { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 },
+ { 0xcf,0x08,0x21,0xbc }, { 0xc2,0x03,0x2f,0xb5 },
{ 0xe1,0x32,0x05,0x8a }, { 0xec,0x39,0x0b,0x83 },
- { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 },
- { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 },
- { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 },
- { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 },
- { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 },
- { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c },
- { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e },
+ { 0xfb,0x24,0x19,0x98 }, { 0xf6,0x2f,0x17,0x91 },
+ { 0xd6,0x8d,0x76,0x4d }, { 0xdb,0x86,0x78,0x44 },
+ { 0xcc,0x9b,0x6a,0x5f }, { 0xc1,0x90,0x64,0x56 },
+ { 0xe2,0xa1,0x4e,0x69 }, { 0xef,0xaa,0x40,0x60 },
+ { 0xf8,0xb7,0x52,0x7b }, { 0xf5,0xbc,0x5c,0x72 },
+ { 0xbe,0xd5,0x06,0x05 }, { 0xb3,0xde,0x08,0x0c },
+ { 0xa4,0xc3,0x1a,0x17 }, { 0xa9,0xc8,0x14,0x1e },
{ 0x8a,0xf9,0x3e,0x21 }, { 0x87,0xf2,0x30,0x28 },
- { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a },
+ { 0x90,0xef,0x22,0x33 }, { 0x9d,0xe4,0x2c,0x3a },
{ 0x06,0x3d,0x96,0xdd }, { 0x0b,0x36,0x98,0xd4 },
- { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 },
+ { 0x1c,0x2b,0x8a,0xcf }, { 0x11,0x20,0x84,0xc6 },
{ 0x32,0x11,0xae,0xf9 }, { 0x3f,0x1a,0xa0,0xf0 },
- { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 },
+ { 0x28,0x07,0xb2,0xeb }, { 0x25,0x0c,0xbc,0xe2 },
{ 0x6e,0x65,0xe6,0x95 }, { 0x63,0x6e,0xe8,0x9c },
- { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e },
+ { 0x74,0x73,0xfa,0x87 }, { 0x79,0x78,0xf4,0x8e },
{ 0x5a,0x49,0xde,0xb1 }, { 0x57,0x42,0xd0,0xb8 },
- { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa },
+ { 0x40,0x5f,0xc2,0xa3 }, { 0x4d,0x54,0xcc,0xaa },
{ 0xda,0xf7,0x41,0xec }, { 0xd7,0xfc,0x4f,0xe5 },
- { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 },
+ { 0xc0,0xe1,0x5d,0xfe }, { 0xcd,0xea,0x53,0xf7 },
{ 0xee,0xdb,0x79,0xc8 }, { 0xe3,0xd0,0x77,0xc1 },
- { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 },
+ { 0xf4,0xcd,0x65,0xda }, { 0xf9,0xc6,0x6b,0xd3 },
{ 0xb2,0xaf,0x31,0xa4 }, { 0xbf,0xa4,0x3f,0xad },
- { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf },
+ { 0xa8,0xb9,0x2d,0xb6 }, { 0xa5,0xb2,0x23,0xbf },
{ 0x86,0x83,0x09,0x80 }, { 0x8b,0x88,0x07,0x89 },
- { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b },
+ { 0x9c,0x95,0x15,0x92 }, { 0x91,0x9e,0x1b,0x9b },
{ 0x0a,0x47,0xa1,0x7c }, { 0x07,0x4c,0xaf,0x75 },
- { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 },
+ { 0x10,0x51,0xbd,0x6e }, { 0x1d,0x5a,0xb3,0x67 },
{ 0x3e,0x6b,0x99,0x58 }, { 0x33,0x60,0x97,0x51 },
- { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 },
+ { 0x24,0x7d,0x85,0x4a }, { 0x29,0x76,0x8b,0x43 },
{ 0x62,0x1f,0xd1,0x34 }, { 0x6f,0x14,0xdf,0x3d },
- { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f },
+ { 0x78,0x09,0xcd,0x26 }, { 0x75,0x02,0xc3,0x2f },
{ 0x56,0x33,0xe9,0x10 }, { 0x5b,0x38,0xe7,0x19 },
- { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b },
+ { 0x4c,0x25,0xf5,0x02 }, { 0x41,0x2e,0xfb,0x0b },
{ 0x61,0x8c,0x9a,0xd7 }, { 0x6c,0x87,0x94,0xde },
- { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc },
+ { 0x7b,0x9a,0x86,0xc5 }, { 0x76,0x91,0x88,0xcc },
{ 0x55,0xa0,0xa2,0xf3 }, { 0x58,0xab,0xac,0xfa },
- { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 },
+ { 0x4f,0xb6,0xbe,0xe1 }, { 0x42,0xbd,0xb0,0xe8 },
{ 0x09,0xd4,0xea,0x9f }, { 0x04,0xdf,0xe4,0x96 },
- { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 },
+ { 0x13,0xc2,0xf6,0x8d }, { 0x1e,0xc9,0xf8,0x84 },
{ 0x3d,0xf8,0xd2,0xbb }, { 0x30,0xf3,0xdc,0xb2 },
- { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 },
+ { 0x27,0xee,0xce,0xa9 }, { 0x2a,0xe5,0xc0,0xa0 },
{ 0xb1,0x3c,0x7a,0x47 }, { 0xbc,0x37,0x74,0x4e },
- { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c },
+ { 0xab,0x2a,0x66,0x55 }, { 0xa6,0x21,0x68,0x5c },
{ 0x85,0x10,0x42,0x63 }, { 0x88,0x1b,0x4c,0x6a },
- { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 },
+ { 0x9f,0x06,0x5e,0x71 }, { 0x92,0x0d,0x50,0x78 },
{ 0xd9,0x64,0x0a,0x0f }, { 0xd4,0x6f,0x04,0x06 },
- { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 },
+ { 0xc3,0x72,0x16,0x1d }, { 0xce,0x79,0x18,0x14 },
{ 0xed,0x48,0x32,0x2b }, { 0xe0,0x43,0x3c,0x22 },
- { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 },
+ { 0xf7,0x5e,0x2e,0x39 }, { 0xfa,0x55,0x20,0x30 },
{ 0xb7,0x01,0xec,0x9a }, { 0xba,0x0a,0xe2,0x93 },
- { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 },
+ { 0xad,0x17,0xf0,0x88 }, { 0xa0,0x1c,0xfe,0x81 },
{ 0x83,0x2d,0xd4,0xbe }, { 0x8e,0x26,0xda,0xb7 },
- { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 },
+ { 0x99,0x3b,0xc8,0xac }, { 0x94,0x30,0xc6,0xa5 },
{ 0xdf,0x59,0x9c,0xd2 }, { 0xd2,0x52,0x92,0xdb },
- { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 },
+ { 0xc5,0x4f,0x80,0xc0 }, { 0xc8,0x44,0x8e,0xc9 },
{ 0xeb,0x75,0xa4,0xf6 }, { 0xe6,0x7e,0xaa,0xff },
- { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed },
+ { 0xf1,0x63,0xb8,0xe4 }, { 0xfc,0x68,0xb6,0xed },
{ 0x67,0xb1,0x0c,0x0a }, { 0x6a,0xba,0x02,0x03 },
- { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 },
+ { 0x7d,0xa7,0x10,0x18 }, { 0x70,0xac,0x1e,0x11 },
{ 0x53,0x9d,0x34,0x2e }, { 0x5e,0x96,0x3a,0x27 },
- { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 },
+ { 0x49,0x8b,0x28,0x3c }, { 0x44,0x80,0x26,0x35 },
{ 0x0f,0xe9,0x7c,0x42 }, { 0x02,0xe2,0x72,0x4b },
- { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 },
+ { 0x15,0xff,0x60,0x50 }, { 0x18,0xf4,0x6e,0x59 },
{ 0x3b,0xc5,0x44,0x66 }, { 0x36,0xce,0x4a,0x6f },
- { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d },
+ { 0x21,0xd3,0x58,0x74 }, { 0x2c,0xd8,0x56,0x7d },
{ 0x0c,0x7a,0x37,0xa1 }, { 0x01,0x71,0x39,0xa8 },
- { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba },
+ { 0x16,0x6c,0x2b,0xb3 }, { 0x1b,0x67,0x25,0xba },
{ 0x38,0x56,0x0f,0x85 }, { 0x35,0x5d,0x01,0x8c },
- { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e },
+ { 0x22,0x40,0x13,0x97 }, { 0x2f,0x4b,0x1d,0x9e },
{ 0x64,0x22,0x47,0xe9 }, { 0x69,0x29,0x49,0xe0 },
- { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 },
+ { 0x7e,0x34,0x5b,0xfb }, { 0x73,0x3f,0x55,0xf2 },
{ 0x50,0x0e,0x7f,0xcd }, { 0x5d,0x05,0x71,0xc4 },
- { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 },
+ { 0x4a,0x18,0x63,0xdf }, { 0x47,0x13,0x6d,0xd6 },
{ 0xdc,0xca,0xd7,0x31 }, { 0xd1,0xc1,0xd9,0x38 },
- { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a },
+ { 0xc6,0xdc,0xcb,0x23 }, { 0xcb,0xd7,0xc5,0x2a },
{ 0xe8,0xe6,0xef,0x15 }, { 0xe5,0xed,0xe1,0x1c },
- { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e },
+ { 0xf2,0xf0,0xf3,0x07 }, { 0xff,0xfb,0xfd,0x0e },
{ 0xb4,0x92,0xa7,0x79 }, { 0xb9,0x99,0xa9,0x70 },
- { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 },
+ { 0xae,0x84,0xbb,0x6b }, { 0xa3,0x8f,0xb5,0x62 },
{ 0x80,0xbe,0x9f,0x5d }, { 0x8d,0xb5,0x91,0x54 },
{ 0x9a,0xa8,0x83,0x4f }, { 0x97,0xa3,0x8d,0x46 }
};
static const unsigned char U4[256][4] =
{
{ 0x00,0x00,0x00,0x00 }, { 0x09,0x0d,0x0b,0x0e },
- { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 },
+ { 0x12,0x1a,0x16,0x1c }, { 0x1b,0x17,0x1d,0x12 },
{ 0x24,0x34,0x2c,0x38 }, { 0x2d,0x39,0x27,0x36 },
- { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a },
+ { 0x36,0x2e,0x3a,0x24 }, { 0x3f,0x23,0x31,0x2a },
{ 0x48,0x68,0x58,0x70 }, { 0x41,0x65,0x53,0x7e },
- { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 },
+ { 0x5a,0x72,0x4e,0x6c }, { 0x53,0x7f,0x45,0x62 },
{ 0x6c,0x5c,0x74,0x48 }, { 0x65,0x51,0x7f,0x46 },
- { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a },
+ { 0x7e,0x46,0x62,0x54 }, { 0x77,0x4b,0x69,0x5a },
{ 0x90,0xd0,0xb0,0xe0 }, { 0x99,0xdd,0xbb,0xee },
- { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 },
+ { 0x82,0xca,0xa6,0xfc }, { 0x8b,0xc7,0xad,0xf2 },
{ 0xb4,0xe4,0x9c,0xd8 }, { 0xbd,0xe9,0x97,0xd6 },
- { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca },
+ { 0xa6,0xfe,0x8a,0xc4 }, { 0xaf,0xf3,0x81,0xca },
{ 0xd8,0xb8,0xe8,0x90 }, { 0xd1,0xb5,0xe3,0x9e },
- { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 },
+ { 0xca,0xa2,0xfe,0x8c }, { 0xc3,0xaf,0xf5,0x82 },
{ 0xfc,0x8c,0xc4,0xa8 }, { 0xf5,0x81,0xcf,0xa6 },
- { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba },
+ { 0xee,0x96,0xd2,0xb4 }, { 0xe7,0x9b,0xd9,0xba },
{ 0x3b,0xbb,0x7b,0xdb }, { 0x32,0xb6,0x70,0xd5 },
- { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 },
+ { 0x29,0xa1,0x6d,0xc7 }, { 0x20,0xac,0x66,0xc9 },
{ 0x1f,0x8f,0x57,0xe3 }, { 0x16,0x82,0x5c,0xed },
- { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 },
+ { 0x0d,0x95,0x41,0xff }, { 0x04,0x98,0x4a,0xf1 },
{ 0x73,0xd3,0x23,0xab }, { 0x7a,0xde,0x28,0xa5 },
- { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 },
+ { 0x61,0xc9,0x35,0xb7 }, { 0x68,0xc4,0x3e,0xb9 },
{ 0x57,0xe7,0x0f,0x93 }, { 0x5e,0xea,0x04,0x9d },
- { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 },
+ { 0x45,0xfd,0x19,0x8f }, { 0x4c,0xf0,0x12,0x81 },
{ 0xab,0x6b,0xcb,0x3b }, { 0xa2,0x66,0xc0,0x35 },
- { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 },
+ { 0xb9,0x71,0xdd,0x27 }, { 0xb0,0x7c,0xd6,0x29 },
{ 0x8f,0x5f,0xe7,0x03 }, { 0x86,0x52,0xec,0x0d },
- { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 },
+ { 0x9d,0x45,0xf1,0x1f }, { 0x94,0x48,0xfa,0x11 },
{ 0xe3,0x03,0x93,0x4b }, { 0xea,0x0e,0x98,0x45 },
- { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 },
+ { 0xf1,0x19,0x85,0x57 }, { 0xf8,0x14,0x8e,0x59 },
{ 0xc7,0x37,0xbf,0x73 }, { 0xce,0x3a,0xb4,0x7d },
- { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 },
+ { 0xd5,0x2d,0xa9,0x6f }, { 0xdc,0x20,0xa2,0x61 },
{ 0x76,0x6d,0xf6,0xad }, { 0x7f,0x60,0xfd,0xa3 },
- { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf },
+ { 0x64,0x77,0xe0,0xb1 }, { 0x6d,0x7a,0xeb,0xbf },
{ 0x52,0x59,0xda,0x95 }, { 0x5b,0x54,0xd1,0x9b },
- { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 },
+ { 0x40,0x43,0xcc,0x89 }, { 0x49,0x4e,0xc7,0x87 },
{ 0x3e,0x05,0xae,0xdd }, { 0x37,0x08,0xa5,0xd3 },
- { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf },
+ { 0x2c,0x1f,0xb8,0xc1 }, { 0x25,0x12,0xb3,0xcf },
{ 0x1a,0x31,0x82,0xe5 }, { 0x13,0x3c,0x89,0xeb },
- { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 },
+ { 0x08,0x2b,0x94,0xf9 }, { 0x01,0x26,0x9f,0xf7 },
{ 0xe6,0xbd,0x46,0x4d }, { 0xef,0xb0,0x4d,0x43 },
- { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f },
+ { 0xf4,0xa7,0x50,0x51 }, { 0xfd,0xaa,0x5b,0x5f },
{ 0xc2,0x89,0x6a,0x75 }, { 0xcb,0x84,0x61,0x7b },
- { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 },
+ { 0xd0,0x93,0x7c,0x69 }, { 0xd9,0x9e,0x77,0x67 },
{ 0xae,0xd5,0x1e,0x3d }, { 0xa7,0xd8,0x15,0x33 },
- { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f },
+ { 0xbc,0xcf,0x08,0x21 }, { 0xb5,0xc2,0x03,0x2f },
{ 0x8a,0xe1,0x32,0x05 }, { 0x83,0xec,0x39,0x0b },
- { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 },
+ { 0x98,0xfb,0x24,0x19 }, { 0x91,0xf6,0x2f,0x17 },
{ 0x4d,0xd6,0x8d,0x76 }, { 0x44,0xdb,0x86,0x78 },
- { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 },
+ { 0x5f,0xcc,0x9b,0x6a }, { 0x56,0xc1,0x90,0x64 },
{ 0x69,0xe2,0xa1,0x4e }, { 0x60,0xef,0xaa,0x40 },
- { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c },
+ { 0x7b,0xf8,0xb7,0x52 }, { 0x72,0xf5,0xbc,0x5c },
{ 0x05,0xbe,0xd5,0x06 }, { 0x0c,0xb3,0xde,0x08 },
- { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 },
+ { 0x17,0xa4,0xc3,0x1a }, { 0x1e,0xa9,0xc8,0x14 },
{ 0x21,0x8a,0xf9,0x3e }, { 0x28,0x87,0xf2,0x30 },
- { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c },
+ { 0x33,0x90,0xef,0x22 }, { 0x3a,0x9d,0xe4,0x2c },
{ 0xdd,0x06,0x3d,0x96 }, { 0xd4,0x0b,0x36,0x98 },
- { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 },
+ { 0xcf,0x1c,0x2b,0x8a }, { 0xc6,0x11,0x20,0x84 },
{ 0xf9,0x32,0x11,0xae }, { 0xf0,0x3f,0x1a,0xa0 },
- { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc },
+ { 0xeb,0x28,0x07,0xb2 }, { 0xe2,0x25,0x0c,0xbc },
{ 0x95,0x6e,0x65,0xe6 }, { 0x9c,0x63,0x6e,0xe8 },
- { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 },
+ { 0x87,0x74,0x73,0xfa }, { 0x8e,0x79,0x78,0xf4 },
{ 0xb1,0x5a,0x49,0xde }, { 0xb8,0x57,0x42,0xd0 },
- { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc },
+ { 0xa3,0x40,0x5f,0xc2 }, { 0xaa,0x4d,0x54,0xcc },
{ 0xec,0xda,0xf7,0x41 }, { 0xe5,0xd7,0xfc,0x4f },
- { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 },
+ { 0xfe,0xc0,0xe1,0x5d }, { 0xf7,0xcd,0xea,0x53 },
{ 0xc8,0xee,0xdb,0x79 }, { 0xc1,0xe3,0xd0,0x77 },
- { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b },
+ { 0xda,0xf4,0xcd,0x65 }, { 0xd3,0xf9,0xc6,0x6b },
{ 0xa4,0xb2,0xaf,0x31 }, { 0xad,0xbf,0xa4,0x3f },
- { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 },
+ { 0xb6,0xa8,0xb9,0x2d }, { 0xbf,0xa5,0xb2,0x23 },
{ 0x80,0x86,0x83,0x09 }, { 0x89,0x8b,0x88,0x07 },
- { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b },
+ { 0x92,0x9c,0x95,0x15 }, { 0x9b,0x91,0x9e,0x1b },
{ 0x7c,0x0a,0x47,0xa1 }, { 0x75,0x07,0x4c,0xaf },
- { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 },
+ { 0x6e,0x10,0x51,0xbd }, { 0x67,0x1d,0x5a,0xb3 },
{ 0x58,0x3e,0x6b,0x99 }, { 0x51,0x33,0x60,0x97 },
- { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b },
+ { 0x4a,0x24,0x7d,0x85 }, { 0x43,0x29,0x76,0x8b },
{ 0x34,0x62,0x1f,0xd1 }, { 0x3d,0x6f,0x14,0xdf },
- { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 },
+ { 0x26,0x78,0x09,0xcd }, { 0x2f,0x75,0x02,0xc3 },
{ 0x10,0x56,0x33,0xe9 }, { 0x19,0x5b,0x38,0xe7 },
- { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb },
+ { 0x02,0x4c,0x25,0xf5 }, { 0x0b,0x41,0x2e,0xfb },
{ 0xd7,0x61,0x8c,0x9a }, { 0xde,0x6c,0x87,0x94 },
- { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 },
+ { 0xc5,0x7b,0x9a,0x86 }, { 0xcc,0x76,0x91,0x88 },
{ 0xf3,0x55,0xa0,0xa2 }, { 0xfa,0x58,0xab,0xac },
- { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 },
+ { 0xe1,0x4f,0xb6,0xbe }, { 0xe8,0x42,0xbd,0xb0 },
{ 0x9f,0x09,0xd4,0xea }, { 0x96,0x04,0xdf,0xe4 },
- { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 },
+ { 0x8d,0x13,0xc2,0xf6 }, { 0x84,0x1e,0xc9,0xf8 },
{ 0xbb,0x3d,0xf8,0xd2 }, { 0xb2,0x30,0xf3,0xdc },
- { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 },
+ { 0xa9,0x27,0xee,0xce }, { 0xa0,0x2a,0xe5,0xc0 },
{ 0x47,0xb1,0x3c,0x7a }, { 0x4e,0xbc,0x37,0x74 },
- { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 },
+ { 0x55,0xab,0x2a,0x66 }, { 0x5c,0xa6,0x21,0x68 },
{ 0x63,0x85,0x10,0x42 }, { 0x6a,0x88,0x1b,0x4c },
- { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 },
+ { 0x71,0x9f,0x06,0x5e }, { 0x78,0x92,0x0d,0x50 },
{ 0x0f,0xd9,0x64,0x0a }, { 0x06,0xd4,0x6f,0x04 },
- { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 },
+ { 0x1d,0xc3,0x72,0x16 }, { 0x14,0xce,0x79,0x18 },
{ 0x2b,0xed,0x48,0x32 }, { 0x22,0xe0,0x43,0x3c },
- { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 },
- { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 },
- { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe },
+ { 0x39,0xf7,0x5e,0x2e }, { 0x30,0xfa,0x55,0x20 },
+ { 0x9a,0xb7,0x01,0xec }, { 0x93,0xba,0x0a,0xe2 },
+ { 0x88,0xad,0x17,0xf0 }, { 0x81,0xa0,0x1c,0xfe },
{ 0xbe,0x83,0x2d,0xd4 }, { 0xb7,0x8e,0x26,0xda },
- { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 },
- { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 },
- { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e },
+ { 0xac,0x99,0x3b,0xc8 }, { 0xa5,0x94,0x30,0xc6 },
+ { 0xd2,0xdf,0x59,0x9c }, { 0xdb,0xd2,0x52,0x92 },
+ { 0xc0,0xc5,0x4f,0x80 }, { 0xc9,0xc8,0x44,0x8e },
{ 0xf6,0xeb,0x75,0xa4 }, { 0xff,0xe6,0x7e,0xaa },
- { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 },
+ { 0xe4,0xf1,0x63,0xb8 }, { 0xed,0xfc,0x68,0xb6 },
{ 0x0a,0x67,0xb1,0x0c }, { 0x03,0x6a,0xba,0x02 },
- { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e },
+ { 0x18,0x7d,0xa7,0x10 }, { 0x11,0x70,0xac,0x1e },
{ 0x2e,0x53,0x9d,0x34 }, { 0x27,0x5e,0x96,0x3a },
- { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 },
- { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 },
- { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e },
+ { 0x3c,0x49,0x8b,0x28 }, { 0x35,0x44,0x80,0x26 },
+ { 0x42,0x0f,0xe9,0x7c }, { 0x4b,0x02,0xe2,0x72 },
+ { 0x50,0x15,0xff,0x60 }, { 0x59,0x18,0xf4,0x6e },
{ 0x66,0x3b,0xc5,0x44 }, { 0x6f,0x36,0xce,0x4a },
- { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 },
+ { 0x74,0x21,0xd3,0x58 }, { 0x7d,0x2c,0xd8,0x56 },
{ 0xa1,0x0c,0x7a,0x37 }, { 0xa8,0x01,0x71,0x39 },
- { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 },
+ { 0xb3,0x16,0x6c,0x2b }, { 0xba,0x1b,0x67,0x25 },
{ 0x85,0x38,0x56,0x0f }, { 0x8c,0x35,0x5d,0x01 },
- { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d },
- { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 },
- { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 },
+ { 0x97,0x22,0x40,0x13 }, { 0x9e,0x2f,0x4b,0x1d },
+ { 0xe9,0x64,0x22,0x47 }, { 0xe0,0x69,0x29,0x49 },
+ { 0xfb,0x7e,0x34,0x5b }, { 0xf2,0x73,0x3f,0x55 },
{ 0xcd,0x50,0x0e,0x7f }, { 0xc4,0x5d,0x05,0x71 },
- { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d },
+ { 0xdf,0x4a,0x18,0x63 }, { 0xd6,0x47,0x13,0x6d },
{ 0x31,0xdc,0xca,0xd7 }, { 0x38,0xd1,0xc1,0xd9 },
- { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 },
+ { 0x23,0xc6,0xdc,0xcb }, { 0x2a,0xcb,0xd7,0xc5 },
{ 0x15,0xe8,0xe6,0xef }, { 0x1c,0xe5,0xed,0xe1 },
- { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd },
+ { 0x07,0xf2,0xf0,0xf3 }, { 0x0e,0xff,0xfb,0xfd },
{ 0x79,0xb4,0x92,0xa7 }, { 0x70,0xb9,0x99,0xa9 },
- { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 },
+ { 0x6b,0xae,0x84,0xbb }, { 0x62,0xa3,0x8f,0xb5 },
{ 0x5d,0x80,0xbe,0x9f }, { 0x54,0x8d,0xb5,0x91 },
{ 0x4f,0x9a,0xa8,0x83 }, { 0x46,0x97,0xa3,0x8d }
};
-static const u32 rcon[30] =
- {
+static const u32 rcon[30] =
+ {
0x01, 0x02, 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x1b, 0x36, 0x6c,
0xd8, 0xab, 0x4d, 0x9a, 0x2f, 0x5e, 0xbc, 0x63, 0xc6, 0x97, 0x35,
0x6a, 0xd4, 0xb3, 0x7d, 0xfa, 0xef, 0xc5, 0x91
};
-
/* Rijndael (AES) for GnuPG
* Copyright (C) 2000, 2001, 2002, 2003, 2007,
- * 2008 Free Software Foundation, Inc.
+ * 2008, 2011 Free Software Foundation, Inc.
*
* This file is part of Libgcrypt.
*
#define BLOCKSIZE (128/8)
+/* Helper macro to force alignment to 16 bytes. */
+#ifdef __GNUC__
+# define ATTR_ALIGNED_16 __attribute__ ((aligned (16)))
+#else
+# define ATTR_ALIGNED_16
+#endif
+
+
/* USE_PADLOCK indicates whether to compile the padlock specific
code. */
#undef USE_PADLOCK
#ifdef ENABLE_PADLOCK_SUPPORT
# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && defined (__GNUC__)
-# define USE_PADLOCK
+# define USE_PADLOCK 1
# endif
#endif /*ENABLE_PADLOCK_SUPPORT*/
-static const char *selftest(void);
+/* USE_AESNI inidicates whether to compile with Intel AES-NI code. We
+ need the vector-size attribute which seems to be available since
+ gcc 3. However, to be on the safe side we require at least gcc 4. */
+#undef USE_AESNI
+#ifdef ENABLE_AESNI_SUPPORT
+# if defined (__i386__) && SIZEOF_UNSIGNED_LONG == 4 && __GNUC__ >= 4
+# define USE_AESNI 1
+# endif
+#endif /* ENABLE_AESNI_SUPPORT */
-typedef struct
-{
- int ROUNDS; /* Key-length-dependent number of rounds. */
- int decryption_prepared; /* The decryption key schedule is available. */
-#ifdef USE_PADLOCK
- int use_padlock; /* Padlock shall be used. */
- /* The key as passed to the padlock engine. */
- unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#ifdef USE_AESNI
+ typedef int m128i_t __attribute__ ((__vector_size__ (16)));
+#endif /*USE_AESNI*/
+
+/* Define an u32 variant for the sake of gcc 4.4's strict aliasing. */
+#if __GNUC__ > 4 || ( __GNUC__ == 4 && __GNUC_MINOR__ >= 4 )
+typedef u32 __attribute__ ((__may_alias__)) u32_a_t;
+#else
+typedef u32 u32_a_t;
#endif
+
+
+\f
+/* Our context object. */
+typedef struct
+{
+ /* The first fields are the keyschedule arrays. This is so that
+ they are aligned on a 16 byte boundary if using gcc. This
+ alignment is required for the AES-NI code and a good idea in any
+ case. The alignment is guaranteed due to the way cipher.c
+ allocates the space for the context. The PROPERLY_ALIGNED_TYPE
+ hack is used to force a minimal alignment if not using gcc of if
+ the alignment requirement is higher that 16 bytes. */
union
{
PROPERLY_ALIGNED_TYPE dummy;
byte keyschedule[MAXROUNDS+1][4][4];
+#ifdef USE_PADLOCK
+ /* The key as passed to the padlock engine. It is only used if
+ the padlock engine is used (USE_PADLOCK, below). */
+ unsigned char padlock_key[16] __attribute__ ((aligned (16)));
+#endif /*USE_PADLOCK*/
} u1;
union
{
PROPERLY_ALIGNED_TYPE dummy;
- byte keyschedule[MAXROUNDS+1][4][4];
+ byte keyschedule[MAXROUNDS+1][4][4];
} u2;
-} RIJNDAEL_context;
+ int rounds; /* Key-length-dependent number of rounds. */
+ int decryption_prepared; /* The decryption key schedule is available. */
+#ifdef USE_PADLOCK
+ int use_padlock; /* Padlock shall be used. */
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ int use_aesni; /* AES-NI shall be used. */
+#endif /*USE_AESNI*/
+} RIJNDAEL_context ATTR_ALIGNED_16;
+
+/* Macros defining alias for the keyschedules. */
+#define keyschenc u1.keyschedule
+#define keyschdec u2.keyschedule
+#define padlockkey u1.padlock_key
+
+/* Two macros to be called prior and after the use of AESNI
+ instructions. There should be no external function calls between
+ the use of these macros. There purpose is to make sure that the
+ SSE regsiters are cleared and won't reveal any information about
+ the key or the data. */
+#ifdef USE_AESNI
+# define aesni_prepare() do { } while (0)
+# define aesni_cleanup() \
+ do { asm volatile ("pxor %%xmm0, %%xmm0\n\t" \
+ "pxor %%xmm1, %%xmm1\n" :: ); \
+ } while (0)
+# define aesni_cleanup_2_4() \
+ do { asm volatile ("pxor %%xmm2, %%xmm2\n\t" \
+ "pxor %%xmm3, %%xmm3\n" \
+ "pxor %%xmm4, %%xmm4\n":: ); \
+ } while (0)
+#else
+# define aesni_prepare() do { } while (0)
+# define aesni_cleanup() do { } while (0)
+#endif
-#define keySched u1.keyschedule
-#define keySched2 u2.keyschedule
/* All the numbers. */
#include "rijndael-tables.h"
-/* Perform the key setup. */
+\f
+/* Function prototypes. */
+#ifdef USE_AESNI
+/* We don't want to inline these functions to help gcc allocate enough
+ registers. */
+static void do_aesni_ctr (const RIJNDAEL_context *ctx, unsigned char *ctr,
+ unsigned char *b, const unsigned char *a)
+ __attribute__ ((__noinline__));
+static void do_aesni_ctr_4 (const RIJNDAEL_context *ctx, unsigned char *ctr,
+ unsigned char *b, const unsigned char *a)
+ __attribute__ ((__noinline__));
+#endif /*USE_AESNI*/
+
+static const char *selftest(void);
+
+
+\f
+/* Perform the key setup. */
static gcry_err_code_t
do_setkey (RIJNDAEL_context *ctx, const byte *key, const unsigned keylen)
{
static int initialized = 0;
static const char *selftest_failed=0;
- int ROUNDS;
+ int rounds;
int i,j, r, t, rconpointer = 0;
int KC;
union
PROPERLY_ALIGNED_TYPE dummy;
byte tk[MAXKC][4];
} tk;
-#define tk tk.tk
+#define tk tk.tk
/* The on-the-fly self tests are only run in non-fips mode. In fips
mode explicit self-tests are required. Actually the on-the-fly
self-tests are not fully thread-safe and it might happen that a
- failed self-test won't get noticed in another thread.
+ failed self-test won't get noticed in another thread.
FIXME: We might want to have a central registry of succeeded
self-tests. */
#ifdef USE_PADLOCK
ctx->use_padlock = 0;
#endif
+#ifdef USE_AESNI
+ ctx->use_aesni = 0;
+#endif
if( keylen == 128/8 )
{
- ROUNDS = 10;
+ rounds = 10;
KC = 4;
+
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
+ else if ((_gcry_get_hw_features () & HWF_PADLOCK_AES))
{
ctx->use_padlock = 1;
- memcpy (ctx->padlock_key, key, keylen);
+ memcpy (ctx->padlockkey, key, keylen);
+ }
+#endif
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
}
#endif
}
else if ( keylen == 192/8 )
{
- ROUNDS = 12;
+ rounds = 12;
KC = 6;
+
+ if (0)
+ {
+ ;
+ }
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
+ }
+#endif
}
else if ( keylen == 256/8 )
{
- ROUNDS = 14;
+ rounds = 14;
KC = 8;
+
+ if (0)
+ {
+ ;
+ }
+#ifdef USE_AESNI
+ else if ((_gcry_get_hw_features () & HWF_INTEL_AESNI))
+ {
+ ctx->use_aesni = 1;
+ }
+#endif
}
else
return GPG_ERR_INV_KEYLEN;
- ctx->ROUNDS = ROUNDS;
+ ctx->rounds = rounds;
-#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ /* NB: We don't yet support Padlock hardware key generation. */
+
+ if (0)
+ ;
+#ifdef USE_AESNI_is_disabled_here
+ else if (ctx->use_aesni && ctx->rounds == 10)
{
- /* Nothing to do as we support only hardware key generation for
- now. */
+ /* Note: This code works for AES-128 but it is not much better
+ than using the standard key schedule. We disable it for
+ now and don't put any effort into implementing this for
+ AES-192 and AES-256. */
+ asm volatile ("movl %[key], %%esi\n\t"
+ "movdqu (%%esi), %%xmm1\n\t" /* xmm1 := key */
+ "movl %[ksch], %%esi\n\t"
+ "movdqa %%xmm1, (%%esi)\n\t" /* ksch[0] := xmm1 */
+ "aeskeygenassist $0x01, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x10(%%esi)\n\t" /* ksch[1] := xmm1 */
+ "aeskeygenassist $0x02, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x20(%%esi)\n\t" /* ksch[2] := xmm1 */
+ "aeskeygenassist $0x04, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x30(%%esi)\n\t" /* ksch[3] := xmm1 */
+ "aeskeygenassist $0x08, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x40(%%esi)\n\t" /* ksch[4] := xmm1 */
+ "aeskeygenassist $0x10, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x50(%%esi)\n\t" /* ksch[5] := xmm1 */
+ "aeskeygenassist $0x20, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x60(%%esi)\n\t" /* ksch[6] := xmm1 */
+ "aeskeygenassist $0x40, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x70(%%esi)\n\t" /* ksch[7] := xmm1 */
+ "aeskeygenassist $0x80, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x80(%%esi)\n\t" /* ksch[8] := xmm1 */
+ "aeskeygenassist $0x1b, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0x90(%%esi)\n\t" /* ksch[9] := xmm1 */
+ "aeskeygenassist $0x36, %%xmm1, %%xmm2\n\t"
+ "call .Lexpand128_%=\n\t"
+ "movdqa %%xmm1, 0xa0(%%esi)\n\t" /* ksch[10] := xmm1 */
+ "jmp .Lleave%=\n"
+
+ ".Lexpand128_%=:\n\t"
+ "pshufd $0xff, %%xmm2, %%xmm2\n\t"
+ "movdqa %%xmm1, %%xmm3\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm1\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm1\n\t"
+ "pslldq $4, %%xmm3\n\t"
+ "pxor %%xmm3, %%xmm2\n\t"
+ "pxor %%xmm2, %%xmm1\n\t"
+ "ret\n"
+
+ ".Lleave%=:\n\t"
+ "pxor %%xmm1, %%xmm1\n\t"
+ "pxor %%xmm2, %%xmm2\n\t"
+ "pxor %%xmm3, %%xmm3\n"
+ :
+ : [key] "g" (key), [ksch] "g" (ctx->keyschenc)
+ : "%esi", "cc", "memory" );
}
+#endif /*USE_AESNI*/
else
-#endif /*USE_PADLOCK*/
{
-#define W (ctx->keySched)
- for (i = 0; i < keylen; i++)
+#define W (ctx->keyschenc)
+ for (i = 0; i < keylen; i++)
{
- k[i >> 2][i & 3] = key[i];
+ k[i >> 2][i & 3] = key[i];
}
-
- for (j = KC-1; j >= 0; j--)
+
+ for (j = KC-1; j >= 0; j--)
{
*((u32*)tk[j]) = *((u32*)k[j]);
}
r = 0;
t = 0;
/* Copy values into round key array. */
- for (j = 0; (j < KC) && (r < ROUNDS + 1); )
+ for (j = 0; (j < KC) && (r < rounds + 1); )
{
for (; (j < KC) && (t < 4); j++, t++)
{
t = 0;
}
}
-
- while (r < ROUNDS + 1)
+
+ while (r < rounds + 1)
{
/* While not enough round key material calculated calculate
new values. */
tk[0][2] ^= S[tk[KC-1][3]];
tk[0][3] ^= S[tk[KC-1][0]];
tk[0][0] ^= rcon[rconpointer++];
-
+
if (KC != 8)
{
- for (j = 1; j < KC; j++)
+ for (j = 1; j < KC; j++)
{
*((u32*)tk[j]) ^= *((u32*)tk[j-1]);
}
- }
- else
+ }
+ else
{
for (j = 1; j < KC/2; j++)
{
*((u32*)tk[j]) ^= *((u32*)tk[j-1]);
}
}
-
+
/* Copy values into round key array. */
- for (j = 0; (j < KC) && (r < ROUNDS + 1); )
+ for (j = 0; (j < KC) && (r < rounds + 1); )
{
for (; (j < KC) && (t < 4); j++, t++)
{
t = 0;
}
}
- }
-#undef W
+ }
+#undef W
}
return 0;
prepare_decryption( RIJNDAEL_context *ctx )
{
int r;
- union
- {
- PROPERLY_ALIGNED_TYPE dummy;
- byte *w;
- } w;
-#define w w.w
- for (r=0; r < MAXROUNDS+1; r++ )
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
{
- *((u32*)ctx->keySched2[r][0]) = *((u32*)ctx->keySched[r][0]);
- *((u32*)ctx->keySched2[r][1]) = *((u32*)ctx->keySched[r][1]);
- *((u32*)ctx->keySched2[r][2]) = *((u32*)ctx->keySched[r][2]);
- *((u32*)ctx->keySched2[r][3]) = *((u32*)ctx->keySched[r][3]);
+ /* The AES-NI decrypt instructions use the Equivalent Inverse
+ Cipher, thus we can't use the the standard decrypt key
+ preparation. */
+ m128i_t *ekey = (m128i_t*)ctx->keyschenc;
+ m128i_t *dkey = (m128i_t*)ctx->keyschdec;
+ int rr;
+
+ dkey[0] = ekey[ctx->rounds];
+ for (r=1, rr=ctx->rounds-1; r < ctx->rounds; r++, rr--)
+ {
+ asm volatile
+ ("movdqu %[ekey], %%xmm1\n\t"
+ /*"aesimc %%xmm1, %%xmm1\n\t"*/
+ ".byte 0x66, 0x0f, 0x38, 0xdb, 0xc9\n\t"
+ "movdqu %%xmm1, %[dkey]"
+ : [dkey] "=m" (dkey[r])
+ : [ekey] "m" (ekey[rr]) );
+ }
+ dkey[r] = ekey[0];
}
-#define W (ctx->keySched2)
- for (r = 1; r < ctx->ROUNDS; r++)
+ else
+#endif /*USE_AESNI*/
{
- w = W[r][0];
- *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
- ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-
- w = W[r][1];
- *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
- ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-
- w = W[r][2];
- *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
- ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
-
- w = W[r][3];
- *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ union
+ {
+ PROPERLY_ALIGNED_TYPE dummy;
+ byte *w;
+ } w;
+#define w w.w
+
+ for (r=0; r < MAXROUNDS+1; r++ )
+ {
+ *((u32*)ctx->keyschdec[r][0]) = *((u32*)ctx->keyschenc[r][0]);
+ *((u32*)ctx->keyschdec[r][1]) = *((u32*)ctx->keyschenc[r][1]);
+ *((u32*)ctx->keyschdec[r][2]) = *((u32*)ctx->keyschenc[r][2]);
+ *((u32*)ctx->keyschdec[r][3]) = *((u32*)ctx->keyschenc[r][3]);
+ }
+#define W (ctx->keyschdec)
+ for (r = 1; r < ctx->rounds; r++)
+ {
+ w = W[r][0];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+
+ w = W[r][1];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+
+ w = W[r][2];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
- }
+
+ w = W[r][3];
+ *((u32*)w) = *((u32*)U1[w[0]]) ^ *((u32*)U2[w[1]])
+ ^ *((u32*)U3[w[2]]) ^ *((u32*)U4[w[3]]);
+ }
#undef W
#undef w
-}
-
+ }
+}
\f
/* Encrypt one block. A and B need to be aligned on a 4 byte
boundary. A and B may be the same. */
static void
-do_encrypt_aligned (const RIJNDAEL_context *ctx,
+do_encrypt_aligned (const RIJNDAEL_context *ctx,
unsigned char *b, const unsigned char *a)
{
-#define rk (ctx->keySched)
- int ROUNDS = ctx->ROUNDS;
+#define rk (ctx->keyschenc)
+ int rounds = ctx->rounds;
int r;
union
{
byte temp[4][4];
} u;
- *((u32*)u.temp[0]) = *((u32*)(a )) ^ *((u32*)rk[0][0]);
- *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[0][1]);
- *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[0][2]);
- *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[0][3]);
- *((u32*)(b )) = (*((u32*)T1[u.temp[0][0]])
- ^ *((u32*)T2[u.temp[1][1]])
- ^ *((u32*)T3[u.temp[2][2]])
- ^ *((u32*)T4[u.temp[3][3]]));
- *((u32*)(b + 4)) = (*((u32*)T1[u.temp[1][0]])
- ^ *((u32*)T2[u.temp[2][1]])
- ^ *((u32*)T3[u.temp[3][2]])
- ^ *((u32*)T4[u.temp[0][3]]));
- *((u32*)(b + 8)) = (*((u32*)T1[u.temp[2][0]])
- ^ *((u32*)T2[u.temp[3][1]])
- ^ *((u32*)T3[u.temp[0][2]])
- ^ *((u32*)T4[u.temp[1][3]]));
- *((u32*)(b +12)) = (*((u32*)T1[u.temp[3][0]])
- ^ *((u32*)T2[u.temp[0][1]])
- ^ *((u32*)T3[u.temp[1][2]])
- ^ *((u32*)T4[u.temp[2][3]]));
-
- for (r = 1; r < ROUNDS-1; r++)
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[0][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[0][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[0][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[0][3]);
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
+ ^ *((u32_a_t*)T2[u.temp[1][1]])
+ ^ *((u32_a_t*)T3[u.temp[2][2]])
+ ^ *((u32_a_t*)T4[u.temp[3][3]]));
+ *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
+ ^ *((u32_a_t*)T2[u.temp[2][1]])
+ ^ *((u32_a_t*)T3[u.temp[3][2]])
+ ^ *((u32_a_t*)T4[u.temp[0][3]]));
+ *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
+ ^ *((u32_a_t*)T2[u.temp[3][1]])
+ ^ *((u32_a_t*)T3[u.temp[0][2]])
+ ^ *((u32_a_t*)T4[u.temp[1][3]]));
+ *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
+ ^ *((u32_a_t*)T2[u.temp[0][1]])
+ ^ *((u32_a_t*)T3[u.temp[1][2]])
+ ^ *((u32_a_t*)T4[u.temp[2][3]]));
+
+ for (r = 1; r < rounds-1; r++)
{
- *((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[r][0]);
- *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
- *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
- *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
-
- *((u32*)(b )) = (*((u32*)T1[u.temp[0][0]])
- ^ *((u32*)T2[u.temp[1][1]])
- ^ *((u32*)T3[u.temp[2][2]])
- ^ *((u32*)T4[u.temp[3][3]]));
- *((u32*)(b + 4)) = (*((u32*)T1[u.temp[1][0]])
- ^ *((u32*)T2[u.temp[2][1]])
- ^ *((u32*)T3[u.temp[3][2]])
- ^ *((u32*)T4[u.temp[0][3]]));
- *((u32*)(b + 8)) = (*((u32*)T1[u.temp[2][0]])
- ^ *((u32*)T2[u.temp[3][1]])
- ^ *((u32*)T3[u.temp[0][2]])
- ^ *((u32*)T4[u.temp[1][3]]));
- *((u32*)(b +12)) = (*((u32*)T1[u.temp[3][0]])
- ^ *((u32*)T2[u.temp[0][1]])
- ^ *((u32*)T3[u.temp[1][2]])
- ^ *((u32*)T4[u.temp[2][3]]));
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
+
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T1[u.temp[0][0]])
+ ^ *((u32_a_t*)T2[u.temp[1][1]])
+ ^ *((u32_a_t*)T3[u.temp[2][2]])
+ ^ *((u32_a_t*)T4[u.temp[3][3]]));
+ *((u32_a_t*)(b + 4)) = (*((u32_a_t*)T1[u.temp[1][0]])
+ ^ *((u32_a_t*)T2[u.temp[2][1]])
+ ^ *((u32_a_t*)T3[u.temp[3][2]])
+ ^ *((u32_a_t*)T4[u.temp[0][3]]));
+ *((u32_a_t*)(b + 8)) = (*((u32_a_t*)T1[u.temp[2][0]])
+ ^ *((u32_a_t*)T2[u.temp[3][1]])
+ ^ *((u32_a_t*)T3[u.temp[0][2]])
+ ^ *((u32_a_t*)T4[u.temp[1][3]]));
+ *((u32_a_t*)(b +12)) = (*((u32_a_t*)T1[u.temp[3][0]])
+ ^ *((u32_a_t*)T2[u.temp[0][1]])
+ ^ *((u32_a_t*)T3[u.temp[1][2]])
+ ^ *((u32_a_t*)T4[u.temp[2][3]]));
}
- /* Last round is special. */
- *((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[ROUNDS-1][0]);
- *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[ROUNDS-1][1]);
- *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[ROUNDS-1][2]);
- *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[ROUNDS-1][3]);
+ /* Last round is special. */
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[rounds-1][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[rounds-1][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[rounds-1][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[rounds-1][3]);
b[ 0] = T1[u.temp[0][0]][1];
b[ 1] = T1[u.temp[1][1]][1];
b[ 2] = T1[u.temp[2][2]][1];
b[13] = T1[u.temp[0][1]][1];
b[14] = T1[u.temp[1][2]][1];
b[15] = T1[u.temp[2][3]][1];
- *((u32*)(b )) ^= *((u32*)rk[ROUNDS][0]);
- *((u32*)(b+ 4)) ^= *((u32*)rk[ROUNDS][1]);
- *((u32*)(b+ 8)) ^= *((u32*)rk[ROUNDS][2]);
- *((u32*)(b+12)) ^= *((u32*)rk[ROUNDS][3]);
+ *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[rounds][0]);
+ *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[rounds][1]);
+ *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[rounds][2]);
+ *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[rounds][3]);
#undef rk
}
do_encrypt (const RIJNDAEL_context *ctx,
unsigned char *bx, const unsigned char *ax)
{
- /* BX and AX are not necessary correctly aligned. Thus we need to
- copy them here. */
- union
- {
- u32 dummy[4];
- byte a[16];
- } a;
- union
- {
- u32 dummy[4];
- byte b[16];
- } b;
+ /* BX and AX are not necessary correctly aligned. Thus we might
+ need to copy them here. We try to align to a 16 bytes. */
+ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+ {
+ union
+ {
+ u32 dummy[4];
+ byte a[16] ATTR_ALIGNED_16;
+ } a;
+ union
+ {
+ u32 dummy[4];
+ byte b[16] ATTR_ALIGNED_16;
+ } b;
- memcpy (a.a, ax, 16);
- do_encrypt_aligned (ctx, b.b, a.a);
- memcpy (bx, b.b, 16);
+ memcpy (a.a, ax, 16);
+ do_encrypt_aligned (ctx, b.b, a.a);
+ memcpy (bx, b.b, 16);
+ }
+ else
+ {
+ do_encrypt_aligned (ctx, bx, ax);
+ }
}
/* The control word fields are:
127:12 11:10 9 8 7 6 5 4 3:0
RESERVED KSIZE CRYPT INTER KEYGN CIPHR ALIGN DGEST ROUND */
- cword[0] = (ctx->ROUNDS & 15); /* (The mask is just a safeguard.) */
+ cword[0] = (ctx->rounds & 15); /* (The mask is just a safeguard.) */
cword[1] = 0;
cword[2] = 0;
cword[3] = 0;
cword[0] |= 0x00000200;
memcpy (a, ax, 16);
-
- asm volatile
- ("pushfl\n\t" /* Force key reload. */
+
+ asm volatile
+ ("pushfl\n\t" /* Force key reload. */
"popfl\n\t"
"xchg %3, %%ebx\n\t" /* Load key. */
"movl $1, %%ecx\n\t" /* Init counter for just one block. */
".byte 0xf3, 0x0f, 0xa7, 0xc8\n\t" /* REP XSTORE ECB. */
"xchg %3, %%ebx\n" /* Restore GOT register. */
: /* No output */
- : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlock_key)
+ : "S" (a), "D" (b), "d" (cword), "r" (ctx->padlockkey)
: "%ecx", "cc", "memory"
);
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+/* Encrypt one block using the Intel AES-NI instructions. A and B may
+ be the same; they need to be properly aligned to 16 bytes.
+
+ Our problem here is that gcc does not allow the "x" constraint for
+ SSE registers in asm unless you compile with -msse. The common
+ wisdom is to use a separate file for SSE instructions and build it
+ separately. This would require a lot of extra build system stuff,
+ similar to what we do in mpi/ for the asm stuff. What we do
+ instead is to use standard registers and a bit more of plain asm
+ which copies the data and key stuff to the SSE registers and later
+ back. If we decide to implement some block modes with parallelized
+ AES instructions, it might indeed be better to use plain asm ala
+ mpi/. */
+static void
+do_aesni_enc_aligned (const RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ /* Note: For now we relax the alignment requirement for A and B: It
+ does not make much difference because in many case we would need
+ to memcpy them to an extra buffer; using the movdqu is much faster
+ that memcpy and movdqa. For CFB we know that the IV is properly
+ aligned but that is a special case. We should better implement
+ CFB direct in asm. */
+ asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %%xmm0, %[dst]\n"
+ : [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "r" (ctx->keyschenc),
+ [rounds] "r" (ctx->rounds)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+static void
+do_aesni_dec_aligned (const RIJNDAEL_context *ctx,
+ unsigned char *b, const unsigned char *a)
+{
+#define aesdec_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xde, 0xc1\n\t"
+#define aesdeclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdf, 0xc1\n\t"
+ asm volatile ("movdqu %[src], %%xmm0\n\t" /* xmm0 := *a */
+ "movl %[key], %%esi\n\t"
+ "movdqa (%%esi), %%xmm1\n\t"
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Ldeclast%=\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Ldeclast%=\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesdec_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Ldeclast%=:\n\t"
+ aesdeclast_xmm1_xmm0
+ "movdqu %%xmm0, %[dst]\n"
+ : [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "r" (ctx->keyschdec),
+ [rounds] "r" (ctx->rounds)
+ : "%esi", "cc", "memory");
+#undef aesdec_xmm1_xmm0
+#undef aesdeclast_xmm1_xmm0
+}
+
+
+/* Perform a CFB encryption or decryption round using the
+ initialization vector IV and the input block A. Write the result
+ to the output block B and update IV. IV needs to be 16 byte
+ aligned. */
+static void
+do_aesni_cfb (const RIJNDAEL_context *ctx, int decrypt_flag,
+ unsigned char *iv, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ asm volatile ("movdqa %[iv], %%xmm0\n\t" /* xmm0 := IV */
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %[src], %%xmm1\n\t" /* Save input. */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 = input ^ IV */
+
+ "cmp $1, %[decrypt]\n\t"
+ "jz .Ldecrypt_%=\n\t"
+ "movdqa %%xmm0, %[iv]\n\t" /* [encrypt] Store IV. */
+ "jmp .Lleave_%=\n"
+ ".Ldecrypt_%=:\n\t"
+ "movdqa %%xmm1, %[iv]\n" /* [decrypt] Store IV. */
+ ".Lleave_%=:\n\t"
+ "movdqu %%xmm0, %[dst]\n" /* Store output. */
+ : [iv] "+m" (*iv), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [decrypt] "m" (decrypt_flag)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+/* Perform a CTR encryption round using the counter CTR and the input
+ block A. Write the result to the output block B and update CTR.
+ CTR needs to be a 16 byte aligned little-endian value. */
+static void
+do_aesni_ctr (const RIJNDAEL_context *ctx,
+ unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+ static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */
+ "movaps %%xmm0, %%xmm2\n\t"
+ "mov $1, %%esi\n\t" /* xmm2++ (big-endian) */
+ "movd %%esi, %%xmm1\n\t"
+ "pshufb %[mask], %%xmm2\n\t"
+ "paddq %%xmm1, %%xmm2\n\t"
+ "pshufb %[mask], %%xmm2\n\t"
+ "movdqa %%xmm2, %[ctr]\n" /* Update CTR. */
+
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ "movdqu %[src], %%xmm1\n\t" /* xmm1 := input */
+ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR ^= input */
+ "movdqu %%xmm0, %[dst]" /* Store EncCTR. */
+
+ : [ctr] "+m" (*ctr), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [mask] "m" (*be_mask)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenclast_xmm1_xmm0
+}
+
+
+/* Four blocks at a time variant of do_aesni_ctr. */
+static void
+do_aesni_ctr_4 (const RIJNDAEL_context *ctx,
+ unsigned char *ctr, unsigned char *b, const unsigned char *a)
+{
+#define aesenc_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xc1\n\t"
+#define aesenc_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd1\n\t"
+#define aesenc_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xd9\n\t"
+#define aesenc_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdc, 0xe1\n\t"
+#define aesenclast_xmm1_xmm0 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xc1\n\t"
+#define aesenclast_xmm1_xmm2 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd1\n\t"
+#define aesenclast_xmm1_xmm3 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xd9\n\t"
+#define aesenclast_xmm1_xmm4 ".byte 0x66, 0x0f, 0x38, 0xdd, 0xe1\n\t"
+
+ static unsigned char be_mask[16] __attribute__ ((aligned (16))) =
+ { 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0 };
+
+ /* Register usage:
+ esi keyschedule
+ xmm0 CTR-0
+ xmm1 temp / round key
+ xmm2 CTR-1
+ xmm3 CTR-2
+ xmm4 CTR-3
+ xmm5 temp
+ */
+
+ asm volatile ("movdqa %[ctr], %%xmm0\n\t" /* xmm0, xmm2 := CTR */
+ "movaps %%xmm0, %%xmm2\n\t"
+ "mov $1, %%esi\n\t" /* xmm1 := 1 */
+ "movd %%esi, %%xmm1\n\t"
+ "pshufb %[mask], %%xmm2\n\t" /* xmm2 := le(xmm2) */
+ "paddq %%xmm1, %%xmm2\n\t" /* xmm2++ */
+ "movaps %%xmm2, %%xmm3\n\t" /* xmm3 := xmm2 */
+ "paddq %%xmm1, %%xmm3\n\t" /* xmm3++ */
+ "movaps %%xmm3, %%xmm4\n\t" /* xmm4 := xmm3 */
+ "paddq %%xmm1, %%xmm4\n\t" /* xmm4++ */
+ "movaps %%xmm4, %%xmm5\n\t" /* xmm5 := xmm4 */
+ "paddq %%xmm1, %%xmm5\n\t" /* xmm5++ */
+ "pshufb %[mask], %%xmm2\n\t" /* xmm2 := be(xmm2) */
+ "pshufb %[mask], %%xmm3\n\t" /* xmm3 := be(xmm3) */
+ "pshufb %[mask], %%xmm4\n\t" /* xmm4 := be(xmm4) */
+ "pshufb %[mask], %%xmm5\n\t" /* xmm5 := be(xmm5) */
+ "movdqa %%xmm5, %[ctr]\n" /* Update CTR. */
+
+ "movl %[key], %%esi\n\t" /* esi := keyschenc */
+ "movdqa (%%esi), %%xmm1\n\t" /* xmm1 := key[0] */
+ "pxor %%xmm1, %%xmm0\n\t" /* xmm0 ^= key[0] */
+ "pxor %%xmm1, %%xmm2\n\t" /* xmm2 ^= key[0] */
+ "pxor %%xmm1, %%xmm3\n\t" /* xmm3 ^= key[0] */
+ "pxor %%xmm1, %%xmm4\n\t" /* xmm4 ^= key[0] */
+ "movdqa 0x10(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x20(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x30(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x40(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x50(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x60(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x70(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x80(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0x90(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xa0(%%esi), %%xmm1\n\t"
+ "cmp $10, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xb0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xc0(%%esi), %%xmm1\n\t"
+ "cmp $12, %[rounds]\n\t"
+ "jz .Lenclast%=\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xd0(%%esi), %%xmm1\n\t"
+ aesenc_xmm1_xmm0
+ aesenc_xmm1_xmm2
+ aesenc_xmm1_xmm3
+ aesenc_xmm1_xmm4
+ "movdqa 0xe0(%%esi), %%xmm1\n"
+
+ ".Lenclast%=:\n\t"
+ aesenclast_xmm1_xmm0
+ aesenclast_xmm1_xmm2
+ aesenclast_xmm1_xmm3
+ aesenclast_xmm1_xmm4
+
+ "movdqu %[src], %%xmm1\n\t" /* Get block 1. */
+ "pxor %%xmm1, %%xmm0\n\t" /* EncCTR-1 ^= input */
+ "movdqu %%xmm0, %[dst]\n\t" /* Store block 1 */
+
+ "movdqu (16)%[src], %%xmm1\n\t" /* Get block 2. */
+ "pxor %%xmm1, %%xmm2\n\t" /* EncCTR-2 ^= input */
+ "movdqu %%xmm2, (16)%[dst]\n\t" /* Store block 2. */
+
+ "movdqu (32)%[src], %%xmm1\n\t" /* Get block 3. */
+ "pxor %%xmm1, %%xmm3\n\t" /* EncCTR-3 ^= input */
+ "movdqu %%xmm3, (32)%[dst]\n\t" /* Store block 3. */
+
+ "movdqu (48)%[src], %%xmm1\n\t" /* Get block 4. */
+ "pxor %%xmm1, %%xmm4\n\t" /* EncCTR-4 ^= input */
+ "movdqu %%xmm4, (48)%[dst]" /* Store block 4. */
+
+ : [ctr] "+m" (*ctr), [dst] "=m" (*b)
+ : [src] "m" (*a),
+ [key] "g" (ctx->keyschenc),
+ [rounds] "g" (ctx->rounds),
+ [mask] "m" (*be_mask)
+ : "%esi", "cc", "memory");
+#undef aesenc_xmm1_xmm0
+#undef aesenc_xmm1_xmm2
+#undef aesenc_xmm1_xmm3
+#undef aesenc_xmm1_xmm4
+#undef aesenclast_xmm1_xmm0
+#undef aesenclast_xmm1_xmm2
+#undef aesenclast_xmm1_xmm3
+#undef aesenclast_xmm1_xmm4
+}
+
+
+static void
+do_aesni (RIJNDAEL_context *ctx, int decrypt_flag,
+ unsigned char *bx, const unsigned char *ax)
+{
+
+ if (decrypt_flag)
+ {
+ if (!ctx->decryption_prepared )
+ {
+ prepare_decryption ( ctx );
+ ctx->decryption_prepared = 1;
+ }
+ do_aesni_dec_aligned (ctx, bx, ax);
+ }
+ else
+ do_aesni_enc_aligned (ctx, bx, ax);
+}
+#endif /*USE_AESNI*/
+
+
static void
rijndael_encrypt (void *context, byte *b, const byte *a)
{
RIJNDAEL_context *ctx = context;
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
{
do_padlock (ctx, 0, b, a);
_gcry_burn_stack (48 + 15 /* possible padding for alignment */);
}
- else
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ do_aesni (ctx, 0, b, a);
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
{
do_encrypt (ctx, b, a);
- _gcry_burn_stack (48 + 2*sizeof(int));
+ _gcry_burn_stack (56 + 2*sizeof(int));
}
}
function is only intended for the bulk encryption feature of
cipher.c. */
void
-_gcry_aes_cfb_enc (void *context, unsigned char *iv,
+_gcry_aes_cfb_enc (void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks)
{
unsigned char *ivp;
int i;
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
{
/* Fixme: Let Padlock do the CFBing. */
for ( ;nblocks; nblocks-- )
*outbuf++ = (*ivp++ ^= *inbuf++);
}
}
+#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_cfb (ctx, 0, iv, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
else
-#endif /* USE_PADLOCK*/
{
for ( ;nblocks; nblocks-- )
{
function is only intended for the bulk encryption feature of
cipher.c. */
void
-_gcry_aes_cbc_enc (void *context, unsigned char *iv,
+_gcry_aes_cbc_enc (void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks, int cbc_mac)
{
unsigned char *ivp;
int i;
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
+ aesni_prepare ();
+#endif /*USE_AESNI*/
+
for ( ;nblocks; nblocks-- )
{
for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
outbuf[i] = inbuf[i] ^ *ivp++;
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
do_padlock (ctx, 0, outbuf, outbuf);
- else
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ do_aesni (ctx, 0, outbuf, outbuf);
+#endif /*USE_AESNI*/
+ else
do_encrypt (ctx, outbuf, outbuf );
memcpy (iv, outbuf, BLOCKSIZE);
outbuf += BLOCKSIZE;
}
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
+ aesni_cleanup ();
+#endif /*USE_AESNI*/
+
+ _gcry_burn_stack (48 + 2*sizeof(int));
+}
+
+
+/* Bulk encryption of complete blocks in CTR mode. Caller needs to
+ make sure that CTR is aligned on a 16 byte boundary if AESNI; the
+ minimum alignment is for an u32. This function is only intended
+ for the bulk encryption feature of cipher.c. CTR is expected to be
+ of size BLOCKSIZE. */
+void
+_gcry_aes_ctr_enc (void *context, unsigned char *ctr,
+ void *outbuf_arg, const void *inbuf_arg,
+ unsigned int nblocks)
+{
+ RIJNDAEL_context *ctx = context;
+ unsigned char *outbuf = outbuf_arg;
+ const unsigned char *inbuf = inbuf_arg;
+ unsigned char *p;
+ int i;
+
+ if (0)
+ ;
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks > 3 ; nblocks -= 4 )
+ {
+ do_aesni_ctr_4 (ctx, ctr, outbuf, inbuf);
+ outbuf += 4*BLOCKSIZE;
+ inbuf += 4*BLOCKSIZE;
+ }
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_ctr (ctx, ctr, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ aesni_cleanup_2_4 ();
+ }
+#endif /*USE_AESNI*/
+ else
+ {
+ union { unsigned char x1[16]; u32 x32[4]; } tmp;
+
+ for ( ;nblocks; nblocks-- )
+ {
+ /* Encrypt the counter. */
+ do_encrypt_aligned (ctx, tmp.x1, ctr);
+ /* XOR the input with the encrypted counter and store in output. */
+ for (p=tmp.x1, i=0; i < BLOCKSIZE; i++)
+ *outbuf++ = (*p++ ^= *inbuf++);
+ /* Increment the counter. */
+ for (i = BLOCKSIZE; i > 0; i--)
+ {
+ ctr[i-1]++;
+ if (ctr[i-1])
+ break;
+ }
+ }
+ }
+
_gcry_burn_stack (48 + 2*sizeof(int));
}
and the decryption must have been prepared. A and B may be the
same. */
static void
-do_decrypt_aligned (RIJNDAEL_context *ctx,
+do_decrypt_aligned (RIJNDAEL_context *ctx,
unsigned char *b, const unsigned char *a)
{
-#define rk (ctx->keySched2)
- int ROUNDS = ctx->ROUNDS;
+#define rk (ctx->keyschdec)
+ int rounds = ctx->rounds;
int r;
- union
+ union
{
u32 tempu32[4]; /* Force correct alignment. */
byte temp[4][4];
} u;
- *((u32*)u.temp[0]) = *((u32*)(a )) ^ *((u32*)rk[ROUNDS][0]);
- *((u32*)u.temp[1]) = *((u32*)(a+ 4)) ^ *((u32*)rk[ROUNDS][1]);
- *((u32*)u.temp[2]) = *((u32*)(a+ 8)) ^ *((u32*)rk[ROUNDS][2]);
- *((u32*)u.temp[3]) = *((u32*)(a+12)) ^ *((u32*)rk[ROUNDS][3]);
-
- *((u32*)(b )) = (*((u32*)T5[u.temp[0][0]])
- ^ *((u32*)T6[u.temp[3][1]])
- ^ *((u32*)T7[u.temp[2][2]])
- ^ *((u32*)T8[u.temp[1][3]]));
- *((u32*)(b+ 4)) = (*((u32*)T5[u.temp[1][0]])
- ^ *((u32*)T6[u.temp[0][1]])
- ^ *((u32*)T7[u.temp[3][2]])
- ^ *((u32*)T8[u.temp[2][3]]));
- *((u32*)(b+ 8)) = (*((u32*)T5[u.temp[2][0]])
- ^ *((u32*)T6[u.temp[1][1]])
- ^ *((u32*)T7[u.temp[0][2]])
- ^ *((u32*)T8[u.temp[3][3]]));
- *((u32*)(b+12)) = (*((u32*)T5[u.temp[3][0]])
- ^ *((u32*)T6[u.temp[2][1]])
- ^ *((u32*)T7[u.temp[1][2]])
- ^ *((u32*)T8[u.temp[0][3]]));
-
- for (r = ROUNDS-1; r > 1; r--)
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(a )) ^ *((u32_a_t*)rk[rounds][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(a+ 4)) ^ *((u32_a_t*)rk[rounds][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(a+ 8)) ^ *((u32_a_t*)rk[rounds][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(a+12)) ^ *((u32_a_t*)rk[rounds][3]);
+
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]])
+ ^ *((u32_a_t*)T6[u.temp[3][1]])
+ ^ *((u32_a_t*)T7[u.temp[2][2]])
+ ^ *((u32_a_t*)T8[u.temp[1][3]]));
+ *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]])
+ ^ *((u32_a_t*)T6[u.temp[0][1]])
+ ^ *((u32_a_t*)T7[u.temp[3][2]])
+ ^ *((u32_a_t*)T8[u.temp[2][3]]));
+ *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]])
+ ^ *((u32_a_t*)T6[u.temp[1][1]])
+ ^ *((u32_a_t*)T7[u.temp[0][2]])
+ ^ *((u32_a_t*)T8[u.temp[3][3]]));
+ *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]])
+ ^ *((u32_a_t*)T6[u.temp[2][1]])
+ ^ *((u32_a_t*)T7[u.temp[1][2]])
+ ^ *((u32_a_t*)T8[u.temp[0][3]]));
+
+ for (r = rounds-1; r > 1; r--)
{
- *((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[r][0]);
- *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[r][1]);
- *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[r][2]);
- *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[r][3]);
- *((u32*)(b )) = (*((u32*)T5[u.temp[0][0]])
- ^ *((u32*)T6[u.temp[3][1]])
- ^ *((u32*)T7[u.temp[2][2]])
- ^ *((u32*)T8[u.temp[1][3]]));
- *((u32*)(b+ 4)) = (*((u32*)T5[u.temp[1][0]])
- ^ *((u32*)T6[u.temp[0][1]])
- ^ *((u32*)T7[u.temp[3][2]])
- ^ *((u32*)T8[u.temp[2][3]]));
- *((u32*)(b+ 8)) = (*((u32*)T5[u.temp[2][0]])
- ^ *((u32*)T6[u.temp[1][1]])
- ^ *((u32*)T7[u.temp[0][2]])
- ^ *((u32*)T8[u.temp[3][3]]));
- *((u32*)(b+12)) = (*((u32*)T5[u.temp[3][0]])
- ^ *((u32*)T6[u.temp[2][1]])
- ^ *((u32*)T7[u.temp[1][2]])
- ^ *((u32*)T8[u.temp[0][3]]));
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[r][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[r][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[r][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[r][3]);
+ *((u32_a_t*)(b )) = (*((u32_a_t*)T5[u.temp[0][0]])
+ ^ *((u32_a_t*)T6[u.temp[3][1]])
+ ^ *((u32_a_t*)T7[u.temp[2][2]])
+ ^ *((u32_a_t*)T8[u.temp[1][3]]));
+ *((u32_a_t*)(b+ 4)) = (*((u32_a_t*)T5[u.temp[1][0]])
+ ^ *((u32_a_t*)T6[u.temp[0][1]])
+ ^ *((u32_a_t*)T7[u.temp[3][2]])
+ ^ *((u32_a_t*)T8[u.temp[2][3]]));
+ *((u32_a_t*)(b+ 8)) = (*((u32_a_t*)T5[u.temp[2][0]])
+ ^ *((u32_a_t*)T6[u.temp[1][1]])
+ ^ *((u32_a_t*)T7[u.temp[0][2]])
+ ^ *((u32_a_t*)T8[u.temp[3][3]]));
+ *((u32_a_t*)(b+12)) = (*((u32_a_t*)T5[u.temp[3][0]])
+ ^ *((u32_a_t*)T6[u.temp[2][1]])
+ ^ *((u32_a_t*)T7[u.temp[1][2]])
+ ^ *((u32_a_t*)T8[u.temp[0][3]]));
}
- /* Last round is special. */
- *((u32*)u.temp[0]) = *((u32*)(b )) ^ *((u32*)rk[1][0]);
- *((u32*)u.temp[1]) = *((u32*)(b+ 4)) ^ *((u32*)rk[1][1]);
- *((u32*)u.temp[2]) = *((u32*)(b+ 8)) ^ *((u32*)rk[1][2]);
- *((u32*)u.temp[3]) = *((u32*)(b+12)) ^ *((u32*)rk[1][3]);
+ /* Last round is special. */
+ *((u32_a_t*)u.temp[0]) = *((u32_a_t*)(b )) ^ *((u32_a_t*)rk[1][0]);
+ *((u32_a_t*)u.temp[1]) = *((u32_a_t*)(b+ 4)) ^ *((u32_a_t*)rk[1][1]);
+ *((u32_a_t*)u.temp[2]) = *((u32_a_t*)(b+ 8)) ^ *((u32_a_t*)rk[1][2]);
+ *((u32_a_t*)u.temp[3]) = *((u32_a_t*)(b+12)) ^ *((u32_a_t*)rk[1][3]);
b[ 0] = S5[u.temp[0][0]];
b[ 1] = S5[u.temp[3][1]];
b[ 2] = S5[u.temp[2][2]];
b[13] = S5[u.temp[2][1]];
b[14] = S5[u.temp[1][2]];
b[15] = S5[u.temp[0][3]];
- *((u32*)(b )) ^= *((u32*)rk[0][0]);
- *((u32*)(b+ 4)) ^= *((u32*)rk[0][1]);
- *((u32*)(b+ 8)) ^= *((u32*)rk[0][2]);
- *((u32*)(b+12)) ^= *((u32*)rk[0][3]);
+ *((u32_a_t*)(b )) ^= *((u32_a_t*)rk[0][0]);
+ *((u32_a_t*)(b+ 4)) ^= *((u32_a_t*)rk[0][1]);
+ *((u32_a_t*)(b+ 8)) ^= *((u32_a_t*)rk[0][2]);
+ *((u32_a_t*)(b+12)) ^= *((u32_a_t*)rk[0][3]);
#undef rk
}
static void
do_decrypt (RIJNDAEL_context *ctx, byte *bx, const byte *ax)
{
- /* BX and AX are not necessary correctly aligned. Thus we need to
- copy them here. */
- union
- {
- u32 dummy[4];
- byte a[16];
- } a;
- union
- {
- u32 dummy[4];
- byte b[16];
- } b;
-
if ( !ctx->decryption_prepared )
{
prepare_decryption ( ctx );
ctx->decryption_prepared = 1;
}
- memcpy (a.a, ax, 16);
- do_decrypt_aligned (ctx, b.b, a.a);
- memcpy (bx, b.b, 16);
-#undef rk
+ /* BX and AX are not necessary correctly aligned. Thus we might
+ need to copy them here. We try to align to a 16 bytes. */
+ if (((size_t)ax & 0x0f) || ((size_t)bx & 0x0f))
+ {
+ union
+ {
+ u32 dummy[4];
+ byte a[16] ATTR_ALIGNED_16;
+ } a;
+ union
+ {
+ u32 dummy[4];
+ byte b[16] ATTR_ALIGNED_16;
+ } b;
+
+ memcpy (a.a, ax, 16);
+ do_decrypt_aligned (ctx, b.b, a.a);
+ memcpy (bx, b.b, 16);
+ }
+ else
+ {
+ do_decrypt_aligned (ctx, bx, ax);
+ }
}
-
+
{
RIJNDAEL_context *ctx = context;
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
{
do_padlock (ctx, 1, b, a);
_gcry_burn_stack (48 + 2*sizeof(int) /* FIXME */);
}
- else
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ do_aesni (ctx, 1, b, a);
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
{
do_decrypt (ctx, b, a);
- _gcry_burn_stack (48+2*sizeof(int));
+ _gcry_burn_stack (56+2*sizeof(int));
}
}
function is only intended for the bulk encryption feature of
cipher.c. */
void
-_gcry_aes_cfb_dec (void *context, unsigned char *iv,
+_gcry_aes_cfb_dec (void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks)
{
unsigned char temp;
int i;
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
{
/* Fixme: Let Padlock do the CFBing. */
for ( ;nblocks; nblocks-- )
}
}
}
- else
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ {
+ aesni_prepare ();
+ for ( ;nblocks; nblocks-- )
+ {
+ do_aesni_cfb (ctx, 1, iv, outbuf, inbuf);
+ outbuf += BLOCKSIZE;
+ inbuf += BLOCKSIZE;
+ }
+ aesni_cleanup ();
+ }
+#endif /*USE_AESNI*/
+ else
{
for ( ;nblocks; nblocks-- )
{
function is only intended for the bulk encryption feature of
cipher.c. */
void
-_gcry_aes_cbc_dec (void *context, unsigned char *iv,
+_gcry_aes_cbc_dec (void *context, unsigned char *iv,
void *outbuf_arg, const void *inbuf_arg,
unsigned int nblocks)
{
int i;
unsigned char savebuf[BLOCKSIZE];
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
+ aesni_prepare ();
+#endif /*USE_AESNI*/
+
for ( ;nblocks; nblocks-- )
{
/* We need to save INBUF away because it may be identical to
OUTBUF. */
memcpy (savebuf, inbuf, BLOCKSIZE);
+ if (0)
+ ;
#ifdef USE_PADLOCK
- if (ctx->use_padlock)
+ else if (ctx->use_padlock)
do_padlock (ctx, 1, outbuf, inbuf);
- else
#endif /*USE_PADLOCK*/
+#ifdef USE_AESNI
+ else if (ctx->use_aesni)
+ do_aesni (ctx, 1, outbuf, inbuf);
+#endif /*USE_AESNI*/
+ else
do_decrypt (ctx, outbuf, inbuf);
for (ivp=iv, i=0; i < BLOCKSIZE; i++ )
outbuf += BLOCKSIZE;
}
+#ifdef USE_AESNI
+ if (ctx->use_aesni)
+ aesni_cleanup ();
+#endif /*USE_AESNI*/
+
_gcry_burn_stack (48 + 2*sizeof(int) + BLOCKSIZE + 4*sizeof (char*));
}
selftest_basic_128 (void)
{
RIJNDAEL_context ctx;
- unsigned char scratch[16];
+ unsigned char scratch[16];
/* The test vectors are from the AES supplied ones; more or less
randomly taken from ecb_tbl.txt (I=42,81,14) */
- static const unsigned char plaintext_128[16] =
+#if 1
+ static const unsigned char plaintext_128[16] =
{
0x01,0x4B,0xAF,0x22,0x78,0xA6,0x9D,0x33,
0x1D,0x51,0x80,0x10,0x36,0x43,0xE9,0x9A
0x67,0x43,0xC3,0xD1,0x51,0x9A,0xB4,0xF2,
0xCD,0x9A,0x78,0xAB,0x09,0xA5,0x11,0xBD
};
-
+#else
+ /* Test vectors from fips-197, appendix C. */
+# warning debug test vectors in use
+ static const unsigned char plaintext_128[16] =
+ {
+ 0x00,0x11,0x22,0x33,0x44,0x55,0x66,0x77,
+ 0x88,0x99,0xaa,0xbb,0xcc,0xdd,0xee,0xff
+ };
+ static const unsigned char key_128[16] =
+ {
+ 0x00,0x01,0x02,0x03,0x04,0x05,0x06,0x07,
+ 0x08,0x09,0x0a,0x0b,0x0c,0x0d,0x0e,0x0f
+ /* 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6, */
+ /* 0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c */
+ };
+ static const unsigned char ciphertext_128[16] =
+ {
+ 0x69,0xc4,0xe0,0xd8,0x6a,0x7b,0x04,0x30,
+ 0xd8,0xcd,0xb7,0x80,0x70,0xb4,0xc5,0x5a
+ };
+#endif
+
rijndael_setkey (&ctx, key_128, sizeof (key_128));
rijndael_encrypt (&ctx, scratch, plaintext_128);
if (memcmp (scratch, ciphertext_128, sizeof (ciphertext_128)))
rijndael_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_128, sizeof (plaintext_128)))
return "AES-128 test decryption failed.";
-
+
return NULL;
}
selftest_basic_192 (void)
{
RIJNDAEL_context ctx;
- unsigned char scratch[16];
-
- static unsigned char plaintext_192[16] =
+ unsigned char scratch[16];
+
+ static unsigned char plaintext_192[16] =
{
0x76,0x77,0x74,0x75,0xF1,0xF2,0xF3,0xF4,
0xF8,0xF9,0xE6,0xE7,0x77,0x70,0x71,0x72
};
- static unsigned char key_192[24] =
+ static unsigned char key_192[24] =
{
0x04,0x05,0x06,0x07,0x09,0x0A,0x0B,0x0C,
0x0E,0x0F,0x10,0x11,0x13,0x14,0x15,0x16,
0x5D,0x1E,0xF2,0x0D,0xCE,0xD6,0xBC,0xBC,
0x12,0x13,0x1A,0xC7,0xC5,0x47,0x88,0xAA
};
-
+
rijndael_setkey (&ctx, key_192, sizeof(key_192));
rijndael_encrypt (&ctx, scratch, plaintext_192);
if (memcmp (scratch, ciphertext_192, sizeof (ciphertext_192)))
rijndael_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_192, sizeof (plaintext_192)))
return "AES-192 test decryption failed.";
-
+
return NULL;
}
selftest_basic_256 (void)
{
RIJNDAEL_context ctx;
- unsigned char scratch[16];
+ unsigned char scratch[16];
- static unsigned char plaintext_256[16] =
+ static unsigned char plaintext_256[16] =
{
0x06,0x9A,0x00,0x7F,0xC7,0x6A,0x45,0x9F,
0x98,0xBA,0xF9,0x17,0xFE,0xDF,0x95,0x21
};
- static unsigned char key_256[32] =
+ static unsigned char key_256[32] =
{
0x08,0x09,0x0A,0x0B,0x0D,0x0E,0x0F,0x10,
0x12,0x13,0x14,0x15,0x17,0x18,0x19,0x1A,
0x1C,0x1D,0x1E,0x1F,0x21,0x22,0x23,0x24,
0x26,0x27,0x28,0x29,0x2B,0x2C,0x2D,0x2E
};
- static const unsigned char ciphertext_256[16] =
+ static const unsigned char ciphertext_256[16] =
{
0x08,0x0E,0x95,0x17,0xEB,0x16,0x77,0x71,
0x9A,0xCF,0x72,0x80,0x86,0x04,0x0A,0xE3
rijndael_decrypt (&ctx, scratch, scratch);
if (memcmp (scratch, plaintext_256, sizeof (plaintext_256)))
return "AES-256 test decryption failed.";
-
+
return NULL;
}
int mode;
const unsigned char key[16];
const unsigned char iv[16];
- struct
+ struct
{
const unsigned char input[16];
const unsigned char output[16];
GCRY_CIPHER_MODE_CFB, /* F.3.13, CFB128-AES128 */
{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{
{ { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0xe9, 0x3d, 0x7e, 0x11, 0x73, 0x93, 0x17, 0x2a },
{ 0x3b, 0x3f, 0xd9, 0x2e, 0xb7, 0x2d, 0xad, 0x20,
0x33, 0x34, 0x49, 0xf8, 0xe8, 0x3c, 0xfb, 0x4a } },
-
+
{ { 0xae, 0x2d, 0x8a, 0x57, 0x1e, 0x03, 0xac, 0x9c,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
{ 0xc8, 0xa6, 0x45, 0x37, 0xa0, 0xb3, 0xa9, 0x3f,
0xcd, 0xe3, 0xcd, 0xad, 0x9f, 0x1c, 0xe5, 0x8b } },
-
- { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
+
+ { { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
{ 0x26, 0x75, 0x1f, 0x67, 0xa3, 0xcb, 0xb1, 0x40,
0xb1, 0x80, 0x8c, 0xf1, 0x87, 0xa4, 0xf4, 0xdf } },
-
+
{ { 0xf6, 0x9f, 0x24, 0x45, 0xdf, 0x4f, 0x9b, 0x17,
0xad, 0x2b, 0x41, 0x7b, 0xe6, 0x6c, 0x37, 0x10 },
{ 0xc0, 0x4b, 0x05, 0x35, 0x7c, 0x5d, 0x1c, 0x0e,
GCRY_CIPHER_MODE_OFB,
{ 0x2b, 0x7e, 0x15, 0x16, 0x28, 0xae, 0xd2, 0xa6,
0xab, 0xf7, 0x15, 0x88, 0x09, 0xcf, 0x4f, 0x3c },
- { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
{
{ { 0x6b, 0xc1, 0xbe, 0xe2, 0x2e, 0x40, 0x9f, 0x96,
0x9e, 0xb7, 0x6f, 0xac, 0x45, 0xaf, 0x8e, 0x51 },
{ 0x77, 0x89, 0x50, 0x8d, 0x16, 0x91, 0x8f, 0x03,
0xf5, 0x3c, 0x52, 0xda, 0xc5, 0x4e, 0xd8, 0x25 } },
-
+
{ { 0x30, 0xc8, 0x1c, 0x46, 0xa3, 0x5c, 0xe4, 0x11,
0xe5, 0xfb, 0xc1, 0x19, 0x1a, 0x0a, 0x52, 0xef },
{ 0x97, 0x40, 0x05, 0x1e, 0x9c, 0x5f, 0xec, 0xf6,
#undef Fail
_gcry_cipher_close (hdenc);
- _gcry_cipher_close (hddec);
+ _gcry_cipher_close (hddec);
return NULL;
}
{
const char *what;
const char *errtxt;
-
+
what = "low-level";
errtxt = selftest_basic_128 ();
if (errtxt)
errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_CFB);
if (errtxt)
goto failed;
-
+
what = "ofb";
errtxt = selftest_fips_128_38a (GCRY_CIPHER_MODE_OFB);
if (errtxt)
{
const char *what;
const char *errtxt;
-
+
(void)extended; /* No extended tests available. */
what = "low-level";
default:
ec = GPG_ERR_CIPHER_ALGO;
break;
-
+
}
return ec;
}
"AES", rijndael_names, rijndael_oids, 16, 128, sizeof (RIJNDAEL_context),
rijndael_setkey, rijndael_encrypt, rijndael_decrypt
};
-cipher_extra_spec_t _gcry_cipher_extraspec_aes =
+cipher_extra_spec_t _gcry_cipher_extraspec_aes =
{
run_selftests
};
"AES192", rijndael192_names, rijndael192_oids, 16, 192, sizeof (RIJNDAEL_context),
rijndael_setkey, rijndael_encrypt, rijndael_decrypt
};
-cipher_extra_spec_t _gcry_cipher_extraspec_aes192 =
+cipher_extra_spec_t _gcry_cipher_extraspec_aes192 =
{
run_selftests
};
rijndael_setkey, rijndael_encrypt, rijndael_decrypt
};
-cipher_extra_spec_t _gcry_cipher_extraspec_aes256 =
+cipher_extra_spec_t _gcry_cipher_extraspec_aes256 =
{
run_selftests
};
/* We need this here because random.c must have direct access. */
-typedef struct
+typedef struct
{
u32 h0,h1,h2,h3,h4;
u32 nblocks;
void _gcry_rmd160_mixblock ( RMD160_CONTEXT *hd, void *blockof64byte );
#endif /*G10_RMD_H*/
-
}
if( !inbuf )
return;
- if( hd->count )
+ if( hd->count )
{
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
RMD160_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
-
+
rmd160_write(hd, NULL, 0); /* flush */;
t = hd->nblocks;
" (u #304559a9ead56d2309d203811a641bb1a09626bc8eb36fffa23c968ec5bd891e"
" ebbafc73ae666e01ba7c8990bae06cc2bbe10b75e69fcacb353a6473079d8e9b#)))";
/* A sample 1024 bit RSA key used for the selftests (public only). */
-static const char sample_public_key[] =
+static const char sample_public_key[] =
"(public-key"
" (rsa"
" (n #00e0ce96f90b6c9e02f3922beada93fe50a875eac6bcc18bb9a9cf2e84965caa"
/* Use the RSA secret function to create a signature of the plaintext. */
secret (signature, plaintext, sk);
-
+
/* Use the RSA public function to verify this signature. */
public (decr_plaintext, signature, &pk);
if (gcry_mpi_cmp (decr_plaintext, plaintext))
gcry_mpi_t e = arg;
gcry_mpi_t tmp;
int result;
-
+
mpi_sub_ui (a, a, 1);
tmp = _gcry_mpi_alloc_like (a);
result = !gcry_mpi_gcd(tmp, e, a); /* GCD is not 1. */
}
/****************
- * Generate a key pair with a key of size NBITS.
+ * Generate a key pair with a key of size NBITS.
* USE_E = 0 let Libcgrypt decide what exponent to use.
- * = 1 request the use of a "secure" exponent; this is required by some
+ * = 1 request the use of a "secure" exponent; this is required by some
* specification to be 65537.
* > 2 Use this public exponent. If the given exponent
- * is not odd one is internally added to it.
+ * is not odd one is internally added to it.
* TRANSIENT_KEY: If true, generate the primes using the standard RNG.
* Returns: 2 structures filled with all needed values
*/
/* Make sure that nbits is even so that we generate p, q of equal size. */
if ( (nbits&1) )
- nbits++;
+ nbits++;
if (use_e == 1) /* Alias for a secure value */
use_e = 65537; /* as demanded by Sphinx. */
/* Public exponent:
In general we use 41 as this is quite fast and more secure than the
commonly used 17. Benchmarking the RSA verify function
- with a 1024 bit key yields (2001-11-08):
+ with a 1024 bit key yields (2001-11-08):
e=17 0.54 ms
e=41 0.75 ms
e=257 0.95 ms
e = mpi_alloc( (32+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
if (!use_e)
mpi_set_ui (e, 41); /* This is a reasonable secure and fast value */
- else
+ else
{
use_e |= 1; /* make sure this is odd */
- mpi_set_ui (e, use_e);
+ mpi_set_ui (e, use_e);
}
-
+
n = gcry_mpi_new (nbits);
p = q = NULL;
/* Helper for generate_x931. */
-static gcry_mpi_t
+static gcry_mpi_t
gen_x931_parm_xp (unsigned int nbits)
{
gcry_mpi_t xp;
xp = gcry_mpi_snew (nbits);
gcry_mpi_randomize (xp, nbits, GCRY_VERY_STRONG_RANDOM);
-
+
/* The requirement for Xp is:
sqrt{2}*2^{nbits-1} <= xp <= 2^{nbits} - 1
mpi_set_highbit (xp, nbits-1);
mpi_set_bit (xp, nbits-2);
gcry_assert ( mpi_get_nbits (xp) == nbits );
-
+
return xp;
-}
+}
/* Helper for generate_x931. */
-static gcry_mpi_t
+static gcry_mpi_t
gen_x931_parm_xi (void)
{
gcry_mpi_t xi;
gcry_mpi_randomize (xi, 101, GCRY_VERY_STRONG_RANDOM);
mpi_set_highbit (xi, 100);
gcry_assert ( mpi_get_nbits (xi) == 101 );
-
+
return xi;
-}
+}
*swapped = 0;
if (e_value == 1) /* Alias for a secure value. */
- e_value = 65537;
+ e_value = 65537;
/* Point 1 of section 4.1: k = 1024 + 256s with S >= 0 */
if (nbits < 1024 || (nbits % 256))
return GPG_ERR_INV_VALUE;
-
+
/* Point 2: 2 <= bitlength(e) < 2^{k-2}
Note that we do not need to check the upper bound because we use
an unsigned long for E and thus there is no way for E to reach
that limit. */
if (e_value < 3)
return GPG_ERR_INV_VALUE;
-
+
/* Our implementaion requires E to be odd. */
if (!(e_value & 1))
return GPG_ERR_INV_VALUE;
};
int idx;
gcry_sexp_t oneparm;
-
+
tbl[0].value = &xp1;
tbl[1].value = &xp2;
tbl[2].value = &xp;
return GPG_ERR_MISSING_VALUE;
}
}
-
- e = mpi_alloc_set_ui (e_value);
+
+ e = mpi_alloc_set_ui (e_value);
/* Find two prime numbers. */
p = _gcry_derive_x931_prime (xp, xp1, xp2, e, NULL, NULL);
gcry_mpi_release (xp); xp = NULL;
gcry_mpi_release (xp1); xp1 = NULL;
gcry_mpi_release (xp2); xp2 = NULL;
- gcry_mpi_release (xq); xq = NULL;
+ gcry_mpi_release (xq); xq = NULL;
gcry_mpi_release (xq1); xq1 = NULL;
gcry_mpi_release (xq2); xq2 = NULL;
if (!p || !q)
{
int rc;
gcry_mpi_t temp = mpi_alloc( mpi_get_nlimbs(sk->p)*2 );
-
+
mpi_mul(temp, sk->p, sk->q );
rc = mpi_cmp( temp, sk->n );
mpi_free(temp);
*
* Or faster:
*
- * m1 = c ^ (d mod (p-1)) mod p
- * m2 = c ^ (d mod (q-1)) mod q
- * h = u * (m2 - m1) mod q
+ * m1 = c ^ (d mod (p-1)) mod p
+ * m2 = c ^ (d mod (q-1)) mod q
+ * h = u * (m2 - m1) mod q
* m = m1 + h * p
*
* Where m is OUTPUT, c is INPUT and d,n,p,q,u are elements of SKEY.
gcry_mpi_t m1 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
gcry_mpi_t m2 = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
gcry_mpi_t h = mpi_alloc_secure( mpi_get_nlimbs(skey->n)+1 );
-
+
/* m1 = c ^ (d mod (p-1)) mod p */
mpi_sub_ui( h, skey->p, 1 );
- mpi_fdiv_r( h, skey->d, h );
+ mpi_fdiv_r( h, skey->d, h );
mpi_powm( m1, input, h, skey->p );
/* m2 = c ^ (d mod (q-1)) mod q */
mpi_sub_ui( h, skey->q, 1 );
mpi_powm( m2, input, h, skey->q );
/* h = u * ( m2 - m1 ) mod q */
mpi_sub( h, m2, m1 );
- if ( mpi_is_neg( h ) )
+ if ( mpi_is_neg( h ) )
mpi_add ( h, h, skey->q );
- mpi_mulm( h, skey->u, h, skey->q );
+ mpi_mulm( h, skey->u, h, skey->q );
/* m = m2 + h * p */
mpi_mul ( h, h, skey->p );
mpi_add ( output, m1, h );
-
+
mpi_free ( h );
mpi_free ( m1 );
mpi_free ( m2 );
a = gcry_mpi_snew (gcry_mpi_get_nbits (n));
y = gcry_mpi_snew (gcry_mpi_get_nbits (n));
-
+
/* Now we calculate: y = (x * r^e) mod n, where r is the random
number, e is the public exponent, x is the non-blinded data and n
is the RSA modulus. */
gcry_sexp_t l1;
(void)algo;
-
+
*retfactors = NULL; /* We don't return them. */
deriveparms = (genparms?
gcry_sexp_release (deriveparms);
if (!ec && r_extrainfo && swapped)
{
- ec = gcry_sexp_new (r_extrainfo,
+ ec = gcry_sexp_new (r_extrainfo,
"(misc-key-info(p-q-swapped))", 0, 1);
if (ec)
{
skey[4] = sk.q;
skey[5] = sk.u;
}
-
+
return ec;
}
(void)algo;
(void)flags;
-
+
pk.n = pkey[0];
pk.e = pkey[1];
resarr[0] = mpi_alloc (mpi_get_nlimbs (pk.n));
public (resarr[0], data, &pk);
-
+
return GPG_ERR_NO_ERROR;
}
/* We use blinding by default to mitigate timing attacks which can
be practically mounted over the network as shown by Brumley and
- Boney in 2003. */
+ Boney in 2003. */
if (! (flags & PUBKEY_FLAG_NO_BLINDING))
{
/* Initialize blinding. */
-
+
/* First, we need a random number r between 0 and n - 1, which
is relatively prime to n (i.e. it is neither p nor q). The
random number needs to be only unpredictable, thus we employ
gcry_mpi_randomize. */
r = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
ri = gcry_mpi_snew (gcry_mpi_get_nbits (sk.n));
-
+
gcry_mpi_randomize (r, gcry_mpi_get_nbits (sk.n), GCRY_WEAK_RANDOM);
gcry_mpi_mod (r, r, sk.n);
{
/* Undo blinding. */
gcry_mpi_t a = gcry_mpi_copy (y);
-
+
gcry_mpi_release (y);
y = rsa_unblind (a, ri, sk.n);
/* Copy out result. */
*result = y;
-
+
return GPG_ERR_NO_ERROR;
}
RSA_secret_key sk;
(void)algo;
-
+
sk.n = skey[0];
sk.e = skey[1];
sk.d = skey[2];
log_mpidump (" hash:", hash );
}
#endif /*IS_DEVELOPMENT_VERSION*/
- /*rc = (*cmp)( opaquev, result );*/
- rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
+ if (cmp)
+ rc = (*cmp) (opaquev, result);
+ else
+ rc = mpi_cmp (result, hash) ? GPG_ERR_BAD_SIGNATURE : GPG_ERR_NO_ERROR;
gcry_mpi_release (result);
-
+
return rc;
}
(rsa
(n #00B...#)
(e #010001#))
-
+
PKCS-15 says that for RSA only the modulus should be hashed -
however, it is not clear whether this is meant to use the raw bytes
(assuming this is an unsigned integer) or whether the DER required
\f
-/*
+/*
Self-test section.
*/
static const char *
selftest_sign_1024 (gcry_sexp_t pkey, gcry_sexp_t skey)
{
- static const char sample_data[] =
+ static const char sample_data[] =
"(data (flags pkcs1)"
" (hash sha1 #11223344556677889900aabbccddeeff10203040#))";
- static const char sample_data_bad[] =
+ static const char sample_data_bad[] =
"(data (flags pkcs1)"
" (hash sha1 #11223344556677889900aabbccddeeff80203040#))";
err = gcry_sexp_sscan (&data, NULL,
sample_data, strlen (sample_data));
if (!err)
- err = gcry_sexp_sscan (&data_bad, NULL,
+ err = gcry_sexp_sscan (&data_bad, NULL,
sample_data_bad, strlen (sample_data_bad));
if (err)
{
/* Create plaintext. The plaintext is actually a big integer number. */
plaintext = gcry_mpi_new (nbits);
gcry_mpi_randomize (plaintext, nbits, GCRY_WEAK_RANDOM);
-
+
/* Put the plaintext into an S-expression. */
err = gcry_sexp_build (&plain, NULL,
"(data (flags raw) (value %m))", plaintext);
errtxt = "decrypt returned no plaintext";
goto leave;
}
-
+
/* Check that the decrypted plaintext matches the original plaintext. */
if (gcry_mpi_cmp (plaintext, decr_plaintext))
{
gcry_error_t err;
gcry_sexp_t skey = NULL;
gcry_sexp_t pkey = NULL;
-
+
/* Convert the S-expressions into the internal representation. */
what = "convert";
- err = gcry_sexp_sscan (&skey, NULL,
+ err = gcry_sexp_sscan (&skey, NULL,
sample_secret_key, strlen (sample_secret_key));
if (!err)
- err = gcry_sexp_sscan (&pkey, NULL,
+ err = gcry_sexp_sscan (&pkey, NULL,
sample_public_key, strlen (sample_public_key));
if (err)
{
default:
ec = GPG_ERR_PUBKEY_ALGO;
break;
-
+
}
return ec;
}
rsa_verify,
rsa_get_nbits,
};
-pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
+pk_extra_spec_t _gcry_pubkey_extraspec_rsa =
{
run_selftests,
rsa_generate_ext,
compute_keygrip
};
-
static const char *selftest(void);
-typedef struct
+typedef struct
{
u32 keyschedule[32];
} SEED_context;
/* Perform the key setup.
- */
+ */
static gcry_err_code_t
do_setkey (SEED_context *ctx, const byte *key, const unsigned keylen)
{
selftest (void)
{
SEED_context ctx;
- byte scratch[16];
+ byte scratch[16];
/* The test vector is taken from the appendix section B.3 of RFC4269.
*/
/* A prototype. */
static const char *serpent_test (void);
-
+
#define byte_swap_32(x) \
(0 \
/* Copy key. */
memcpy (key_prepared, key, key_length);
+ key_length /= 4;
#ifdef WORDS_BIGENDIAN
- for (i = 0; i < key_length / 4; i++)
+ for (i = 0; i < key_length; i++)
key_prepared[i] = byte_swap_32 (key_prepared[i]);
+#else
+ i = key_length;
#endif
-
- if (key_length < 32)
+ if (i < 8)
{
/* Key must be padded according to the Serpent
specification. */
- key_prepared[key_length / 4] = 0x00000001;
+ key_prepared[i] = 0x00000001;
- for (i = key_length / 4 + 1; i < 8; i++)
+ for (i++; i < 8; i++)
key_prepared[i] = 0;
}
}
static const char *serpent_test_ret;
static int serpent_init_done;
gcry_err_code_t ret = GPG_ERR_NO_ERROR;
-
+
if (! serpent_init_done)
{
/* Execute a self-test the first time, Serpent is used. */
serpent_block_t b, b_next;
int round = ROUNDS;
- memcpy (b, input, sizeof (b));
+ memcpy (b_next, input, sizeof (b));
#ifdef WORDS_BIGENDIAN
- b[0] = byte_swap_32 (b[0]);
- b[1] = byte_swap_32 (b[1]);
- b[2] = byte_swap_32 (b[2]);
- b[3] = byte_swap_32 (b[3]);
+ b_next[0] = byte_swap_32 (b_next[0]);
+ b_next[1] = byte_swap_32 (b_next[1]);
+ b_next[2] = byte_swap_32 (b_next[2]);
+ b_next[3] = byte_swap_32 (b_next[3]);
#endif
ROUND_FIRST_INVERSE (7, context->keys, b_next, b);
{
serpent_setkey_internal (&context, test_data[i].key,
test_data[i].key_length);
- serpent_encrypt_internal (&context,
- test_data[i].text_plain,
- scratch);
+ serpent_encrypt_internal (&context, test_data[i].text_plain, scratch);
if (memcmp (scratch, test_data[i].text_cipher, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
return "Serpent-256 test encryption failed.";
}
- serpent_decrypt_internal (&context,
- test_data[i].text_cipher,
- scratch);
+ serpent_decrypt_internal (&context, test_data[i].text_cipher, scratch);
if (memcmp (scratch, test_data[i].text_plain, sizeof (serpent_block_t)))
switch (test_data[i].key_length)
{
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#ifdef HAVE_STDINT_H
+#ifdef HAVE_STDINT_H
# include <stdint.h>
#endif
#define TRANSFORM(x,d,n) transform ((x), (d), (n))
-typedef struct
+typedef struct
{
u32 h0,h1,h2,h3,h4;
u32 nblocks;
register u32 a, b, c, d, e; /* Local copies of the chaining variables. */
register u32 tm; /* Helper. */
u32 x[16]; /* The array we work on. */
-
+
/* Loop over all blocks. */
for ( ;nblocks; nblocks--)
{
sha1_final(void *context)
{
SHA1_CONTEXT *hd = context;
-
+
u32 t, msb, lsb;
unsigned char *p;
\f
-/*
+/*
Self-test section.
*/
{
const char *what;
const char *errtxt;
-
+
what = "short string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA1, 0,
+ (GCRY_MD_SHA1, 0,
"abc", 3,
"\xA9\x99\x3E\x36\x47\x06\x81\x6A\xBA\x3E"
"\x25\x71\x78\x50\xC2\x6C\x9C\xD0\xD8\x9D", 20);
{
what = "long string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA1, 0,
+ (GCRY_MD_SHA1, 0,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
"\x84\x98\x3E\x44\x1C\x3B\xD2\x6E\xBA\xAE"
"\x4A\xA1\xF9\x51\x29\xE5\xE5\x46\x70\xF1", 20);
if (errtxt)
goto failed;
-
+
what = "one million \"a\"";
errtxt = _gcry_hash_selftest_check_one
(GCRY_MD_SHA1, 1,
default:
ec = GPG_ERR_DIGEST_ALGO;
break;
-
+
}
return ec;
}
sha1_init, sha1_write, sha1_final, sha1_read,
sizeof (SHA1_CONTEXT)
};
-md_extra_spec_t _gcry_digest_extraspec_sha1 =
+md_extra_spec_t _gcry_digest_extraspec_sha1 =
{
run_selftests
};
-
/* Test vectors:
-
+
"abc"
SHA224: 23097d22 3405d822 8642a477 bda255b3 2aadbce4 bda0b3f7 e36c9da7
SHA256: ba7816bf 8f01cfea 414140de 5dae2223 b00361a3 96177a9c b410ff61 f20015ad
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
SHA224: 75388b16 512776cc 5dba5da1 fd890150 b0c6455c b4f58b19 52522525
SHA256: 248d6a61 d20638b8 e5c02693 0c3e6039 a33ce459 64ff2167 f6ecedd4 19db06c1
-
+
"a" one million times
SHA224: 20794655 980c91d8 bbb4c1ea 97618a4b f03f4258 1948b2ee 4ee7ad67
SHA256: cdc76e5c 9914fb92 81a1c7e2 84d73e67 f1809a48 a497200e 046d39cc c7112cd0
{
return ((x & y) | (z & (x|y)));
}
-
+
/* (4.4) */
static inline u32
Sum0 (u32 x)
return (ror (x, 6) ^ ror (x, 11) ^ ror (x, 25));
}
-
+
static void
transform (SHA256_CONTEXT *hd, const unsigned char *data)
{
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
- 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
+ 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
u32 x[16];
u32 w[64];
int i;
-
+
a = hd->h0;
b = hd->h1;
c = hd->h2;
f = hd->h5;
g = hd->h6;
h = hd->h7;
-
+
#ifdef WORDS_BIGENDIAN
memcpy (x, data, 64);
#else
- {
+ {
byte *p2;
-
- for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
+
+ for (i=0, p2=(byte*)x; i < 16; i++, p2 += 4 )
{
p2[3] = *data++;
p2[2] = *data++;
R(a,b,c,d,e,f,g,h,K[i],w[i]);
i++;
#else
- t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
+ t1 = h + Sum1 (e) + Cho (e, f, g) + K[i] + w[i];
t2 = Sum0 (a) + Maj (a, b, c);
d += t1;
h = t1 + t2;
SHA256_CONTEXT *hd = context;
u32 t, msb, lsb;
byte *p;
-
+
sha256_write (hd, NULL, 0); /* flush */;
t = hd->nblocks;
\f
-/*
+/*
Self-test section.
*/
{
const char *what;
const char *errtxt;
-
+
what = "short string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA224, 0,
+ (GCRY_MD_SHA224, 0,
"abc", 3,
"\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", 28);
{
what = "long string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA224, 0,
+ (GCRY_MD_SHA224, 0,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
"\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", 28);
if (errtxt)
goto failed;
-
+
what = "one million \"a\"";
errtxt = _gcry_hash_selftest_check_one
(GCRY_MD_SHA224, 1,
{
const char *what;
const char *errtxt;
-
+
what = "short string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA256, 0,
+ (GCRY_MD_SHA256, 0,
"abc", 3,
"\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", 32);
{
what = "long string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA256, 0,
+ (GCRY_MD_SHA256, 0,
"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", 56,
"\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",
32);
if (errtxt)
goto failed;
-
+
what = "one million \"a\"";
errtxt = _gcry_hash_selftest_check_one
(GCRY_MD_SHA256, 1,
default:
ec = GPG_ERR_DIGEST_ALGO;
break;
-
+
}
return ec;
}
static gcry_md_oid_spec_t oid_spec_sha224[] =
{
/* From RFC3874, Section 4 */
- { "2.16.840.1.101.3.4.2.4" },
+ { "2.16.840.1.101.3.4.2.4" },
{ NULL },
};
static gcry_md_oid_spec_t oid_spec_sha256[] =
{
/* According to the OpenPGP draft rfc2440-bis06 */
- { "2.16.840.1.101.3.4.2.1" },
+ { "2.16.840.1.101.3.4.2.1" },
/* PKCS#1 sha256WithRSAEncryption */
{ "1.2.840.113549.1.1.11" },
sha224_init, sha256_write, sha256_final, sha256_read,
sizeof (SHA256_CONTEXT)
};
-md_extra_spec_t _gcry_digest_extraspec_sha224 =
+md_extra_spec_t _gcry_digest_extraspec_sha224 =
{
run_selftests
};
sha256_init, sha256_write, sha256_final, sha256_read,
sizeof (SHA256_CONTEXT)
};
-md_extra_spec_t _gcry_digest_extraspec_sha256 =
+md_extra_spec_t _gcry_digest_extraspec_sha256 =
{
run_selftests
};
t2 = Sum0 (b) + Maj (b, c, d);
e += t1;
a = t1 + t2;
-
+
t += 8;
#endif
}
\f
-/*
+/*
Self-test section.
*/
{
const char *what;
const char *errtxt;
-
+
what = "short string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA384, 0,
+ (GCRY_MD_SHA384, 0,
"abc", 3,
"\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"
{
what = "long string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA384, 0,
+ (GCRY_MD_SHA384, 0,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
"\x09\x33\x0C\x33\xF7\x11\x47\xE8\x3D\x19\x2F\xC7\x82\xCD\x1B\x47"
"\x53\x11\x1B\x17\x3B\x3B\x05\xD2\x2F\xA0\x80\x86\xE3\xB0\xF7\x12"
"\xFC\xC7\xC7\x1A\x55\x7E\x2D\xB9\x66\xC3\xE9\xFA\x91\x74\x60\x39",
{
const char *what;
const char *errtxt;
-
+
what = "short string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA512, 0,
+ (GCRY_MD_SHA512, 0,
"abc", 3,
"\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"
{
what = "long string";
errtxt = _gcry_hash_selftest_check_one
- (GCRY_MD_SHA512, 0,
+ (GCRY_MD_SHA512, 0,
"abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
- "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", 112,
"\x8E\x95\x9B\x75\xDA\xE3\x13\xDA\x8C\xF4\xF7\x28\x14\xFC\x14\x3F"
"\x8F\x77\x79\xC6\xEB\x9F\x7F\xA1\x72\x99\xAE\xAD\xB6\x88\x90\x18"
"\x50\x1D\x28\x9E\x49\x00\xF7\xE4\x33\x1B\x99\xDE\xC4\xB5\x43\x3A"
64);
if (errtxt)
goto failed;
-
+
what = "one million \"a\"";
errtxt = _gcry_hash_selftest_check_one
(GCRY_MD_SHA512, 1,
default:
ec = GPG_ERR_DIGEST_ALGO;
break;
-
+
}
return ec;
}
{ NULL }
};
-gcry_md_spec_t _gcry_digest_spec_sha512 =
+gcry_md_spec_t _gcry_digest_spec_sha512 =
{
"SHA512", sha512_asn, DIM (sha512_asn), oid_spec_sha512, 64,
sha512_init, sha512_write, sha512_final, sha512_read,
sizeof (SHA512_CONTEXT),
};
-md_extra_spec_t _gcry_digest_extraspec_sha512 =
+md_extra_spec_t _gcry_digest_extraspec_sha512 =
{
run_selftests
};
static gcry_md_oid_spec_t oid_spec_sha384[] =
{
- { "2.16.840.1.101.3.4.2.2" },
+ { "2.16.840.1.101.3.4.2.2" },
/* PKCS#1 sha384WithRSAEncryption */
{ "1.2.840.113549.1.1.12" },
{ NULL },
};
-gcry_md_spec_t _gcry_digest_spec_sha384 =
+gcry_md_spec_t _gcry_digest_spec_sha384 =
{
"SHA384", sha384_asn, DIM (sha384_asn), oid_spec_sha384, 48,
sha384_init, sha512_write, sha512_final, sha512_read,
sizeof (SHA512_CONTEXT),
};
-md_extra_spec_t _gcry_digest_extraspec_sha384 =
+md_extra_spec_t _gcry_digest_extraspec_sha384 =
{
run_selftests
};
u64 a = *ra;
u64 b = *rb;
u64 c = *rc;
-
+
c ^= x;
a -= ( sbox1[ c & 0xff ] ^ sbox2[ (c >> 16) & 0xff ]
^ sbox3[ (c >> 32) & 0xff ] ^ sbox4[ (c >> 48) & 0xff ]);
b += ( sbox4[ (c >> 8) & 0xff ] ^ sbox3[ (c >> 24) & 0xff ]
^ sbox2[ (c >> 40) & 0xff ] ^ sbox1[ (c >> 56) & 0xff ]);
b *= mul;
-
+
*ra = a;
*rb = b;
*rc = c;
}
if( !inbuf )
return;
- if( hd->count )
+ if( hd->count )
{
for( ; inlen && hd->count < 64; inlen-- )
hd->buf[hd->count++] = *inbuf++;
* 128-bit keys use only sa through sh; 256-bit use all of them. */
byte sa = 0, sb = 0, sc = 0, sd = 0, se = 0, sf = 0, sg = 0, sh = 0;
byte si = 0, sj = 0, sk = 0, sl = 0, sm = 0, sn = 0, so = 0, sp = 0;
-
+
/* Temporary for CALC_S. */
byte tmp;
-
+
/* Flags for self-test. */
static int initialized = 0;
static const char *selftest_failed=0;
CALC_K256 (k, 28, 0x84, 0x8A, 0x54, 0x00);
CALC_K256 (k, 30, 0xDF, 0xBC, 0x23, 0x9D);
}
- else
+ else
{
/* Compute the S-boxes. */
for(i=j=0,k=1; i < 256; i++, j += 2, k += 2 )
timer = clock ();
/* Encryption test. */
- for (i = 0; i < 125; i++)
+ for (i = 0; i < 125; i++)
{
twofish_setkey (&ctx, buffer[0], sizeof (buffer[0]));
for (j = 0; j < 1000; j++)
"encryption failure!\n" : "encryption OK!\n";
/* Decryption test. */
- for (i = 0; i < 125; i++)
+ for (i = 0; i < 125; i++)
{
twofish_setkey (&ctx, buffer[2], sizeof (buffer[2])*2);
for (j = 0; j < 1000; j++) {
U64_C (0xfbee7c66dd17479e),
U64_C (0xca2dbf07ad5a8333),
};
-
+
\f
/* Main lookup boxes. */
}
/*_gcry_burn_stack (80+6*sizeof(void*));*/ /* FIXME */
- while (buffer_n >= BLOCK_SIZE)
+ while (buffer_n >= BLOCK_SIZE)
{
whirlpool_transform (context, buffer);
context->count = 0;
2011-12-01 Werner Koch <wk@g10code.com>
- NB: ChangeLog files are no longer manually maintained. Starting
- on December 1st, 2011 we put change information only in the GIT
- commit log, and generate a top-level ChangeLog file from logs at
- "make dist". See doc/HACKING for details.
-
-2011-07-04 Werner Koch <wk@g10code.com>
-
- * longlong.h (add_ssaaaa) [__arm__]: Do no use asm if thumb code
- generation is enabled. This is bug#1202. Reported for gpg 1.4.
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
2011-03-28 Werner Koch <wk@g10code.com>
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.
-
-Local Variables:
-buffer-read-only: t
-End:
mpih-mul3.S
mpih-rshift.S
mpih-sub1.S
+mpi-asm-defs.h
--- /dev/null
+/* This file defines some basic constants for the MPI machinery. We
+ * need to define the types on a per-CPU basis, so it is done with
+ * this file here. */
+#define BYTES_PER_MPI_LIMB 8
ec_mulm (l1, l1, x1, ctx);
}
if (z1_is_one)
- mpi_set (l2, x1);
+ mpi_set (l2, x2);
else
{
ec_powm (l2, z1, ctx->two, ctx);
mpi_mul (h, k, ctx->three); /* h = 3k */
loops = mpi_get_nbits (h);
-
- mpi_set (result->x, point->x);
- mpi_set (result->y, yy); mpi_free (yy); yy = NULL;
- mpi_set (result->z, point->z);
+ if (loops < 2)
+ {
+ /* If SCALAR is zero, the above mpi_mul sets H to zero and thus
+ LOOPs will be zero. To avoid an underflow of I in the main
+ loop we set LOOP to 2 and the result to (0,0,0). */
+ loops = 2;
+ mpi_clear (result->x);
+ mpi_clear (result->y);
+ mpi_clear (result->z);
+ }
+ else
+ {
+ mpi_set (result->x, point->x);
+ mpi_set (result->y, yy);
+ mpi_set (result->z, point->z);
+ }
+ mpi_free (yy); yy = NULL;
p1.x = x1; x1 = NULL;
p1.y = y1; y1 = NULL;
/***************************************
************** ARM ******************
***************************************/
-#if defined (__arm__) && W_TYPE_SIZE == 32 && !defined (__thumb__)
+#if defined (__arm__) && W_TYPE_SIZE == 32 && \
+ (!defined (__thumb__) || defined (__thumb2__))
+/* The __ARM_ARCH define is provided by gcc 4.8. Construct it otherwise. */
+#ifndef __ARM_ARCH
+# ifdef __ARM_ARCH_2__
+# define __ARM_ARCH 2
+# elif defined (__ARM_ARCH_3__) || defined (__ARM_ARCH_3M__)
+# define __ARM_ARCH 3
+# elif defined (__ARM_ARCH_4__) || defined (__ARM_ARCH_4T__)
+# define __ARM_ARCH 4
+# elif defined (__ARM_ARCH_5__) || defined (__ARM_ARCH_5E__) \
+ || defined(__ARM_ARCH_5T__) || defined(__ARM_ARCH_5TE__) \
+ || defined(__ARM_ARCH_5TEJ__)
+# define __ARM_ARCH 5
+# elif defined (__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) \
+ || defined (__ARM_ARCH_6Z__) || defined(__ARM_ARCH_6ZK__) \
+ || defined (__ARM_ARCH_6K__) || defined(__ARM_ARCH_6T2__)
+# define __ARM_ARCH 6
+# elif defined (__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) \
+ || defined(__ARM_ARCH_7R__) || defined(__ARM_ARCH_7M__) \
+ || defined(__ARM_ARCH_7EM__)
+# define __ARM_ARCH 7
+# else
+ /* could not detect? */
+# endif
+#endif
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("adds %1, %4, %5\n" \
"adc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
- "rI" ((USItype)(bl)))
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subs %1, %4, %5\n" \
"sbc %0, %2, %3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(bh)), \
"r" ((USItype)(al)), \
- "rI" ((USItype)(bl)))
-#if defined __ARM_ARCH_2__ || defined __ARM_ARCH_3__
+ "rI" ((USItype)(bl)) __CLOBBER_CC)
+#if (defined __ARM_ARCH && __ARM_ARCH <= 3)
#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
+ __asm__ ("@ Inlined umul_ppmm\n" \
"mov %|r0, %2, lsr #16 @ AAAA\n" \
"mov %|r2, %3, lsr #16 @ BBBB\n" \
"bic %|r1, %2, %|r0, lsl #16 @ aaaa\n" \
"addcs %|r2, %|r2, #65536\n" \
"adds %1, %|r1, %|r0, lsl #16\n" \
"adc %0, %|r2, %|r0, lsr #16" \
- : "=&r" ((USItype)(xh)), \
- "=r" ((USItype)(xl)) \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
: "r" ((USItype)(a)), \
"r" ((USItype)(b)) \
- : "r0", "r1", "r2")
-#else
+ : "r0", "r1", "r2" __CLOBBER_CC)
+#else /* __ARM_ARCH >= 4 */
#define umul_ppmm(xh, xl, a, b) \
- __asm__ ("%@ Inlined umul_ppmm\n" \
- "umull %r1, %r0, %r2, %r3" \
- : "=&r" ((USItype)(xh)), \
- "=r" ((USItype)(xl)) \
+ __asm__ ("@ Inlined umul_ppmm\n" \
+ "umull %1, %0, %2, %3" \
+ : "=&r" ((xh)), \
+ "=r" ((xl)) \
: "r" ((USItype)(a)), \
- "r" ((USItype)(b)) \
- : "r0", "r1")
-#endif
+ "r" ((USItype)(b)))
+#endif /* __ARM_ARCH >= 4 */
#define UMUL_TIME 20
#define UDIV_TIME 100
+#if (defined __ARM_ARCH && __ARM_ARCH >= 5)
+#define count_leading_zeros(count, x) \
+ __asm__ ("clz %0, %1" \
+ : "=r" ((count)) \
+ : "r" ((USItype)(x)))
+#endif /* __ARM_ARCH >= 5 */
#endif /* __arm__ */
/***************************************
#define add_ssaaaa(sh, sl, ah, al, bh, bl) \
__asm__ ("addl %5,%1\n" \
"adcl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"%1" ((USItype)(al)), \
- "g" ((USItype)(bl)))
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
__asm__ ("subl %5,%1\n" \
"sbbl %3,%0" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "0" ((USItype)(ah)), \
"g" ((USItype)(bh)), \
"1" ((USItype)(al)), \
- "g" ((USItype)(bl)))
+ "g" ((USItype)(bl)) \
+ __CLOBBER_CC)
#define umul_ppmm(w1, w0, u, v) \
__asm__ ("mull %3" \
- : "=a" ((USItype)(w0)), \
- "=d" ((USItype)(w1)) \
+ : "=a" ((w0)), \
+ "=d" ((w1)) \
: "%0" ((USItype)(u)), \
- "rm" ((USItype)(v)))
+ "rm" ((USItype)(v)) \
+ __CLOBBER_CC)
#define udiv_qrnnd(q, r, n1, n0, d) \
__asm__ ("divl %4" \
- : "=a" ((USItype)(q)), \
- "=d" ((USItype)(r)) \
+ : "=a" ((q)), \
+ "=d" ((r)) \
: "0" ((USItype)(n0)), \
"1" ((USItype)(n1)), \
- "rm" ((USItype)(d)))
+ "rm" ((USItype)(d)) \
+ __CLOBBER_CC)
#define count_leading_zeros(count, x) \
do { \
USItype __cbtmp; \
__asm__ ("bsrl %1,%0" \
- : "=r" (__cbtmp) : "rm" ((USItype)(x))); \
+ : "=r" (__cbtmp) : "rm" ((USItype)(x)) \
+ __CLOBBER_CC); \
(count) = __cbtmp ^ 31; \
} while (0)
#define count_trailing_zeros(count, x) \
- __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)))
+ __asm__ ("bsfl %1,%0" : "=r" (count) : "rm" ((USItype)(x)) __CLOBBER_CC)
#ifndef UMUL_TIME
#define UMUL_TIME 40
#endif
do { \
if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{a%I4|add%I4c} %1,%3,%4\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"%r" ((USItype)(al)), \
"rI" ((USItype)(bl))); \
else \
__asm__ ("{a%I5|add%I5c} %1,%4,%5\n\t{ae|adde} %0,%2,%3" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "%r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"%r" ((USItype)(al)), \
do { \
if (__builtin_constant_p (ah) && (ah) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfze|subfze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (ah) && (ah) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{sfme|subfme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) == 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{ame|addme} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else if (__builtin_constant_p (bh) && (bh) ==~(USItype) 0) \
__asm__ ("{sf%I3|subf%I3c} %1,%4,%3\n\t{aze|addze} %0,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"rI" ((USItype)(al)), \
"r" ((USItype)(bl))); \
else \
__asm__ ("{sf%I4|subf%I4c} %1,%5,%4\n\t{sfe|subfe} %0,%3,%2" \
- : "=r" ((USItype)(sh)), \
- "=&r" ((USItype)(sl)) \
+ : "=r" ((sh)), \
+ "=&r" ((sl)) \
: "r" ((USItype)(ah)), \
"r" ((USItype)(bh)), \
"rI" ((USItype)(al)), \
} while (0)
#define count_leading_zeros(count, x) \
__asm__ ("{cntlz|cntlzw} %0,%1" \
- : "=r" ((USItype)(count)) \
+ : "=r" ((count)) \
: "r" ((USItype)(x)))
#define COUNT_LEADING_ZEROS_0 32
#if defined (_ARCH_PPC)
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mulhwu %0,%1,%2" \
- : "=r" ((USItype) ph) \
+ : "=r" (ph) \
: "%r" (__m0), \
"r" (__m1)); \
(pl) = __m0 * __m1; \
do { \
USItype __m0 = (m0), __m1 = (m1); \
__asm__ ("mul %0,%2,%3" \
- : "=r" ((USItype)(xh)), \
- "=q" ((USItype)(xl)) \
+ : "=r" ((xh)), \
+ "=q" ((xl)) \
: "r" (__m0), \
"r" (__m1)); \
(xh) += ((((SItype) __m0 >> 31) & __m1) \
#ifndef G10_MPI_INLINE_H
#define G10_MPI_INLINE_H
+/* Starting with gcc 4.3 "extern inline" conforms in c99 mode to the
+ c99 semantics. To keep the useful old semantics we use an
+ attribute. */
#ifndef G10_MPI_INLINE_DECL
-#define G10_MPI_INLINE_DECL extern __inline__
+# ifdef __GNUC_STDC_INLINE__
+# define G10_MPI_INLINE_DECL extern inline __attribute__ ((__gnu_inline__))
+# else
+# define G10_MPI_INLINE_DECL extern __inline__
+# endif
#endif
G10_MPI_INLINE_DECL mpi_limb_t
/* mpi-pow.c - MPI functions for exponentiation
* Copyright (C) 1994, 1996, 1998, 2000, 2002
* 2003 Free Software Foundation, Inc.
+ * 2013 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
if (!esize)
{
/* Exponent is zero, result is 1 mod MOD, i.e., 1 or 0 depending
- on if MOD equals 1. */
- rp[0] = 1;
+ on if MOD equals 1. */
res->nlimbs = (msize == 1 && mod->d[0] == 1) ? 0 : 1;
+ if (res->nlimbs)
+ {
+ RESIZE_IF_NEEDED (res, 1);
+ rp = res->d;
+ rp[0] = 1;
+ }
res->sign = 0;
goto leave;
}
tp = rp; rp = xp; xp = tp;
rsize = xsize;
- if ( (mpi_limb_signed_t)e < 0 )
+ /* To mitigate the Yarom/Falkner flush+reload cache
+ * side-channel attack on the RSA secret exponent, we do
+ * the multiplication regardless of the value of the
+ * high-bit of E. But to avoid this performance penalty
+ * we do it only if the exponent has been stored in secure
+ * memory and we can thus assume it is a secret exponent. */
+ if (esec || (mpi_limb_signed_t)e < 0)
{
/*mpih_mul( xp, rp, rsize, bp, bsize );*/
if( bsize < KARATSUBA_THRESHOLD )
_gcry_mpih_divrem(xp + msize, 0, xp, xsize, mp, msize);
xsize = msize;
}
-
+ }
+ if ( (mpi_limb_signed_t)e < 0 )
+ {
tp = rp; rp = xp; xp = tp;
rsize = xsize;
}
/* This is sub-optimal but we need to do the shift operation because
the caller has to free the returned buffer. */
- for (p=buffer; !*p && *nbytes; p++, --*nbytes)
+ for (p=buffer; *nbytes && !*p; p++, --*nbytes)
;
if (p != buffer)
memmove (buffer,p, *nbytes);
2011-12-01 Werner Koch <wk@g10code.com>
- NB: ChangeLog files are no longer manually maintained. Starting
- on December 1st, 2011 we put change information only in the GIT
- commit log, and generate a top-level ChangeLog file from logs at
- "make dist". See doc/HACKING for details.
+ NB: ChangeLog files are no longer manually maintained. Starting
+ on December 1st, 2011 we put change information only in the GIT
+ commit log, and generate a top-level ChangeLog file from logs at
+ "make dist". See doc/HACKING for details.
-2011-09-16 Werner Koch <wk@g10code.com>
+2011-09-08 Werner Koch <wk@g10code.com>
- Change ATH code and turn the thread initialization callbacks in
- the API into dummy functions.
-
- * global.c (global_init): Call _gcry_pimegen_init.
-
- * gcrypt.h.in (GCRY_THREAD_OPTI ON_VERSION): Bump to 1.
- (GCRY_THREAD_OPTION_PTH_IMPL): Simplify.
- (GCRY_THREAD_OPTION_PTHREAD_IMPL): Simplify.
-
- * ath.c (ath_read, ath_write): Remove. They are only used in the
- optional random-daemon.
- (ath_select, ath_waitpid, ath_accept, ath_connect, ath_sendmsg)
- (ath_recvmsg): Remove. They are not used.
- * ath.h: Remove prototypes and corresponding structure fields.
-
-2011-03-11 Werner Koch <wk@g10code.com>
-
- * ath.c (mutex_init): Rename second arg to FORCE and invert
- logic. Change all callers.
-
-2011-09-15 Werner Koch <wk@g10code.com>
-
- * gcrypt.h.in (enum gcry_thread_option): Remove deprecated enum.
- (gcry_md_start_debug, gcry_md_stop_debug): Remove deprecated these
- macros.
-
-2011-09-15 Werner Koch <wk@g10code.com>
-
- Removal of the gcry_ac and the module register interfaces.
-
- * Makefile.am (include_HEADERS): Remove gcrypt-module.h.
- (libgcrypt_la_SOURCES): Add gcrypt-module.h which is now internal
- header.
- * gcrypt-module.h (gcry_md_register, gcry_md_unregister): Remove.
- (gcry_pk_register, gcry_pk_unregister): Remove.
- (gcry_cipher_register, gcry_cipher_unregister): Remove.
- * visibility.h: Include gcrypt-module.h.
- * gcrypt.h.in: Do not include gcrypt-module.h.
- * gcrypt.h.in: Remove all gcry_ac symbols.
- (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
- * visibility.h: Remove all gcry_ac symbols.
- (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
- (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
- (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
- * visibility.c: Remove all gcry_ac wrappers.
- (gcry_pk_list, gcry_cipher_list, gcry_md_list): Remove.
- (gcry_cipher_register, gcry_cipher_unregister, gcry_pk_register)
- (gcry_pk_unregister, gcry_md_register, gcry_md_unregister): Remove.
- * libgcrypt.vers: Remove all gcry_ac symbols.
- (GCRYPT_1.2): Rename to GCRYPT_1.6.
- (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
- * libgcrypt.def: Remove all gcry_ac symbols.
- (gcry_pk_list, gcry_md_list, gcry_cipher_list): Remove.
- * global.c (global_init): Remove comment code with a call to
- _gcry_ac_init.
-
-2011-09-15 Werner Koch <wk@g10code.com>
-
- * hmac256.c (main): Fix endless loop when using pipe input and
- option --binary.
+ * gcrypt.h.in [GCRYPT_NO_DEPRECATED]: Exclude gcry_ac structures.
2011-06-10 Werner Koch <wk@g10code.com>
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.
-
-Local Variables:
-buffer-read-only: t
-End:
bin_SCRIPTS = libgcrypt-config
m4datadir = $(datadir)/aclocal
m4data_DATA = libgcrypt.m4
-include_HEADERS = gcrypt.h
+include_HEADERS = gcrypt.h gcrypt-module.h
lib_LTLIBRARIES = libgcrypt.la
bin_PROGRAMS = dumpsexp hmac256
libgcrypt_la_CFLAGS = $(GPG_ERROR_CFLAGS)
libgcrypt_la_SOURCES = g10lib.h visibility.c visibility.h types.h \
- cipher.h cipher-proto.h gcrypt-module.h \
+ cipher.h cipher-proto.h \
misc.c global.c sexp.c hwfeatures.c \
stdmem.c stdmem.h secmem.c secmem.h \
mpi.h missing-string.c module.c fips.c \
-/* ath.c - A Thread-safeness library.
- * Copyright (C) 2002, 2003, 2004, 2011 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/>.
- */
+/* ath.c - Thread-safeness library.
+ Copyright (C) 2002, 2003, 2004 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with Libgcrypt; 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 <assert.h> /* Right: We need to use assert and not gcry_assert. */
#include <unistd.h>
-#include <errno.h>
-#if USE_POSIX_THREADS_WEAK
-# include <pthread.h>
+#ifdef HAVE_SYS_SELECT_H
+# include <sys/select.h>
+#else
+# include <sys/time.h>
+#endif
+#include <sys/types.h>
+#ifndef _WIN32
+#include <sys/wait.h>
#endif
+#include <errno.h>
#include "ath.h"
\f
-/* On an ELF system it is easy to use pthreads using weak references.
- Take care not to test the address of a weak referenced function we
- actually use; some GCC versions have a bug were &foo != NULL is
- always evaluated to true in PIC mode. USING_PTHREAD_AS_DEFAULT is
- used by ath_install to detect the default usage of pthread. */
-#if USE_POSIX_THREADS_WEAK
-# pragma weak pthread_cancel
-# pragma weak pthread_mutex_init
-# pragma weak pthread_mutex_lock
-# pragma weak pthread_mutex_unlock
-# pragma weak pthread_mutex_destroy
-#endif
+/* The interface table. */
+static struct ath_ops ops;
+
+/* True if we should use the external callbacks. */
+static int ops_set;
-/* For the dummy interface. The MUTEX_NOTINIT value is used to check
- that a mutex has been initialized. Because its value is there is
- no need to explicit initialized a mutex variable because it is
- anyway static and we store a pointer to allocated memory there
- after initialization. The same thing works with other thread
- models. */
-#define MUTEX_NOTINIT ((ath_mutex_t) 0)
-#define MUTEX_UNLOCKED ((ath_mutex_t) 1)
-#define MUTEX_LOCKED ((ath_mutex_t) 2)
-#define MUTEX_DESTROYED ((ath_mutex_t) 3)
+
+/* For the dummy interface. */
+#define MUTEX_UNLOCKED ((ath_mutex_t) 0)
+#define MUTEX_LOCKED ((ath_mutex_t) 1)
+#define MUTEX_DESTROYED ((ath_mutex_t) 2)
/* Return the thread type from the option field. */
#define GET_OPTION(a) ((a) & 0xff)
+/* Return the version number from the option field. */
+#define GET_VERSION(a) (((a) >> 8)& 0xff)
\f
-enum ath_thread_model {
- ath_model_undefined = 0,
- ath_model_none, /* No thread support. */
- ath_model_pthreads_weak, /* POSIX threads using weak symbols. */
- ath_model_pthreads, /* POSIX threads directly linked. */
- ath_model_w32 /* Microsoft Windows threads. */
-};
-
-
-/* The thread model in use. */
-static enum ath_thread_model thread_model;
-
-
-/* Initialize the ath subsystem. This is called as part of the
- Libgcrypt initialization. It's purpose is to initialize the
- locking system. It returns 0 on sucess or an ERRNO value on error.
- In the latter case it is not defined whether ERRNO was changed.
+/* The lock we take while checking for lazy lock initialization. */
+static ath_mutex_t check_init_lock = ATH_MUTEX_INITIALIZER;
- Note: This should be called as early as possible because it is not
- always possible to detect the thread model to use while already
- running multi threaded. */
int
ath_init (void)
{
int err = 0;
- if (thread_model)
- return 0; /* Already initialized - no error. */
+ if (ops_set)
+ {
+ if (ops.init)
+ err = (*ops.init) ();
+ if (err)
+ return err;
+ err = (*ops.mutex_init) (&check_init_lock);
+ }
+ return err;
+}
- if (0)
- ;
-#if USE_POSIX_THREADS_WEAK
- else if (pthread_cancel)
+
+/* Initialize the locking library. Returns 0 if the operation was
+ successful, EINVAL if the operation table was invalid and EBUSY if
+ we already were initialized. */
+gpg_err_code_t
+ath_install (struct ath_ops *ath_ops, int check_only)
+{
+ if (check_only)
{
- thread_model = ath_model_pthreads_weak;
+ unsigned int option = 0;
+
+ /* Check if the requested thread option is compatible to the
+ thread option we are already committed to. */
+ if (ath_ops)
+ option = ath_ops->option;
+
+ if (!ops_set && GET_OPTION (option))
+ return GPG_ERR_NOT_SUPPORTED;
+
+ if (GET_OPTION (ops.option) == ATH_THREAD_OPTION_USER
+ || GET_OPTION (option) == ATH_THREAD_OPTION_USER
+ || GET_OPTION (ops.option) != GET_OPTION (option)
+ || GET_VERSION (ops.option) != GET_VERSION (option))
+ return GPG_ERR_NOT_SUPPORTED;
+
+ return 0;
}
-#endif
- else
+
+ if (ath_ops)
{
- /* Assume a single threaded application. */
- thread_model = ath_model_none;
+ /* It is convenient to not require DESTROY. */
+ if (!ath_ops->mutex_init || !ath_ops->mutex_lock
+ || !ath_ops->mutex_unlock)
+ return GPG_ERR_INV_ARG;
+
+ ops = *ath_ops;
+ ops_set = 1;
}
+ else
+ ops_set = 0;
+
+ return 0;
+}
+
+
+static int
+mutex_init (ath_mutex_t *lock, int just_check)
+{
+ int err = 0;
+ if (just_check)
+ (*ops.mutex_lock) (&check_init_lock);
+ if (*lock == ATH_MUTEX_INITIALIZER || !just_check)
+ err = (*ops.mutex_init) (lock);
+ if (just_check)
+ (*ops.mutex_unlock) (&check_init_lock);
return err;
}
-/* Return the used thread model as string for display purposes an if
- R_MODEL is not null store its internal number at R_MODEL. */
-const char *
-ath_get_model (int *r_model)
+int
+ath_mutex_init (ath_mutex_t *lock)
{
- if (r_model)
- *r_model = thread_model;
- switch (thread_model)
+ if (ops_set)
+ return mutex_init (lock, 0);
+
+#ifndef NDEBUG
+ *lock = MUTEX_UNLOCKED;
+#endif
+ return 0;
+}
+
+
+int
+ath_mutex_destroy (ath_mutex_t *lock)
+{
+ if (ops_set)
{
- case ath_model_undefined: return "undefined";
- case ath_model_none: return "none";
- case ath_model_pthreads_weak: return "pthread(weak)";
- case ath_model_pthreads: return "pthread";
- case ath_model_w32: return "w32";
- default: return "?";
+ if (!ops.mutex_destroy)
+ return 0;
+
+ (*ops.mutex_lock) (&check_init_lock);
+ if (*lock == ATH_MUTEX_INITIALIZER)
+ {
+ (*ops.mutex_unlock) (&check_init_lock);
+ return 0;
+ }
+ (*ops.mutex_unlock) (&check_init_lock);
+ return (*ops.mutex_destroy) (lock);
}
+
+#ifndef NDEBUG
+ assert (*lock == MUTEX_UNLOCKED);
+
+ *lock = MUTEX_DESTROYED;
+#endif
+ return 0;
}
-/* This function was used in old Libgcrypt versions (via
- GCRYCTL_SET_THREAD_CBS) to register the thread callback functions.
- It is not anymore required. However to allow existing code to
- continue to work, we keep this function and check that no user
- defined callbacks are used and that the requested thread system
- matches the one Libgcrypt is using. */
-gpg_err_code_t
-ath_install (struct ath_ops *ath_ops)
+int
+ath_mutex_lock (ath_mutex_t *lock)
{
- unsigned int thread_option;
-
- /* Check if the requested thread option is compatible to the
- thread option we are already committed to. */
- thread_option = ath_ops? GET_OPTION (ath_ops->option) : 0;
-
- /* Return an error if the requested thread model does not match the
- configured one. */
- if (0)
- ;
-#if USE_POSIX_THREADS_WEAK
- else if (thread_model == ath_model_pthreads_weak)
+ if (ops_set)
{
- if (thread_option == ATH_THREAD_OPTION_PTHREAD)
- return 0; /* Okay - compatible. */
+ int ret = mutex_init (lock, 1);
+ if (ret)
+ return ret;
+ return (*ops.mutex_lock) (lock);
}
-#endif /*USE_POSIX_THREADS_WEAK*/
- else if (thread_option == ATH_THREAD_OPTION_DEFAULT)
- return 0; /* No thread support requested. */
- return GPG_ERR_NOT_SUPPORTED;
+#ifndef NDEBUG
+ assert (*lock == MUTEX_UNLOCKED);
+
+ *lock = MUTEX_LOCKED;
+#endif
+ return 0;
}
-/* Initialize a new mutex. This function returns 0 on success or an
- system error code (i.e. an ERRNO value). ERRNO may or may not be
- changed on error. */
int
-ath_mutex_init (ath_mutex_t *lock)
+ath_mutex_unlock (ath_mutex_t *lock)
{
- int err;
-
- switch (thread_model)
+ if (ops_set)
{
- case ath_model_none:
- *lock = MUTEX_UNLOCKED;
- err = 0;
- break;
-
-#if USE_POSIX_THREADS_WEAK
- case ath_model_pthreads_weak:
- {
- pthread_mutex_t *plck;
-
- plck = malloc (sizeof *plck);
- if (!plck)
- err = errno? errno : ENOMEM;
- else
- {
- err = pthread_mutex_init (plck, NULL);
- if (err)
- free (plck);
- else
- *lock = (void*)plck;
- }
- }
- break;
-#endif /*USE_POSIX_THREADS_WEAK*/
-
- default:
- err = EINVAL;
- break;
+ int ret = mutex_init (lock, 1);
+ if (ret)
+ return ret;
+ return (*ops.mutex_unlock) (lock);
}
- return err;
+#ifndef NDEBUG
+ assert (*lock == MUTEX_LOCKED);
+
+ *lock = MUTEX_UNLOCKED;
+#endif
+ return 0;
}
-/* Destroy a mutex. This function is a NOP if LOCK is NULL. If the
- mutex is still locked it can't be destroyed and the function
- returns EBUSY. ERRNO may or may not be changed on error. */
-int
-ath_mutex_destroy (ath_mutex_t *lock)
+ssize_t
+ath_read (int fd, void *buf, size_t nbytes)
{
- int err;
+ if (ops_set && ops.read)
+ return (*ops.read) (fd, buf, nbytes);
+ else
+ return read (fd, buf, nbytes);
+}
- if (!*lock)
- return 0;
- switch (thread_model)
- {
- case ath_model_none:
- if (*lock != MUTEX_UNLOCKED)
- err = EBUSY;
- else
- {
- *lock = MUTEX_DESTROYED;
- err = 0;
- }
- break;
-
-#if USE_POSIX_THREADS_WEAK
- case ath_model_pthreads_weak:
- {
- pthread_mutex_t *plck = (pthread_mutex_t*)lock;
-
- err = pthread_mutex_destroy (plck);
- if (!err)
- {
- free (plck);
- lock = NULL;
- }
- }
- break;
-#endif /*USE_POSIX_THREADS_WEAK*/
-
- default:
- err = EINVAL;
- break;
- }
+ssize_t
+ath_write (int fd, const void *buf, size_t nbytes)
+{
+ if (ops_set && ops.write)
+ return (*ops.write) (fd, buf, nbytes);
+ else
+ return write (fd, buf, nbytes);
+}
- return err;
+
+ssize_t
+#ifdef _WIN32
+ath_select (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout)
+#else
+ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout)
+#endif
+{
+ if (ops_set && ops.select)
+ return (*ops.select) (nfd, rset, wset, eset, timeout);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return select (nfd, rset, wset, eset, timeout);
+#endif
+}
+
+
+ssize_t
+ath_waitpid (pid_t pid, int *status, int options)
+{
+ if (ops_set && ops.waitpid)
+ return (*ops.waitpid) (pid, status, options);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return waitpid (pid, status, options);
+#endif
}
-/* Lock the mutex LOCK. On success the function returns 0; on error
- an error code. ERRNO may or may not be changed on error. */
int
-ath_mutex_lock (ath_mutex_t *lock)
+#ifdef _WIN32
+ath_accept (int s, void *addr, int *length_ptr)
+#else
+ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr)
+#endif
{
- int err;
+ if (ops_set && ops.accept)
+ return (*ops.accept) (s, addr, length_ptr);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return accept (s, addr, length_ptr);
+#endif
+}
- switch (thread_model)
- {
- case ath_model_none:
- if (*lock == MUTEX_NOTINIT)
- err = EINVAL;
- else if (*lock == MUTEX_UNLOCKED)
- {
- *lock = MUTEX_LOCKED;
- err = 0;
- }
- else
- err = EDEADLK;
- break;
-
-#if USE_POSIX_THREADS_WEAK
- case ath_model_pthreads_weak:
- err = pthread_mutex_lock ((pthread_mutex_t*)lock);
- break;
-#endif /*USE_POSIX_THREADS_WEAK*/
-
- default:
- err = EINVAL;
- break;
- }
- return err;
+int
+#ifdef _WIN32
+ath_connect (int s, void *addr, int length)
+#else
+ath_connect (int s, struct sockaddr *addr, socklen_t length)
+#endif
+{
+ if (ops_set && ops.connect)
+ return (*ops.connect) (s, addr, length);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return connect (s, addr, length);
+#endif
}
-/* Unlock the mutex LOCK. On success the function returns 0; on error
- an error code. ERRNO may or may not be changed on error. */
+
int
-ath_mutex_unlock (ath_mutex_t *lock)
+#ifdef _WIN32
+ath_sendmsg (int s, const void *msg, int flags)
+#else
+ath_sendmsg (int s, const struct msghdr *msg, int flags)
+#endif
{
- int err;
+ if (ops_set && ops.sendmsg)
+ return (*ops.sendmsg) (s, msg, flags);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return sendmsg (s, msg, flags);
+#endif
+}
- switch (thread_model)
- {
- case ath_model_none:
- if (*lock == MUTEX_NOTINIT)
- err = EINVAL;
- else if (*lock == MUTEX_LOCKED)
- {
- *lock = MUTEX_UNLOCKED;
- err = 0;
- }
- else
- err = EPERM;
- break;
-
-#if USE_POSIX_THREADS_WEAK
- case ath_model_pthreads_weak:
- err = pthread_mutex_unlock ((pthread_mutex_t*)lock);
- break;
-#endif /*USE_POSIX_THREADS_WEAK*/
-
- default:
- err = EINVAL;
- break;
- }
- return err;
+int
+#ifdef _WIN32
+ath_recvmsg (int s, void *msg, int flags)
+#else
+ath_recvmsg (int s, struct msghdr *msg, int flags)
+#endif
+{
+ if (ops_set && ops.recvmsg)
+ return (*ops.recvmsg) (s, msg, flags);
+ else
+#ifdef _WIN32
+ return -1;
+#else
+ return recvmsg (s, msg, flags);
+#endif
}
/* ath.h - Thread-safeness library.
- * Copyright (C) 2002, 2003, 2004, 2011 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/>.
- */
+ Copyright (C) 2002, 2003, 2004 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
+ General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with Libgcrypt; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
+ 02111-1307, USA. */
#ifndef ATH_H
#define ATH_H
#define _ATH_PREFIX(x) _ATH_PREFIX2(_ATH_EXT_SYM_PREFIX,x)
#define ath_install _ATH_PREFIX(ath_install)
#define ath_init _ATH_PREFIX(ath_init)
-#define ath_get_model _ATH_PREFIX(ath_get_model)
#define ath_mutex_init _ATH_PREFIX(ath_mutex_init)
#define ath_mutex_destroy _ATH_PREFIX(ath_mutex_destroy)
#define ath_mutex_lock _ATH_PREFIX(ath_mutex_lock)
#define ath_mutex_unlock _ATH_PREFIX(ath_mutex_unlock)
+#define ath_read _ATH_PREFIX(ath_read)
+#define ath_write _ATH_PREFIX(ath_write)
+#define ath_select _ATH_PREFIX(ath_select)
+#define ath_waitpid _ATH_PREFIX(ath_waitpid)
+#define ath_connect _ATH_PREFIX(ath_connect)
+#define ath_accept _ATH_PREFIX(ath_accept)
+#define ath_sendmsg _ATH_PREFIX(ath_sendmsg)
+#define ath_recvmsg _ATH_PREFIX(ath_recvmsg)
#endif
\f
*/
unsigned int option;
+ int (*init) (void);
+ int (*mutex_init) (void **priv);
+ int (*mutex_destroy) (void *priv);
+ int (*mutex_lock) (void *priv);
+ int (*mutex_unlock) (void *priv);
+ ssize_t (*read) (int fd, void *buf, size_t nbytes);
+ ssize_t (*write) (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ ssize_t (*select) (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, void *addr, int *length_ptr);
+ int (*connect) (int s, void *addr, int length);
+ int (*sendmsg) (int s, const void *msg, int flags);
+ int (*recvmsg) (int s, void *msg, int flags);
+#else
+ ssize_t (*select) (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ ssize_t (*waitpid) (pid_t pid, int *status, int options);
+ int (*accept) (int s, struct sockaddr *addr, socklen_t *length_ptr);
+ int (*connect) (int s, struct sockaddr *addr, socklen_t length);
+ int (*sendmsg) (int s, const struct msghdr *msg, int flags);
+ int (*recvmsg) (int s, struct msghdr *msg, int flags);
+#endif
};
-gpg_err_code_t ath_install (struct ath_ops *ath_ops);
+gpg_err_code_t ath_install (struct ath_ops *ath_ops, int check_only);
int ath_init (void);
-const char *ath_get_model (int *r_model);
+
/* Functions for mutual exclusion. */
typedef void *ath_mutex_t;
+#define ATH_MUTEX_INITIALIZER 0
int ath_mutex_init (ath_mutex_t *mutex);
int ath_mutex_destroy (ath_mutex_t *mutex);
int ath_mutex_lock (ath_mutex_t *mutex);
int ath_mutex_unlock (ath_mutex_t *mutex);
+/* Replacement for the POSIX functions, which can be used to allow
+ other (user-level) threads to run. */
+ssize_t ath_read (int fd, void *buf, size_t nbytes);
+ssize_t ath_write (int fd, const void *buf, size_t nbytes);
+#ifdef _WIN32
+ssize_t ath_select (int nfd, void *rset, void *wset, void *eset,
+ struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+int ath_accept (int s, void *addr, int *length_ptr);
+int ath_connect (int s, void *addr, int length);
+int ath_sendmsg (int s, const void *msg, int flags);
+int ath_recvmsg (int s, void *msg, int flags);
+#else
+ssize_t ath_select (int nfd, fd_set *rset, fd_set *wset, fd_set *eset,
+ struct timeval *timeout);
+ssize_t ath_waitpid (pid_t pid, int *status, int options);
+int ath_accept (int s, struct sockaddr *addr, socklen_t *length_ptr);
+int ath_connect (int s, struct sockaddr *addr, socklen_t length);
+int ath_sendmsg (int s, const struct msghdr *msg, int flags);
+int ath_recvmsg (int s, struct msghdr *msg, int flags);
+#endif
+
#endif /* ATH_H */
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia128;
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia192;
extern gcry_cipher_spec_t _gcry_cipher_spec_camellia256;
+extern gcry_cipher_spec_t _gcry_cipher_spec_idea;
extern cipher_extra_spec_t _gcry_cipher_extraspec_tripledes;
extern cipher_extra_spec_t _gcry_cipher_extraspec_aes;
static int inactive_fips_mode;
/* This is the lock we use to protect the FSM. */
-static ath_mutex_t fsm_lock;
+static ath_mutex_t fsm_lock = ATH_MUTEX_INITIALIZER;
/* The current state of the FSM. The whole state machinery is only
used while in fips mode. Change this only while holding fsm_lock. */
int
_gcry_enforced_fips_mode (void)
{
+ if (!_gcry_fips_mode ())
+ return 0;
return enforced_fips_mode;
}
+/* Set a flag telling whether we are in the enforced fips mode. */
+void
+_gcry_set_enforced_fips_mode (void)
+{
+ enforced_fips_mode = 1;
+}
/* If we do not want to enforce the fips mode, we can set a flag so
that the application may check whether it is still in fips mode.
/* Gettext macros. */
-#define _(a) _gcry_gettext(a)
-
/* Some handy macros */
#ifndef STR
#define STR(v) #v
void _gcry_set_log_verbosity( int level );
int _gcry_log_verbosity( int level );
+#ifdef JNLIB_GCC_M_FUNCTION
+#define BUG() _gcry_bug( __FILE__ , __LINE__, __FUNCTION__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __FUNCTION__))
+#elif __STDC_VERSION__ >= 199901L
#define BUG() _gcry_bug( __FILE__ , __LINE__, __func__ )
#define gcry_assert(expr) ((expr)? (void)0 \
: _gcry_assert_failed (STR(expr), __FILE__, __LINE__, __func__))
+#else
+#define BUG() _gcry_bug( __FILE__ , __LINE__ )
+#define gcry_assert(expr) ((expr)? (void)0 \
+ : _gcry_assert_failed (STR(expr), __FILE__, __LINE__))
+#endif
+
#define log_bug _gcry_log_bug
#define log_fatal _gcry_log_fatal
#endif
/*-- primegen.c --*/
-gcry_err_code_t _gcry_primegen_init (void);
gcry_mpi_t _gcry_generate_secret_prime (unsigned int nbits,
gcry_random_level_t random_level,
int (*extra_check)(void*, gcry_mpi_t),
|| (*(a) >= 'A' && *(a) <= 'F') \
|| (*(a) >= 'a' && *(a) <= 'f'))
-/* Management for ciphers/digests/pubkey-ciphers. */
-
-/* Structure for each registered `module'. */
-struct gcry_module
-{
- struct gcry_module *next; /* List pointers. */
- struct gcry_module **prevp;
- void *spec; /* Pointer to the subsystem-specific
- specification structure. */
- void *extraspec; /* Pointer to the subsystem-specific
- extra specification structure. */
- int flags; /* Associated flags. */
- int counter; /* Use counter. */
- unsigned int mod_id; /* ID of this module. */
-};
-
-typedef struct gcry_module gcry_module_t;
-
-/* Flags for the `flags' member of gcry_module_t. */
-#define FLAG_MODULE_DISABLED (1 << 0)
-
-gcry_err_code_t _gcry_module_add (gcry_module_t *entries,
- unsigned int id,
- void *spec,
- void *extraspec,
- gcry_module_t *module);
-
-typedef int (*gcry_module_lookup_t) (void *spec, void *data);
-
-/* Lookup a module specification by it's ID. After a successful
- lookup, the module has it's resource counter incremented. */
-gcry_module_t _gcry_module_lookup_id (gcry_module_t entries,
- unsigned int id);
-
-/* Internal function. Lookup a module specification. */
-gcry_module_t _gcry_module_lookup (gcry_module_t entries, void *data,
- gcry_module_lookup_t func);
-
-/* Release a module. In case the use-counter reaches zero, destroy
- the module. */
-void _gcry_module_release (gcry_module_t entry);
-
-/* Add a reference to a module. */
-void _gcry_module_use (gcry_module_t module);
-
-/* Return a list of module IDs. */
-gcry_err_code_t _gcry_module_list (gcry_module_t modules,
- int *list, int *list_length);
-
-gcry_err_code_t _gcry_cipher_init (void);
-gcry_err_code_t _gcry_md_init (void);
-gcry_err_code_t _gcry_pk_init (void);
-
-gcry_err_code_t _gcry_pk_module_lookup (int id, gcry_module_t *module);
-void _gcry_pk_module_release (gcry_module_t module);
-gcry_err_code_t _gcry_pk_get_elements (int algo, char **enc, char **sig);
-
-/* Memory management. */
-#define GCRY_ALLOC_FLAG_SECURE (1 << 0)
-
/*-- sexp.c --*/
gcry_error_t _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
void _gcry_initialize_fips_mode (int force);
+int _gcry_fips_mode (void);
+#define fips_mode() _gcry_fips_mode ()
+
int _gcry_enforced_fips_mode (void);
+void _gcry_set_enforced_fips_mode (void);
+
void _gcry_inactivate_fips_mode (const char *text);
int _gcry_is_fips_mode_inactive (void);
/*
This file contains the necessary declarations/definitions for
- working with Libgcrypt modules. Since 1.6 this is an internal
- interface and will eventually be merged into another header or
- entirely removed.
+ working with Libgcrypt modules.
*/
-#ifndef GCRYPT_MODULE_H
-#define GCRYPT_MODULE_H
+#ifndef _GCRYPT_MODULE_H
+#define _GCRYPT_MODULE_H
#ifdef __cplusplus
extern "C" {
gcry_cipher_stdecrypt_t stdecrypt;
} gcry_cipher_spec_t;
+/* Register a new cipher module whose specification can be found in
+ CIPHER. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representing this module is stored in MODULE. */
+gcry_error_t gcry_cipher_register (gcry_cipher_spec_t *cipher,
+ int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+
+/* Unregister the cipher identified by MODULE, which must have been
+ registered with gcry_cipher_register. */
+void gcry_cipher_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
/* ********************** */
gcry_pk_get_nbits_t get_nbits;
} gcry_pk_spec_t;
+/* Register a new pubkey module whose specification can be found in
+ PUBKEY. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t gcry_pk_register (gcry_pk_spec_t *pubkey,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Unregister the pubkey identified by ID, which must have been
+ registered with gcry_pk_register. */
+void gcry_pk_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
/* ********************** */
size_t contextsize; /* allocate this amount of context */
} gcry_md_spec_t;
+/* Register a new digest module whose specification can be found in
+ DIGEST. On success, a new algorithm ID is stored in ALGORITHM_ID
+ and a pointer representhing this module is stored in MODULE. */
+gcry_error_t gcry_md_register (gcry_md_spec_t *digest,
+ unsigned int *algorithm_id,
+ gcry_module_t *module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Unregister the digest identified by ID, which must have been
+ registered with gcry_digest_register. */
+void gcry_md_unregister (gcry_module_t module)
+ /* */ _GCRY_ATTR_INTERNAL;
+
#if 0 /* keep Emacsens's auto-indent happy */
{
#endif
#ifdef __cplusplus
}
#endif
-#endif /*GCRYPT_MODULE_H*/
+#endif
/* gcrypt.h - GNU Cryptographic Library Interface -*- c -*-
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2006
- 2007, 2008, 2009, 2010, 2011 Free Software Foundation, Inc.
+ 2007, 2008, 2009, 2010, 2011,
+ 2012 Free Software Foundation, Inc.
+ Copyright (C) 2012, 2013 g10 Code GmbH
This file is part of Libgcrypt.
matches the installed library. */
#define GCRYPT_VERSION "@VERSION@"
+/* The version number of this header. It may be used to handle minor
+ API incompatibilities. */
+#define GCRYPT_VERSION_NUMBER @VERSION_NUMBER@
+
+
/* Internal: We can't use the convenience macros for the multi
precision integer functions when building this library. */
#ifdef _GCRYPT_IN_LIBGCRYPT
/* Return an error value with the system error ERR. */
gcry_err_code_t gcry_error_from_errno (int err);
-\f
-/* NOTE: Since Libgcrypt 1.6 the thread callbacks are not anymore
- used. However we keep it to allow for some source code
- compatibility if used in the standard way. */
-
-/* Constants defining the thread model to use. Used with the OPTION
- field of the struct gcry_thread_cbs. */
-#define GCRY_THREAD_OPTION_DEFAULT 0
-#define GCRY_THREAD_OPTION_USER 1
-#define GCRY_THREAD_OPTION_PTH 2
-#define GCRY_THREAD_OPTION_PTHREAD 3
-
-/* The version number encoded in the OPTION field of the struct
- gcry_thread_cbs. */
-#define GCRY_THREAD_OPTION_VERSION 1
-
-/* Wrapper for struct ath_ops. */
-struct gcry_thread_cbs
-{
- /* The OPTION field encodes the thread model and the version number
- of this structure.
- Bits 7 - 0 are used for the thread model
- Bits 15 - 8 are used for the version number. */
- unsigned int option;
-} _GCRY_ATTR_INTERNAL;
-
-#define GCRY_THREAD_OPTION_PTH_IMPL \
- static struct gcry_thread_cbs gcry_threads_pth = { \
- (GCRY_THREAD_OPTION_PTH | (GCRY_THREAD_OPTION_VERSION << 8))}
-
-#define GCRY_THREAD_OPTION_PTHREAD_IMPL \
- static struct gcry_thread_cbs gcry_threads_pthread = { \
- (GCRY_THREAD_OPTION_PTHREAD | (GCRY_THREAD_OPTION_VERSION << 8))}
-
-
\f
/* The data object used to hold a multi precision integer. */
struct gcry_mpi;
GCRYCTL_FORCE_FIPS_MODE = 56,
GCRYCTL_SELFTEST = 57,
/* Note: 58 .. 62 are used internally. */
- GCRYCTL_DISABLE_HWF = 63
+ GCRYCTL_DISABLE_HWF = 63,
+ GCRYCTL_SET_ENFORCED_FIPS_FLAG = 64
};
/* Perform various operations defined by CMD. */
#define gcry_cipher_test_algo(a) \
gcry_cipher_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+/* Get a list consisting of the IDs of the loaded cipher modules. If
+ LIST is zero, write the number of loaded cipher modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less cipher modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_cipher_list (int *list, int *list_length);
+
\f
/************************************
* *
#define gcry_pk_test_algo(a) \
gcry_pk_algo_info( (a), GCRYCTL_TEST_ALGO, NULL, NULL )
+/* Get a list consisting of the IDs of the loaded pubkey modules. If
+ LIST is zero, write the number of loaded pubkey modules to
+ LIST_LENGTH and return. If LIST is non-zero, the first
+ *LIST_LENGTH algorithm IDs are stored in LIST, which must be of
+ according size. In case there are less pubkey modules than
+ *LIST_LENGTH, *LIST_LENGTH is updated to the correct number. */
+gcry_error_t gcry_pk_list (int *list, int *list_length);
\f
#define gcry_md_get_asnoid(a,b,n) \
gcry_md_algo_info((a), GCRYCTL_GET_ASNOID, (b), (n))
+/* Enable debugging for digest object A; i.e. create files named
+ dbgmd-<n>.<string> while hashing. B is a string used as the suffix
+ for the filename. This macro is deprecated, use gcry_md_debug. */
+#ifndef GCRYPT_NO_DEPRECATED
+#define gcry_md_start_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_START_DUMP, (b), 0 )
+
+/* Disable the debugging of A. This macro is deprecated, use
+ gcry_md_debug. */
+#define gcry_md_stop_debug(a,b) \
+ gcry_md_ctl( (a), GCRYCTL_STOP_DUMP, (b), 0 )
+#endif
+
+/* Get a list consisting of the IDs of the loaded message digest
+ modules. If LIST is zero, write the number of loaded message
+ digest modules to LIST_LENGTH and return. If LIST is non-zero, the
+ first *LIST_LENGTH algorithm IDs are stored in LIST, which must be
+ of according size. In case there are less message digest modules
+ than *LIST_LENGTH, *LIST_LENGTH is updated to the correct
+ number. */
+gcry_error_t gcry_md_list (int *list, int *list_length);
+
+\f
+#if !defined(GCRYPT_NO_DEPRECATED) || defined(_GCRYPT_IN_LIBGCRYPT)
+/* Alternative interface for asymmetric cryptography. This interface
+ is deprecated. */
+
+/* The algorithm IDs. */
+typedef enum gcry_ac_id
+ {
+ GCRY_AC_RSA = 1,
+ GCRY_AC_DSA = 17,
+ GCRY_AC_ELG = 20,
+ GCRY_AC_ELG_E = 16
+ }
+gcry_ac_id_t _GCRY_ATTR_INTERNAL;
+
+/* Key types. */
+typedef enum gcry_ac_key_type
+ {
+ GCRY_AC_KEY_SECRET,
+ GCRY_AC_KEY_PUBLIC
+ }
+gcry_ac_key_type_t _GCRY_ATTR_INTERNAL;
+
+/* Encoding methods. */
+typedef enum gcry_ac_em
+ {
+ GCRY_AC_EME_PKCS_V1_5,
+ GCRY_AC_EMSA_PKCS_V1_5
+ }
+gcry_ac_em_t _GCRY_ATTR_INTERNAL;
+
+/* Encryption and Signature schemes. */
+typedef enum gcry_ac_scheme
+ {
+ GCRY_AC_ES_PKCS_V1_5,
+ GCRY_AC_SSA_PKCS_V1_5
+ }
+gcry_ac_scheme_t _GCRY_ATTR_INTERNAL;
+
+/* AC data. */
+#define GCRY_AC_FLAG_DEALLOC (1 << 0)
+#define GCRY_AC_FLAG_COPY (1 << 1)
+#define GCRY_AC_FLAG_NO_BLINDING (1 << 2)
+
+/* This type represents a `data set'. */
+typedef struct gcry_ac_data *gcry_ac_data_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a single `key', either a secret one or a
+ public one. */
+typedef struct gcry_ac_key *gcry_ac_key_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `key pair' containing a secret and a public
+ key. */
+typedef struct gcry_ac_key_pair *gcry_ac_key_pair_t _GCRY_ATTR_INTERNAL;
+
+/* This type represents a `handle' that is needed by functions
+ performing cryptographic operations. */
+typedef struct gcry_ac_handle *gcry_ac_handle_t _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_read_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t *buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef gpg_error_t (*gcry_ac_data_write_cb_t) (void *opaque,
+ unsigned char *buffer,
+ size_t buffer_n)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_READABLE,
+ GCRY_AC_IO_WRITABLE
+ }
+gcry_ac_io_mode_t _GCRY_ATTR_INTERNAL;
+
+typedef enum
+ {
+ GCRY_AC_IO_STRING,
+ GCRY_AC_IO_CALLBACK
+ }
+gcry_ac_io_type_t _GCRY_ATTR_INTERNAL;
+
+typedef struct gcry_ac_io
+{
+ /* This is an INTERNAL structure, do NOT use manually. */
+ gcry_ac_io_mode_t mode _GCRY_ATTR_INTERNAL;
+ gcry_ac_io_type_t type _GCRY_ATTR_INTERNAL;
+ union
+ {
+ union
+ {
+ struct
+ {
+ gcry_ac_data_read_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char *data;
+ size_t data_n;
+ } string;
+ void *opaque;
+ } readable;
+ union
+ {
+ struct
+ {
+ gcry_ac_data_write_cb_t cb;
+ void *opaque;
+ } callback;
+ struct
+ {
+ unsigned char **data;
+ size_t *data_n;
+ } string;
+ void *opaque;
+ } writable;
+ } io _GCRY_ATTR_INTERNAL;
+}
+gcry_ac_io_t _GCRY_ATTR_INTERNAL;
+
+/* The caller of gcry_ac_key_pair_generate can provide one of these
+ structures in order to influence the key generation process in an
+ algorithm-specific way. */
+typedef struct gcry_ac_key_spec_rsa
+{
+ gcry_mpi_t e; /* E to use. */
+} gcry_ac_key_spec_rsa_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EME-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_eme_pkcs_v1_5
+{
+ size_t key_size;
+} gcry_ac_eme_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+typedef enum gcry_md_algos gcry_md_algo_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `EMSA-PKCS-V1_5' encoding method. */
+typedef struct gcry_ac_emsa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+ size_t em_n;
+} gcry_ac_emsa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+
+/* Structure used for passing data to the implementation of the
+ `SSA-PKCS-V1_5' signature scheme. */
+typedef struct gcry_ac_ssa_pkcs_v1_5
+{
+ gcry_md_algo_t md;
+} gcry_ac_ssa_pkcs_v1_5_t _GCRY_ATTR_INTERNAL;
+#endif /* !GCRYPT_NO_DEPRECATED || !_GCRYPT_IN_LIBGCRYPT */
+
+
+#ifndef GCRYPT_NO_DEPRECATED
+/* Returns a new, empty data set in DATA. */
+gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy the data set DATA. */
+void gcry_ac_data_destroy (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a copy of the data set DATA and store it in DATA_CP. */
+gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+ gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Return the number of named MPI values inside of the data set
+ DATA. */
+unsigned int gcry_ac_data_length (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy any values contained in the data set DATA. */
+void gcry_ac_data_clear (gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Add the value MPI to DATA with the label NAME. If FLAGS contains
+ GCRY_AC_FLAG_DATA_COPY, the data set will contain copies of NAME
+ and MPI. If FLAGS contains GCRY_AC_FLAG_DATA_DEALLOC or
+ GCRY_AC_FLAG_DATA_COPY, the values contained in the data set will
+ be deallocated when they are to be removed from the data set. */
+gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the value labelled with NAME found in DATA in MPI. If FLAGS
+ contains GCRY_AC_FLAG_COPY, store a copy of the MPI value contained
+ in the data set. MPI may be NULL. */
+gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores in NAME and MPI the named MPI value contained in the data
+ set DATA with the index IDX. If FLAGS contains GCRY_AC_FLAG_COPY,
+ store copies of the values contained in the data set. NAME or MPI
+ may be NULL. */
+gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Convert the data set DATA into a new S-Expression, which is to be
+ stored in SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new data set, which is to be stored in DATA_SET, from the
+ S-Expression SEXP, according to the identifiers contained in
+ IDENTIFIERS. */
+gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize AC_IO according to MODE, TYPE and the variable list of
+ arguments AP. The list of variable arguments to specify depends on
+ the given TYPE. */
+void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Create a new ac handle. */
+gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy an ac handle. */
+void gcry_ac_close (gcry_ac_handle_t handle)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Initialize a key from a given data set. */
+gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Generates a new key pair via the handle HANDLE of NBITS bits and
+ stores it in KEY_PAIR. In case non-standard settings are wanted, a
+ pointer to a structure of type gcry_ac_key_spec_<algorithm>_t,
+ matching the selected algorithm, can be given as KEY_SPEC.
+ MISC_DATA is not used yet. */
+gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the key of type WHICH out of the key pair KEY_PAIR. */
+gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Returns the data set contained in the key KEY. */
+gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies that the key KEY is sane via HANDLE. */
+gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Stores the number of bits of the key KEY in NBITS via HANDLE. */
+gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Writes the 20 byte long key grip of the key KEY to KEY_GRIP via
+ HANDLE. */
+gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key. */
+void gcry_ac_key_destroy (gcry_ac_key_t key)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Destroy a key pair. */
+void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decodes a message according to the encoding method METHOD. OPTIONS
+ must be a pointer to a method-specific structure
+ (gcry_ac_em*_t). */
+gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypt the plain text MPI value DATA_PLAIN with the key KEY under
+ the control of the flags FLAGS and store the resulting data set
+ into DATA_ENCRYPTED. */
+gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypt the decrypted data contained in the data set DATA_ENCRYPTED
+ with the key KEY under the control of the flags FLAGS and store the
+ resulting plain text MPI value in DATA_PLAIN. */
+gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Sign the data contained in DATA with the key KEY and store the
+ resulting signature in the data set DATA_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verify that the signature contained in the data set DATA_SIGNATURE
+ is indeed the result of signing the data contained in DATA with the
+ secret key belonging to the public key KEY. */
+gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Encrypts the plain text readable from IO_MESSAGE through HANDLE
+ with the public key KEY according to SCHEME, FLAGS and OPTS. If
+ OPTS is not NULL, it has to be a pointer to a structure specific to
+ the chosen scheme (gcry_ac_es_*_t). The encrypted message is
+ written to IO_CIPHER. */
+gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Decrypts the cipher text readable from IO_CIPHER through HANDLE
+ with the secret key KEY according to SCHEME, @var{flags} and OPTS.
+ If OPTS is not NULL, it has to be a pointer to a structure specific
+ to the chosen scheme (gcry_ac_es_*_t). The decrypted message is
+ written to IO_MESSAGE. */
+gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Signs the message readable from IO_MESSAGE through HANDLE with the
+ secret key KEY according to SCHEME, FLAGS and OPTS. If OPTS is not
+ NULL, it has to be a pointer to a structure specific to the chosen
+ scheme (gcry_ac_ssa_*_t). The signature is written to
+ IO_SIGNATURE. */
+gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Verifies through HANDLE that the signature readable from
+ IO_SIGNATURE is indeed the result of signing the message readable
+ from IO_MESSAGE with the secret key belonging to the public key KEY
+ according to SCHEME and OPTS. If OPTS is not NULL, it has to be an
+ anonymous structure (gcry_ac_ssa_*_t) specific to the chosen
+ scheme. */
+gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+ /* */ _GCRY_ATTR_INTERNAL;
+
+/* Store the textual representation of the algorithm whose id is given
+ in ALGORITHM in NAME. This function is deprecated; use
+ gcry_pk_algo_name. */
+gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm,
+ const char **name)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+/* Store the numeric ID of the algorithm whose textual representation
+ is contained in NAME in ALGORITHM. This function is deprecated;
+ use gcry_pk_map_name. */
+gcry_error_t gcry_ac_name_to_id (const char *name,
+ gcry_ac_id_t *algorithm)
+ /* */ _GCRY_GCC_ATTR_DEPRECATED;
+#endif /*GCRYPT_NO_DEPRECATED*/
\f
/******************************
#define gcry_fips_mode_active() !!gcry_control (GCRYCTL_FIPS_MODE_P, 0)
+/* Include support for Libgcrypt modules. */
+#include <gcrypt-module.h>
+
#if 0 /* (Keep Emacsens' auto-indent happy.) */
{
#endif
/* Initialize our portable thread/mutex wrapper. */
err = ath_init ();
if (err)
- {
- err = gpg_error_from_errno (err);
- goto fail;
- }
+ goto fail;
/* See whether the system is in FIPS mode. This needs to come as
- early as possible but after ATH has been initialized. */
+ early as possible put after the ATH has been initialized. */
_gcry_initialize_fips_mode (force_fips_mode);
/* Before we do any other initialization we need to test available
hardware features. */
_gcry_detect_hw_features (disabled_hw_features);
- /* Initialize the modules - this is mainly allocating some memory and
- creating mutexes. */
err = _gcry_cipher_init ();
if (err)
goto fail;
err = _gcry_pk_init ();
if (err)
goto fail;
- err = _gcry_primegen_init ();
- if (err)
- goto fail;
+#if 0
+ /* Hmmm, as of now ac_init does nothing. */
+ if ( !fips_mode () )
+ {
+ err = _gcry_ac_init ();
+ if (err)
+ goto fail;
+ }
+#endif
return;
int rq_major, rq_minor, rq_micro;
const char *my_plvl;
+ if (req_version && req_version[0] == 1 && req_version[1] == 1)
+ return _gcry_compat_identification ();
+
/* Initialize library. */
global_init ();
#endif
"\n");
fnc (fp, "mpi-asm:%s:\n", _gcry_mpi_get_hw_config ());
- fnc (fp, "threads:%s:\n", ath_get_model (NULL));
hwf = _gcry_get_hw_features ();
fnc (fp, "hwflist:");
for (i=0; hwflist[i].desc; i++)
break;
case GCRYCTL_SET_THREAD_CBS:
- err = ath_install (va_arg (arg_ptr, void *));
- if (!err)
+ err = ath_install (va_arg (arg_ptr, void *), any_init_done);
+ if (! err)
global_init ();
break;
}
break;
+ case GCRYCTL_SET_ENFORCED_FIPS_FLAG:
+ if (!any_init_done)
+ {
+ /* Not yet intialized at all. Set the enforced fips mode flag */
+ _gcry_set_enforced_fips_mode ();
+ }
+ else
+ err = GPG_ERR_GENERAL;
+ break;
+
default:
- /* A call to make sure that the dummy code is linked in. */
- _gcry_compat_identification ();
err = GPG_ERR_INV_OP;
}
pgm, strerror (errno));
exit (1);
}
- if (use_stdin)
- break;
}
else
{
gcry_cipher_decrypt @101
gcry_cipher_get_algo_keylen @102
gcry_cipher_get_algo_blklen @103
-
-;; @104 used to be part of the module register interface
+ gcry_cipher_list @104
gcry_pk_encrypt @105
gcry_pk_decrypt @106
gcry_pk_map_name @114
gcry_pk_get_nbits @115
gcry_pk_get_keygrip @116
-
-;; @117 used to be part of the module register interface
-
-;;
-;; 118 to 142 were used in previous Libgcrypt versions for the gcry_ac
-;; interface
-;;
+ gcry_pk_list @117
+
+ gcry_ac_data_new @118
+ gcry_ac_data_destroy @119
+ gcry_ac_data_set @120
+ gcry_ac_data_copy @121
+ gcry_ac_data_length @122
+ gcry_ac_data_get_name @123
+ gcry_ac_data_get_index @124
+ gcry_ac_data_clear @125
+ gcry_ac_open @126
+ gcry_ac_close @127
+ gcry_ac_key_init @128
+ gcry_ac_key_pair_generate @129
+ gcry_ac_key_pair_extract @130
+ gcry_ac_key_data_get @131
+ gcry_ac_key_test @132
+ gcry_ac_key_get_nbits @133
+ gcry_ac_key_get_grip @134
+ gcry_ac_key_destroy @135
+ gcry_ac_key_pair_destroy @136
+ gcry_ac_data_encrypt @137
+ gcry_ac_data_decrypt @138
+ gcry_ac_data_sign @139
+ gcry_ac_data_verify @140
+ gcry_ac_id_to_name @141
+ gcry_ac_name_to_id @142
gcry_md_open @143
gcry_md_close @144
gcry_md_algo_name @158
gcry_md_map_name @159
gcry_md_setkey @160
-;; @161 used to be part of the module register interface
+ gcry_md_list @161
+
gcry_randomize @162
gcry_random_add_bytes @163
gcry_random_bytes @164
gcry_md_debug @172
-;; @173 used to be part of the module register interface
-;; @174 used to be part of the module register interface
-;; @175 used to be part of the module register interface
-;; @176 used to be part of the module register interface
-;; @177 used to be part of the module register interface
-;; @178 used to be part of the module register interface
-;;
-;; @179 to @186 used to be part of the removed gcry_ac interface
-;;
+ gcry_cipher_register @173
+ gcry_cipher_unregister @174
+ gcry_md_register @175
+ gcry_md_unregister @176
+ gcry_pk_register @177
+ gcry_pk_unregister @178
+
+ gcry_ac_data_from_sexp @179
+ gcry_ac_data_to_sexp @180
+ gcry_ac_io_init @181
+ gcry_ac_io_init_va @182
+ gcry_ac_data_encrypt_scheme @183
+ gcry_ac_data_decrypt_scheme @184
+ gcry_ac_data_sign_scheme @185
+ gcry_ac_data_verify_scheme @186
gcry_sexp_nth_string @187
dnl Autoconf macros for libgcrypt
-dnl Copyright (C) 2002, 2004, 2011 Free Software Foundation, Inc.
+dnl Copyright (C) 2002, 2004 Free Software Foundation, Inc.
dnl
dnl This file is free software; as a special exception the author gives
dnl unlimited permission to copy and/or distribute it, with or without
dnl with a changed API.
dnl
AC_DEFUN([AM_PATH_LIBGCRYPT],
-[ AC_REQUIRE([AC_CANONICAL_HOST])
- AC_ARG_WITH(libgcrypt-prefix,
+[ AC_ARG_WITH(libgcrypt-prefix,
AC_HELP_STRING([--with-libgcrypt-prefix=PFX],
[prefix where LIBGCRYPT is installed (optional)]),
libgcrypt_config_prefix="$withval", libgcrypt_config_prefix="")
LIBGCRYPT_CFLAGS=`$LIBGCRYPT_CONFIG --cflags`
LIBGCRYPT_LIBS=`$LIBGCRYPT_CONFIG --libs`
ifelse([$2], , :, [$2])
- libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
- if test x"$libgcrypt_config_host" != xnone ; then
- if test x"$libgcrypt_config_host" != x"$host" ; then
+ if test x"$host" != x ; then
+ libgcrypt_config_host=`$LIBGCRYPT_CONFIG --host 2>/dev/null || echo none`
+ if test x"$libgcrypt_config_host" != xnone ; then
+ if test x"$libgcrypt_config_host" != x"$host" ; then
AC_MSG_WARN([[
***
*** The config script $LIBGCRYPT_CONFIG was
*** You may want to use the configure option --with-libgcrypt-prefix
*** to specify a matching config script.
***]])
+ fi
fi
fi
else
# libgcrypt.vers - What symbols to export -*- std -*-
-# Copyright (C) 2002, 2004, 2008, 2011 Free Software Foundation, Inc.
+# Copyright (C) 2002, 2004, 2008 Free Software Foundation, Inc.
#
# This file is part of Libgcrypt.
#
# NOTE: When adding new functions, please make sure to add them to
# visibility.h and libgcrypt.def as well.
-GCRYPT_1.6 {
+GCRYPT_1.2 {
global:
gcry_check_version; gcry_control;
gcry_set_allocation_handler; gcry_set_fatalerror_handler;
gcry_md_copy; gcry_md_ctl; gcry_md_enable; gcry_md_get;
gcry_md_get_algo; gcry_md_get_algo_dlen; gcry_md_hash_buffer;
gcry_md_info; gcry_md_is_enabled; gcry_md_is_secure;
- gcry_md_map_name; gcry_md_open; gcry_md_read;
- gcry_md_reset; gcry_md_setkey;
- gcry_md_write; gcry_md_debug;
+ gcry_md_list; gcry_md_map_name; gcry_md_open; gcry_md_read;
+ gcry_md_register; gcry_md_reset; gcry_md_setkey;
+ gcry_md_unregister; gcry_md_write; gcry_md_debug;
gcry_cipher_algo_info; gcry_cipher_algo_name; gcry_cipher_close;
gcry_cipher_ctl; gcry_cipher_decrypt; gcry_cipher_encrypt;
gcry_cipher_get_algo_blklen; gcry_cipher_get_algo_keylen;
- gcry_cipher_info; gcry_cipher_map_name;
+ gcry_cipher_info; gcry_cipher_list; gcry_cipher_map_name;
gcry_cipher_mode_from_oid; gcry_cipher_open;
+ gcry_cipher_register; gcry_cipher_unregister;
gcry_cipher_setkey; gcry_cipher_setiv; gcry_cipher_setctr;
gcry_pk_algo_info; gcry_pk_algo_name; gcry_pk_ctl;
gcry_pk_decrypt; gcry_pk_encrypt; gcry_pk_genkey;
- gcry_pk_get_keygrip; gcry_pk_get_nbits;
+ gcry_pk_get_keygrip; gcry_pk_get_nbits; gcry_pk_list;
gcry_pk_map_name; gcry_pk_register; gcry_pk_sign;
- gcry_pk_testkey; gcry_pk_verify;
+ gcry_pk_testkey; gcry_pk_unregister; gcry_pk_verify;
gcry_pk_get_curve; gcry_pk_get_param;
+ gcry_ac_data_new; gcry_ac_data_destroy; gcry_ac_data_copy;
+ gcry_ac_data_length; gcry_ac_data_clear; gcry_ac_data_set;
+ gcry_ac_data_get_name; gcry_ac_data_get_index; gcry_ac_open;
+ gcry_ac_close; gcry_ac_key_init; gcry_ac_key_pair_generate;
+ gcry_ac_key_pair_extract; gcry_ac_key_data_get; gcry_ac_key_test;
+ gcry_ac_key_get_nbits; gcry_ac_key_get_grip; gcry_ac_key_destroy;
+ gcry_ac_key_pair_destroy; gcry_ac_data_encrypt; gcry_ac_data_decrypt;
+ gcry_ac_data_sign; gcry_ac_data_verify; gcry_ac_id_to_name;
+ gcry_ac_name_to_id; gcry_ac_list; gcry_ac_data_encode;
+ gcry_ac_data_decode; gcry_ac_mpi_to_os; gcry_ac_mpi_to_os_alloc;
+ gcry_ac_os_to_mpi; gcry_ac_data_encrypt_scheme;
+ gcry_ac_data_decrypt_scheme;
+ gcry_ac_data_sign_scheme; gcry_ac_data_verify_scheme;
+ gcry_ac_data_to_sexp; gcry_ac_data_from_sexp;
+ gcry_ac_io_init; gcry_ac_io_init_va;
+
gcry_kdf_derive;
gcry_prime_check; gcry_prime_generate;
# define mpi_alloc_secure(n) _gcry_mpi_alloc_secure((n) )
# define mpi_free(a) _gcry_mpi_free((a) )
# define mpi_resize(a,b) _gcry_mpi_resize((a),(b))
-# define mpi_copy(a) gcry_mpi_copy((a))
+# define mpi_copy(a) _gcry_mpi_copy((a))
gcry_mpi_t _gcry_mpi_alloc( unsigned nlimbs );
gcry_mpi_t _gcry_mpi_alloc_secure( unsigned nlimbs );
void _gcry_mpi_free( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_copy( gcry_mpi_t a );
#endif
+#define gcry_mpi_copy _gcry_mpi_copy
+
#define mpi_is_opaque(a) ((a) && ((a)->flags&4))
#define mpi_is_secure(a) ((a) && ((a)->flags&1))
#define mpi_clear(a) _gcry_mpi_clear ((a))
#define mpi_alloc_set_ui(a) _gcry_mpi_alloc_set_ui ((a))
#define mpi_m_check(a) _gcry_mpi_m_check ((a))
#define mpi_swap(a,b) _gcry_mpi_swap ((a),(b))
-#define mpi_new(n) gcry_mpi_new ((n))
+#define mpi_new(n) _gcry_mpi_new ((n))
#define mpi_snew(n) _gcry_mpi_snew ((n))
void _gcry_mpi_clear( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_like( gcry_mpi_t a );
gcry_mpi_t _gcry_mpi_alloc_set_ui( unsigned long u);
gcry_err_code_t _gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
+gcry_err_code_t gcry_mpi_get_ui (gcry_mpi_t w, ulong *u);
void _gcry_mpi_m_check( gcry_mpi_t a );
void _gcry_mpi_swap( gcry_mpi_t a, gcry_mpi_t b);
gcry_mpi_t _gcry_mpi_new (unsigned int nbits);
p++;
if ( *p == ST_DATA ) {
- memcpy ( &n, p, sizeof n ); p += sizeof n;
- newlist = gcry_malloc ( sizeof *newlist + n + 1 );
+ memcpy ( &n, p, sizeof n );
+ /* Allocate 1 (=sizeof *newlist) byte for ST_OPEN
+ 1 byte for ST_DATA
+ sizeof n byte for n
+ n byte for the data
+ 1 byte for ST_CLOSE
+ 1 byte for ST_STOP */
+ newlist = gcry_malloc ( sizeof *newlist + 1 + sizeof n + n + 2 );
if (!newlist)
- return NULL;
- d = newlist->d;
- memcpy ( d, p, n ); d += n;
- *d++ = ST_STOP;
+ return NULL;
+ d = newlist->d;
+ *d = ST_OPEN; /* Put the ST_OPEN flag */
+ d++; /* Move forward */
+ /* Copy ST_DATA, n and the data from p to d */
+ memcpy ( d, p, 1 + sizeof n + n );
+ d += 1 + sizeof n + n; /* Move after the data copied */
+ *d = ST_CLOSE; /* Put the ST_CLOSE flag */
+ d++; /* Move forward */
+ *d = ST_STOP; /* Put the ST_STOP flag */
}
else if ( *p == ST_OPEN ) {
const byte *head = p;
VS_VERSION_INFO VERSIONINFO
- FILEVERSION @LIBGCRYPT_LT_CURRENT@,@LIBGCRYPT_LT_AGE@,@LIBGCRYPT_LT_REVISION@,@BUILD_REVISION@
+ FILEVERSION @BUILD_FILEVERSION@
PRODUCTVERSION @BUILD_FILEVERSION@
FILEFLAGSMASK 0x3fL
#ifdef _DEBUG
VALUE "FileDescription", "Libgcrypt - The GNU Crypto Library\0"
VALUE "FileVersion", "@LIBGCRYPT_LT_CURRENT@.@LIBGCRYPT_LT_AGE@.@LIBGCRYPT_LT_REVISION@.@BUILD_REVISION@\0"
VALUE "InternalName", "libgcrypt\0"
- VALUE "LegalCopyright", "Copyright © 2011 Free Software Foundation, Inc.\0"
+ VALUE "LegalCopyright", "Copyright © 2012 Free Software Foundation, Inc.\0"
VALUE "LegalTrademarks", "\0"
VALUE "OriginalFilename", "libgcrypt.dll\0"
VALUE "PrivateBuild", "\0"
return _gcry_cipher_get_algo_blklen (algo);
}
+gcry_error_t
+gcry_cipher_list (int *list, int *list_length)
+{
+ return _gcry_cipher_list (list, list_length);
+}
+
gcry_error_t
gcry_pk_encrypt (gcry_sexp_t *result, gcry_sexp_t data, gcry_sexp_t pkey)
{
return _gcry_pk_get_param (algo, name);
}
+gcry_error_t
+gcry_pk_list (int *list, int *list_length)
+{
+ return _gcry_pk_list (list, list_length);
+}
+
gcry_error_t
gcry_md_open (gcry_md_hd_t *h, int algo, unsigned int flags)
{
_gcry_md_debug (hd, suffix);
}
+gcry_error_t
+gcry_md_list (int *list, int *list_length)
+{
+ return _gcry_md_list (list, list_length);
+}
+
+gcry_error_t
+gcry_ac_data_new (gcry_ac_data_t *data)
+{
+ return _gcry_ac_data_new (data);
+}
+
+void
+gcry_ac_data_destroy (gcry_ac_data_t data)
+{
+ _gcry_ac_data_destroy (data);
+}
+
+gcry_error_t
+gcry_ac_data_copy (gcry_ac_data_t *data_cp, gcry_ac_data_t data)
+{
+ return _gcry_ac_data_copy (data_cp, data);
+}
+
+unsigned int
+gcry_ac_data_length (gcry_ac_data_t data)
+{
+ return _gcry_ac_data_length (data);
+}
+
+void
+gcry_ac_data_clear (gcry_ac_data_t data)
+{
+ _gcry_ac_data_clear (data);
+}
+
+gcry_error_t
+gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi)
+{
+ return _gcry_ac_data_set (data, flags, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi)
+{
+ return _gcry_ac_data_get_name (data, flags, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx, const char **name, gcry_mpi_t *mpi)
+{
+ return _gcry_ac_data_get_index (data, flags, idx, name, mpi);
+}
+
+gcry_error_t
+gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers)
+{
+ return _gcry_ac_data_to_sexp (data, sexp, identifiers);
+}
+
+gcry_error_t
+gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers)
+{
+ return _gcry_ac_data_from_sexp (data, sexp, identifiers);
+}
+
+void
+gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...)
+{
+ va_list arg_ptr;
+
+ va_start (arg_ptr, type);
+ _gcry_ac_io_init_va (ac_io, mode, type, arg_ptr);
+ va_end (arg_ptr);
+}
+
+void
+gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap)
+{
+ _gcry_ac_io_init_va (ac_io, mode, type, ap);
+}
+
+gcry_error_t
+gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags)
+{
+ return _gcry_ac_open (handle, algorithm, flags);
+}
+
+void
+gcry_ac_close (gcry_ac_handle_t handle)
+{
+ _gcry_ac_close (handle);
+}
+
+gcry_error_t
+gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data)
+{
+ return _gcry_ac_key_init (key, handle, type, data);
+}
+
+gcry_error_t
+gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **miscdata)
+{
+ return _gcry_ac_key_pair_generate ( handle, nbits, spec, key_pair, miscdata);
+}
+
+gcry_ac_key_t
+gcry_ac_key_pair_extract (gcry_ac_key_pair_t keypair, gcry_ac_key_type_t which)
+{
+ return _gcry_ac_key_pair_extract (keypair, which);
+}
+
+gcry_ac_data_t
+gcry_ac_key_data_get (gcry_ac_key_t key)
+{
+ return _gcry_ac_key_data_get (key);
+}
+
+gcry_error_t
+gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key)
+{
+ return _gcry_ac_key_test (handle, key);
+}
+
+gcry_error_t
+gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits)
+{
+ return _gcry_ac_key_get_nbits (handle, key, nbits);
+}
+
+gcry_error_t
+gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip)
+{
+ return _gcry_ac_key_get_grip (handle, key, key_grip);
+}
+
+void
+gcry_ac_key_destroy (gcry_ac_key_t key)
+{
+ _gcry_ac_key_destroy (key);
+}
+
+void
+gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair)
+{
+ _gcry_ac_key_pair_destroy (key_pair);
+}
+
+gcry_error_t
+gcry_ac_data_encode (gcry_ac_em_t method, unsigned int flags, void *options,
+ gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
+{
+ return _gcry_ac_data_encode (method, flags, options, io_read, io_write);
+}
+
+gcry_error_t
+gcry_ac_data_decode (gcry_ac_em_t method, unsigned int flags, void *options,
+ gcry_ac_io_t *io_read, gcry_ac_io_t *io_write)
+{
+ return _gcry_ac_data_decode (method, flags, options, io_read, io_write);
+}
+
+gcry_error_t
+gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted)
+{
+ return _gcry_ac_data_encrypt (handle, flags, key,
+ data_plain, data_encrypted);
+}
+
+gcry_error_t
+gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted)
+{
+ return _gcry_ac_data_decrypt (handle, flags, key,
+ data_plain, data_encrypted);
+}
+
+gcry_error_t
+gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature)
+{
+ return _gcry_ac_data_sign (handle, key, data, data_signature);
+}
+
+gcry_error_t
+gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature)
+{
+ return _gcry_ac_data_verify (handle, key, data, data_signature);
+}
+
+gcry_error_t
+gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher)
+{
+ return _gcry_ac_data_encrypt_scheme (handle, scheme, flags, opts, key,
+ io_message, io_cipher);
+}
+
+gcry_error_t
+gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message)
+{
+ return _gcry_ac_data_decrypt_scheme (handle, scheme, flags, opts, key,
+ io_cipher, io_message);
+}
+
+gcry_error_t
+gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ return _gcry_ac_data_sign_scheme (handle, scheme, flags, opts, key,
+ io_message, io_signature);
+}
+
+gcry_error_t
+gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature)
+{
+ return _gcry_ac_data_verify_scheme (handle, scheme, flags, opts, key,
+ io_message, io_signature);
+}
+
+gcry_error_t
+gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name)
+{
+ /* This function is deprecated. We implement it in terms of the
+ suggested replacement. */
+ const char *tmp = _gcry_pk_algo_name (algorithm);
+ if (!*tmp)
+ return gcry_error (GPG_ERR_PUBKEY_ALGO);
+ *name = tmp;
+ return 0;
+}
+
+gcry_error_t
+gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm)
+{
+ /* This function is deprecated. We implement it in terms of the
+ suggested replacement. */
+ int algo = _gcry_pk_map_name (name);
+ if (!algo)
+ return gcry_error (GPG_ERR_PUBKEY_ALGO);
+ *algorithm = algo;
+ return 0;
+}
+
gpg_error_t
gcry_kdf_derive (const void *passphrase, size_t passphraselen,
int algo, int hashalgo,
{
return _gcry_is_secure (a);
}
+
+
+gcry_error_t
+gcry_cipher_register (gcry_cipher_spec_t *cipher, int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_cipher_register (cipher, NULL, algorithm_id, module);
+}
+
+void
+gcry_cipher_unregister (gcry_module_t module)
+{
+ _gcry_cipher_unregister (module);
+}
+
+gcry_error_t
+gcry_pk_register (gcry_pk_spec_t *pubkey, unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_pk_register (pubkey, NULL, algorithm_id, module);
+}
+
+void
+gcry_pk_unregister (gcry_module_t module)
+{
+ _gcry_pk_unregister (module);
+}
+
+gcry_error_t
+gcry_md_register (gcry_md_spec_t *digest, unsigned int *algorithm_id,
+ gcry_module_t *module)
+{
+ return _gcry_md_register (digest, NULL, algorithm_id, module);
+}
+
+void
+gcry_md_unregister (gcry_module_t module)
+{
+ _gcry_md_unregister (module);
+}
#define gcry_md_info _gcry_md_info
#define gcry_md_is_enabled _gcry_md_is_enabled
#define gcry_md_is_secure _gcry_md_is_secure
+#define gcry_md_list _gcry_md_list
#define gcry_md_map_name _gcry_md_map_name
#define gcry_md_open _gcry_md_open
#define gcry_md_read _gcry_md_read
+/* gcry_md_register and _gcry_md_register differ. */
+#define gcry_md_unregister _gcry_md_unregister
#define gcry_md_reset _gcry_md_reset
#define gcry_md_setkey _gcry_md_setkey
#define gcry_md_write _gcry_md_write
#define gcry_cipher_get_algo_blklen _gcry_cipher_get_algo_blklen
#define gcry_cipher_get_algo_keylen _gcry_cipher_get_algo_keylen
#define gcry_cipher_info _gcry_cipher_info
+#define gcry_cipher_list _gcry_cipher_list
#define gcry_cipher_map_name _gcry_cipher_map_name
#define gcry_cipher_mode_from_oid _gcry_cipher_mode_from_oid
#define gcry_cipher_open _gcry_cipher_open
+/* gcry_cipher_register and _gcry_cipher_register differ. */
+#define gcry_cipher_unregister _gcry_cipher_unregister
#define gcry_pk_algo_info _gcry_pk_algo_info
#define gcry_pk_algo_name _gcry_pk_algo_name
#define gcry_pk_get_curve _gcry_pk_get_curve
#define gcry_pk_get_param _gcry_pk_get_param
#define gcry_pk_get_nbits _gcry_pk_get_nbits
+#define gcry_pk_list _gcry_pk_list
#define gcry_pk_map_name _gcry_pk_map_name
+/* gcry_pk_register and _gcry_pk_register differ. */
+#define gcry_pk_unregister _gcry_pk_unregister
#define gcry_pk_sign _gcry_pk_sign
#define gcry_pk_testkey _gcry_pk_testkey
#define gcry_pk_verify _gcry_pk_verify
+#define gcry_ac_data_new _gcry_ac_data_new
+#define gcry_ac_data_destroy _gcry_ac_data_destroy
+#define gcry_ac_data_copy _gcry_ac_data_copy
+#define gcry_ac_data_length _gcry_ac_data_length
+#define gcry_ac_data_clear _gcry_ac_data_clear
+#define gcry_ac_data_set _gcry_ac_data_set
+#define gcry_ac_data_get_name _gcry_ac_data_get_name
+#define gcry_ac_data_get_index _gcry_ac_data_get_index
+#define gcry_ac_open _gcry_ac_open
+#define gcry_ac_close _gcry_ac_close
+#define gcry_ac_key_init _gcry_ac_key_init
+#define gcry_ac_key_pair_generate _gcry_ac_key_pair_generate
+#define gcry_ac_key_pair_extract _gcry_ac_key_pair_extract
+#define gcry_ac_key_data_get _gcry_ac_key_data_get
+#define gcry_ac_key_test _gcry_ac_key_test
+#define gcry_ac_key_get_nbits _gcry_ac_key_get_nbits
+#define gcry_ac_key_get_grip _gcry_ac_key_get_grip
+#define gcry_ac_key_destroy _gcry_ac_key_destroy
+#define gcry_ac_key_pair_destroy _gcry_ac_key_pair_destroy
+#define gcry_ac_data_encrypt _gcry_ac_data_encrypt
+#define gcry_ac_data_decrypt _gcry_ac_data_decrypt
+#define gcry_ac_data_sign _gcry_ac_data_sign
+#define gcry_ac_data_verify _gcry_ac_data_verify
+#define gcry_ac_id_to_name _gcry_ac_id_to_name
+#define gcry_ac_name_to_id _gcry_ac_name_to_id
+#define gcry_ac_data_encode _gcry_ac_data_encode
+#define gcry_ac_data_decode _gcry_ac_data_decode
+#define gcry_ac_mpi_to_os _gcry_ac_mpi_to_os
+#define gcry_ac_mpi_to_os_alloc _gcry_ac_mpi_to_os_alloc
+#define gcry_ac_os_to_mpi _gcry_ac_os_to_mpi
+#define gcry_ac_data_encrypt_scheme _gcry_ac_data_encrypt_scheme
+#define gcry_ac_data_decrypt_scheme _gcry_ac_data_decrypt_scheme
+#define gcry_ac_data_sign_scheme _gcry_ac_data_sign_scheme
+#define gcry_ac_data_verify_scheme _gcry_ac_data_verify_scheme
+#define gcry_ac_data_to_sexp _gcry_ac_data_to_sexp
+#define gcry_ac_data_from_sexp _gcry_ac_data_from_sexp
+#define gcry_ac_io_init _gcry_ac_io_init
+#define gcry_ac_io_init_va _gcry_ac_io_init_va
+
#define gcry_kdf_derive _gcry_kdf_derive
#define gcry_prime_check _gcry_prime_check
deprecated attribute. */
# define GCRYPT_NO_DEPRECATED
# include "gcrypt.h"
- /* None in this version. */
+/* The algorithm IDs. */
+ gcry_error_t gcry_ac_data_new (gcry_ac_data_t *data);
+ void gcry_ac_data_destroy (gcry_ac_data_t data);
+ gcry_error_t gcry_ac_data_copy (gcry_ac_data_t *data_cp,
+ gcry_ac_data_t data);
+ unsigned int gcry_ac_data_length (gcry_ac_data_t data);
+ void gcry_ac_data_clear (gcry_ac_data_t data);
+ gcry_error_t gcry_ac_data_set (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t mpi);
+ gcry_error_t gcry_ac_data_get_name (gcry_ac_data_t data, unsigned int flags,
+ const char *name, gcry_mpi_t *mpi);
+ gcry_error_t gcry_ac_data_get_index (gcry_ac_data_t data, unsigned int flags,
+ unsigned int idx,
+ const char **name, gcry_mpi_t *mpi);
+ gcry_error_t gcry_ac_data_to_sexp (gcry_ac_data_t data, gcry_sexp_t *sexp,
+ const char **identifiers);
+ gcry_error_t gcry_ac_data_from_sexp (gcry_ac_data_t *data, gcry_sexp_t sexp,
+ const char **identifiers);
+ void gcry_ac_io_init (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, ...);
+ void gcry_ac_io_init_va (gcry_ac_io_t *ac_io, gcry_ac_io_mode_t mode,
+ gcry_ac_io_type_t type, va_list ap);
+ gcry_error_t gcry_ac_open (gcry_ac_handle_t *handle,
+ gcry_ac_id_t algorithm, unsigned int flags);
+ void gcry_ac_close (gcry_ac_handle_t handle);
+ gcry_error_t gcry_ac_key_init (gcry_ac_key_t *key, gcry_ac_handle_t handle,
+ gcry_ac_key_type_t type, gcry_ac_data_t data);
+ gcry_error_t gcry_ac_key_pair_generate (gcry_ac_handle_t handle,
+ unsigned int nbits, void *spec,
+ gcry_ac_key_pair_t *key_pair,
+ gcry_mpi_t **misc_data);
+ gcry_ac_key_t gcry_ac_key_pair_extract (gcry_ac_key_pair_t key_pair,
+ gcry_ac_key_type_t which);
+ gcry_ac_data_t gcry_ac_key_data_get (gcry_ac_key_t key);
+ gcry_error_t gcry_ac_key_test (gcry_ac_handle_t handle, gcry_ac_key_t key);
+ gcry_error_t gcry_ac_key_get_nbits (gcry_ac_handle_t handle,
+ gcry_ac_key_t key, unsigned int *nbits);
+ gcry_error_t gcry_ac_key_get_grip (gcry_ac_handle_t handle, gcry_ac_key_t key,
+ unsigned char *key_grip);
+ void gcry_ac_key_destroy (gcry_ac_key_t key);
+ void gcry_ac_key_pair_destroy (gcry_ac_key_pair_t key_pair);
+ gcry_error_t gcry_ac_data_encode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write);
+ gcry_error_t gcry_ac_data_decode (gcry_ac_em_t method,
+ unsigned int flags, void *options,
+ gcry_ac_io_t *io_read,
+ gcry_ac_io_t *io_write);
+ gcry_error_t gcry_ac_data_encrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t data_plain,
+ gcry_ac_data_t *data_encrypted);
+ gcry_error_t gcry_ac_data_decrypt (gcry_ac_handle_t handle,
+ unsigned int flags,
+ gcry_ac_key_t key,
+ gcry_mpi_t *data_plain,
+ gcry_ac_data_t data_encrypted);
+ gcry_error_t gcry_ac_data_sign (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t *data_signature);
+ gcry_error_t gcry_ac_data_verify (gcry_ac_handle_t handle,
+ gcry_ac_key_t key,
+ gcry_mpi_t data,
+ gcry_ac_data_t data_signature);
+ gcry_error_t gcry_ac_data_encrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_cipher);
+ gcry_error_t gcry_ac_data_decrypt_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_cipher,
+ gcry_ac_io_t *io_message);
+ gcry_error_t gcry_ac_data_sign_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature);
+ gcry_error_t gcry_ac_data_verify_scheme (gcry_ac_handle_t handle,
+ gcry_ac_scheme_t scheme,
+ unsigned int flags, void *opts,
+ gcry_ac_key_t key,
+ gcry_ac_io_t *io_message,
+ gcry_ac_io_t *io_signature);
+ gcry_error_t gcry_ac_id_to_name (gcry_ac_id_t algorithm, const char **name);
+ gcry_error_t gcry_ac_name_to_id (const char *name, gcry_ac_id_t *algorithm);
#else
# include "gcrypt.h"
#endif
-#include "gcrypt-module.h"
/* Prototypes of functions exported but not ready for use. */
gcry_err_code_t gcry_md_get (gcry_md_hd_t hd, int algo,
unsigned char *buffer, int buflen);
+void gcry_ac_mpi_to_os (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
+gcry_error_t gcry_ac_mpi_to_os_alloc (gcry_mpi_t mpi, unsigned char **os,
+ size_t *os_n);
+void gcry_ac_os_to_mpi (gcry_mpi_t mpi, unsigned char *os, size_t os_n);
+
/* Our use of the ELF visibility feature works by passing
#undef gcry_md_info
#undef gcry_md_is_enabled
#undef gcry_md_is_secure
+#undef gcry_md_list
#undef gcry_md_map_name
#undef gcry_md_open
#undef gcry_md_read
+/* gcry_md_register is not anymore a macro. */
+#undef gcry_md_unregister
#undef gcry_md_reset
#undef gcry_md_setkey
#undef gcry_md_write
#undef gcry_cipher_get_algo_blklen
#undef gcry_cipher_get_algo_keylen
#undef gcry_cipher_info
+#undef gcry_cipher_list
#undef gcry_cipher_map_name
#undef gcry_cipher_mode_from_oid
#undef gcry_cipher_open
+/* gcry_cipher_register is not anymore a macro. */
+#undef gcry_cipher_unregister
#undef gcry_pk_algo_info
#undef gcry_pk_algo_name
#undef gcry_pk_get_curve
#undef gcry_pk_get_param
#undef gcry_pk_get_nbits
+#undef gcry_pk_list
#undef gcry_pk_map_name
+/* gcry_pk_register is not anymore a macro. */
+#undef gcry_pk_unregister
#undef gcry_pk_sign
#undef gcry_pk_testkey
#undef gcry_pk_verify
+#undef gcry_ac_data_new
+#undef gcry_ac_data_destroy
+#undef gcry_ac_data_copy
+#undef gcry_ac_data_length
+#undef gcry_ac_data_clear
+#undef gcry_ac_data_set
+#undef gcry_ac_data_get_name
+#undef gcry_ac_data_get_index
+#undef gcry_ac_open
+#undef gcry_ac_close
+#undef gcry_ac_key_init
+#undef gcry_ac_key_pair_generate
+#undef gcry_ac_key_pair_extract
+#undef gcry_ac_key_data_get
+#undef gcry_ac_key_test
+#undef gcry_ac_key_get_nbits
+#undef gcry_ac_key_get_grip
+#undef gcry_ac_key_destroy
+#undef gcry_ac_key_pair_destroy
+#undef gcry_ac_data_encrypt
+#undef gcry_ac_data_decrypt
+#undef gcry_ac_data_sign
+#undef gcry_ac_data_verify
+#undef gcry_ac_id_to_name
+#undef gcry_ac_name_to_id
+#undef gcry_ac_data_encode
+#undef gcry_ac_data_decode
+#undef gcry_ac_mpi_to_os
+#undef gcry_ac_mpi_to_os_alloc
+#undef gcry_ac_os_to_mpi
+#undef gcry_ac_data_encrypt_scheme
+#undef gcry_ac_data_decrypt_scheme
+#undef gcry_ac_data_sign_scheme
+#undef gcry_ac_data_verify_scheme
+#undef gcry_ac_data_to_sexp
+#undef gcry_ac_data_from_sexp
+#undef gcry_ac_io_init
+#undef gcry_ac_io_init_va
+
#undef gcry_kdf_derive
#undef gcry_prime_check
MARK_VISIBLE (gcry_md_info)
MARK_VISIBLE (gcry_md_is_enabled)
MARK_VISIBLE (gcry_md_is_secure)
+MARK_VISIBLE (gcry_md_list)
MARK_VISIBLE (gcry_md_map_name)
MARK_VISIBLE (gcry_md_open)
MARK_VISIBLE (gcry_md_read)
+MARK_VISIBLEX(gcry_md_register)
MARK_VISIBLE (gcry_md_reset)
MARK_VISIBLE (gcry_md_setkey)
+MARK_VISIBLE (gcry_md_unregister)
MARK_VISIBLE (gcry_md_write)
MARK_VISIBLE (gcry_md_debug)
MARK_VISIBLE (gcry_cipher_get_algo_blklen)
MARK_VISIBLE (gcry_cipher_get_algo_keylen)
MARK_VISIBLE (gcry_cipher_info)
+MARK_VISIBLE (gcry_cipher_list)
MARK_VISIBLE (gcry_cipher_map_name)
MARK_VISIBLE (gcry_cipher_mode_from_oid)
MARK_VISIBLE (gcry_cipher_open)
+MARK_VISIBLEX(gcry_cipher_register)
+MARK_VISIBLE (gcry_cipher_unregister)
MARK_VISIBLE (gcry_pk_algo_info)
MARK_VISIBLE (gcry_pk_algo_name)
MARK_VISIBLE (gcry_pk_get_curve)
MARK_VISIBLE (gcry_pk_get_param)
MARK_VISIBLE (gcry_pk_get_nbits)
+MARK_VISIBLE (gcry_pk_list)
MARK_VISIBLE (gcry_pk_map_name)
+MARK_VISIBLEX(gcry_pk_register)
MARK_VISIBLE (gcry_pk_sign)
MARK_VISIBLE (gcry_pk_testkey)
+MARK_VISIBLE (gcry_pk_unregister)
MARK_VISIBLE (gcry_pk_verify)
+MARK_VISIBLE (gcry_ac_data_new)
+MARK_VISIBLE (gcry_ac_data_destroy)
+MARK_VISIBLE (gcry_ac_data_copy)
+MARK_VISIBLE (gcry_ac_data_length)
+MARK_VISIBLE (gcry_ac_data_clear)
+MARK_VISIBLE (gcry_ac_data_set)
+MARK_VISIBLE (gcry_ac_data_get_name)
+MARK_VISIBLE (gcry_ac_data_get_index)
+MARK_VISIBLE (gcry_ac_open)
+MARK_VISIBLE (gcry_ac_close)
+MARK_VISIBLE (gcry_ac_key_init)
+MARK_VISIBLE (gcry_ac_key_pair_generate)
+MARK_VISIBLE (gcry_ac_key_pair_extract)
+MARK_VISIBLE (gcry_ac_key_data_get)
+MARK_VISIBLE (gcry_ac_key_test)
+MARK_VISIBLE (gcry_ac_key_get_nbits)
+MARK_VISIBLE (gcry_ac_key_get_grip)
+MARK_VISIBLE (gcry_ac_key_destroy)
+MARK_VISIBLE (gcry_ac_key_pair_destroy)
+MARK_VISIBLE (gcry_ac_data_encrypt)
+MARK_VISIBLE (gcry_ac_data_decrypt)
+MARK_VISIBLE (gcry_ac_data_sign)
+MARK_VISIBLE (gcry_ac_data_verify)
+MARK_VISIBLE (gcry_ac_id_to_name)
+MARK_VISIBLE (gcry_ac_name_to_id)
+/* MARK_VISIBLE (gcry_ac_list) Not defined although it is in
+ libgcrypt.vers. */
+MARK_VISIBLE (gcry_ac_data_encode)
+MARK_VISIBLE (gcry_ac_data_decode)
+MARK_VISIBLE (gcry_ac_mpi_to_os)
+MARK_VISIBLE (gcry_ac_mpi_to_os_alloc)
+MARK_VISIBLE (gcry_ac_os_to_mpi)
+MARK_VISIBLE (gcry_ac_data_encrypt_scheme)
+MARK_VISIBLE (gcry_ac_data_decrypt_scheme)
+MARK_VISIBLE (gcry_ac_data_sign_scheme)
+MARK_VISIBLE (gcry_ac_data_verify_scheme)
+MARK_VISIBLE (gcry_ac_data_to_sexp)
+MARK_VISIBLE (gcry_ac_data_from_sexp)
+MARK_VISIBLE (gcry_ac_io_init)
+MARK_VISIBLE (gcry_ac_io_init_va)
+
MARK_VISIBLE (gcry_kdf_derive)
MARK_VISIBLE (gcry_prime_check)
#include <sys/types.h>
+#define _gcry_mpi_invm gcry_mpi_invm
+#define _gcry_mpi_set gcry_mpi_set
+#define _gcry_mpi_set_ui gcry_mpi_set_ui
#define size_t grub_size_t
#undef __GNU_LIBRARY__
}
static inline int
-fips_mode (void)
+_gcry_fips_mode (void)
{
return 0;
}
+#define assert gcry_assert
+
#ifdef GRUB_UTIL
#define memset grub_memset
GPG_ERR_WRONG_KEY_USAGE,
GPG_ERR_WRONG_PUBKEY_ALGO,
GPG_ERR_OUT_OF_MEMORY,
- GPG_ERR_TOO_LARGE
+ GPG_ERR_TOO_LARGE,
+ GPG_ERR_ENOMEM
} gpg_err_code_t;
typedef gpg_err_code_t gpg_error_t;
typedef gpg_error_t gcry_error_t;
extern struct gcry_pk_spec *grub_crypto_pk_dsa;
extern struct gcry_pk_spec *grub_crypto_pk_ecdsa;
+extern struct gcry_pk_spec *grub_crypto_pk_ecdh;
extern struct gcry_pk_spec *grub_crypto_pk_rsa;
void
for cipher_file in cipher_files:
infile = os.path.join (cipher_dir_in, cipher_file)
outfile = os.path.join (cipher_dir_out, cipher_file)
- if cipher_file == "ChangeLog":
+ if cipher_file == "ChangeLog" or cipher_file == "ChangeLog-2011":
continue
chlognew = " * %s" % cipher_file
- if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "test-getrusage.c":
+ if re.match ("(Manifest|Makefile\.am|ac\.c|cipher\.c|hash-common\.c|hmac-tests\.c|md\.c|pubkey\.c)$", cipher_file) or cipher_file == "kdf.c" or cipher_file == "elgamal.c" or cipher_file == "primegen.c" or cipher_file == "ecc.c" or cipher_file == "test-getrusage.c":
chlog = "%s%s: Removed\n" % (chlog, chlognew)
continue
# Autogenerated files. Not even worth mentionning in ChangeLog
mdnames = []
pknames = []
hold = False
- skip = False
+ skip = 0
skip2 = False
ismd = False
ispk = False
if not re.search (";", line) is None:
skip_statement = False
continue
- if skip:
+ if skip > 0:
if line[0] == "}":
- skip = False
+ skip = skip - 1
continue
if skip2:
if not re.search (" *};", line) is None:
# Used only for selftests.
m = re.match ("(static byte|static unsigned char) (weak_keys_chksum)\[[0-9]*\] =", line)
if not m is None:
- skip = True
+ skip = 1
fname = m.groups ()[1]
chmsg = "(%s): Removed." % fname
if nch:
# We're optimising for size and exclude anything needing good
# randomness.
if not re.match ("(run_selftests|selftest|_gcry_aes_c.._..c|_gcry_[a-z0-9]*_hash_buffer|tripledes_set2keys|do_tripledes_set_extra_info|_gcry_rmd160_mixblock|serpent_test|dsa_generate_ext|test_keys|gen_k|sign|gen_x931_parm_xp|generate_x931|generate_key|dsa_generate|dsa_sign|ecc_sign|generate|generate_fips186|_gcry_register_pk_dsa_progress|_gcry_register_pk_ecc_progress|progress|scanval|ec2os|ecc_generate_ext|ecc_generate|compute_keygrip|ecc_get_param|_gcry_register_pk_dsa_progress|gen_x931_parm_xp|gen_x931_parm_xi|rsa_decrypt|rsa_sign|rsa_generate_ext|rsa_generate|secret|check_exponent|rsa_blind|rsa_unblind|extract_a_from_sexp|curve_free|curve_copy|point_set)", line) is None:
- skip = True
+
+ skip = 1
+ if not re.match ("selftest", line) is None and cipher_file == "idea.c":
+ skip = 3
+
if not re.match ("serpent_test", line) is None:
fw.write ("static const char *serpent_test (void) { return 0; }\n");
if not re.match ("dsa_generate", line) is None:
holdline = line
continue
m = re.match ("static int tripledes_set2keys \(.*\);", line)
+ if not m is None:
+ continue
+ m = re.match ("static int tripledes_set3keys \(.*\);", line)
if not m is None:
continue
m = re.match ("static int tripledes_set2keys \(", line)
+ if not m is None:
+ skip_statement = True
+ continue
+ m = re.match ("static int tripledes_set3keys \(", line)
if not m is None:
skip_statement = True
continue
conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-redundant-decls -Wno-sign-compare';\n")
elif modname == "gcry_rijndael" or modname == "gcry_md4" or modname == "gcry_md5" or modname == "gcry_rmd160" or modname == "gcry_sha1" or modname == "gcry_sha256" or modname == "gcry_sha512" or modname == "gcry_tiger":
# Alignment checked by hand
- conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align -Wno-strict-aliasing';\n");
+ conf.write (" cflags = '$(CFLAGS_GCRY) -Wno-cast-align';\n");
else:
conf.write (" cflags = '$(CFLAGS_GCRY)';\n");
conf.write (" cppflags = '$(CPPFLAGS_GCRY)';\n");
fw.write ("/* This file was automatically imported with \n")
fw.write (" import_gcry.py. Please don't modify it */\n")
hold = False
- skip = False
+ skip = 0
for line in f:
- if skip:
+ if skip > 0:
if line[0] == "}":
- skip = False
+ skip = skip - 1
continue
if hold:
hold = False
# We're optimising for size and exclude anything needing good
# randomness.
if not re.match ("(_gcry_mpi_get_hw_config|gcry_mpi_randomize)", line) is None:
- skip = True
+ skip = 1
continue
else:
fw.write (holdline)
/^# *include <time\.h>/ d
/^# *include <sys\/socket\.h>/ d
/^# *include <sys\/time\.h>/ d
+/^ typedef long ssize_t;/ d
+/^ typedef int pid_t;/ d
/^# *include <gpg-error\.h>/ s,#include <gpg-error.h>,#include <grub/gcrypt/gpg-error.h>,
/^typedef gpg_error_t gcry_error_t;/ d
/^typedef gpg_err_code_t gcry_err_code_t;/ d
/^typedef struct gcry_mpi \*gcry_mpi_t;/ d
+/^struct gcry_thread_cbs/ d
s,_gcry_mpi_invm,gcry_mpi_invm,g
p
\ No newline at end of file