diff options
author | Karel Miko <karel.miko@gmail.com> | 2018-10-04 20:13:36 +0200 |
---|---|---|
committer | Karel Miko <karel.miko@gmail.com> | 2018-10-04 20:13:36 +0200 |
commit | c14794b6f61e93a6716b75c4547b554033612e07 (patch) | |
tree | 6ae18006485245a855abcef838752b0ed6324e1f /src | |
parent | 3bf90f7e79623e5f5f610fa683032811115b1553 (diff) |
libtomcrypt update
Diffstat (limited to 'src')
35 files changed, 1832 insertions, 879 deletions
diff --git a/src/Makefile b/src/Makefile index 45e5373e..54c673ec 100644 --- a/src/Makefile +++ b/src/Makefile @@ -41,71 +41,74 @@ ltc/mac/xcbc/xcbc_file.o ltc/mac/xcbc/xcbc_init.o ltc/mac/xcbc/xcbc_memory.o ltc ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_to_bin.o \ ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \ ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/copy_or_zeromem.o \ -ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o \ -ltc/misc/pk_oid_str.o ltc/misc/zeromem.o ltc/misc/base16/base16_decode.o ltc/misc/base16/base16_encode.o \ -ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o \ -ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \ -ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o \ -ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \ -ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \ -ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \ -ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \ -ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \ -ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \ -ltc/misc/crypt/crypt_register_all_hashes.o ltc/misc/crypt/crypt_register_all_prngs.o \ -ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \ -ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \ -ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/padding/padding_depad.o \ -ltc/misc/padding/padding_pad.o ltc/misc/pkcs12/pkcs12_kdf.o ltc/misc/pkcs12/pkcs12_utf8_to_utf16.o \ -ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o \ -ltc/modes/cbc/cbc_encrypt.o ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o \ -ltc/modes/cfb/cfb_decrypt.o ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o \ -ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o \ -ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o \ -ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o \ -ltc/modes/ecb/ecb_start.o ltc/modes/ofb/ofb_decrypt.o ltc/modes/ofb/ofb_done.o ltc/modes/ofb/ofb_encrypt.o \ -ltc/modes/ofb/ofb_getiv.o ltc/modes/ofb/ofb_setiv.o ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o \ -ltc/pk/asn1/der/bit/der_decode_raw_bit_string.o ltc/pk/asn1/der/bit/der_encode_bit_string.o \ -ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o ltc/pk/asn1/der/bit/der_length_bit_string.o \ -ltc/pk/asn1/der/boolean/der_decode_boolean.o ltc/pk/asn1/der/boolean/der_encode_boolean.o \ -ltc/pk/asn1/der/boolean/der_length_boolean.o ltc/pk/asn1/der/choice/der_decode_choice.o \ -ltc/pk/asn1/der/custom_type/der_decode_custom_type.o ltc/pk/asn1/der/custom_type/der_encode_custom_type.o \ -ltc/pk/asn1/der/custom_type/der_length_custom_type.o ltc/pk/asn1/der/general/der_asn1_maps.o \ -ltc/pk/asn1/der/general/der_decode_asn1_identifier.o ltc/pk/asn1/der/general/der_decode_asn1_length.o \ -ltc/pk/asn1/der/general/der_encode_asn1_identifier.o ltc/pk/asn1/der/general/der_encode_asn1_length.o \ -ltc/pk/asn1/der/general/der_length_asn1_identifier.o ltc/pk/asn1/der/general/der_length_asn1_length.o \ -ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ -ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o ltc/pk/asn1/der/ia5/der_decode_ia5_string.o \ -ltc/pk/asn1/der/ia5/der_encode_ia5_string.o ltc/pk/asn1/der/ia5/der_length_ia5_string.o \ -ltc/pk/asn1/der/integer/der_decode_integer.o ltc/pk/asn1/der/integer/der_encode_integer.o \ -ltc/pk/asn1/der/integer/der_length_integer.o ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ -ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.o ltc/pk/asn1/der/object_identifier/der_length_object_identifier.o \ -ltc/pk/asn1/der/octet/der_decode_octet_string.o ltc/pk/asn1/der/octet/der_encode_octet_string.o \ -ltc/pk/asn1/der/octet/der_length_octet_string.o ltc/pk/asn1/der/printable_string/der_decode_printable_string.o \ -ltc/pk/asn1/der/printable_string/der_encode_printable_string.o ltc/pk/asn1/der/printable_string/der_length_printable_string.o \ -ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ -ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o \ -ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o ltc/pk/asn1/der/sequence/der_length_sequence.o \ -ltc/pk/asn1/der/sequence/der_sequence_free.o ltc/pk/asn1/der/sequence/der_sequence_shrink.o \ -ltc/pk/asn1/der/set/der_encode_set.o ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ +ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/zeromem.o \ +ltc/misc/base16/base16_decode.o ltc/misc/base16/base16_encode.o ltc/misc/base32/base32_decode.o \ +ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o \ +ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o \ +ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o ltc/misc/crypt/crypt_find_cipher.o \ +ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o \ +ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o \ +ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o \ +ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o \ +ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_prng_rng_descriptor.o \ +ltc/misc/crypt/crypt_register_all_ciphers.o ltc/misc/crypt/crypt_register_all_hashes.o \ +ltc/misc/crypt/crypt_register_all_prngs.o ltc/misc/crypt/crypt_register_cipher.o \ +ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o ltc/misc/crypt/crypt_sizes.o \ +ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o ltc/misc/crypt/crypt_unregister_prng.o \ +ltc/misc/hkdf/hkdf.o ltc/misc/padding/padding_depad.o ltc/misc/padding/padding_pad.o \ +ltc/misc/pbes/pbes.o ltc/misc/pbes/pbes1.o ltc/misc/pbes/pbes2.o ltc/misc/pkcs12/pkcs12_kdf.o \ +ltc/misc/pkcs12/pkcs12_utf8_to_utf16.o ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o \ +ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ +ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o ltc/modes/cfb/cfb_decrypt.o \ +ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o \ +ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o \ +ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o \ +ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o ltc/modes/ecb/ecb_start.o ltc/modes/ofb/ofb_decrypt.o \ +ltc/modes/ofb/ofb_done.o ltc/modes/ofb/ofb_encrypt.o ltc/modes/ofb/ofb_getiv.o ltc/modes/ofb/ofb_setiv.o \ +ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o ltc/pk/asn1/der/bit/der_decode_raw_bit_string.o \ +ltc/pk/asn1/der/bit/der_encode_bit_string.o ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o \ +ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \ +ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \ +ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/custom_type/der_decode_custom_type.o \ +ltc/pk/asn1/der/custom_type/der_encode_custom_type.o ltc/pk/asn1/der/custom_type/der_length_custom_type.o \ +ltc/pk/asn1/der/general/der_asn1_maps.o ltc/pk/asn1/der/general/der_decode_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_decode_asn1_length.o ltc/pk/asn1/der/general/der_encode_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_encode_asn1_length.o ltc/pk/asn1/der/general/der_length_asn1_identifier.o \ +ltc/pk/asn1/der/general/der_length_asn1_length.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ +ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ +ltc/pk/asn1/der/ia5/der_decode_ia5_string.o ltc/pk/asn1/der/ia5/der_encode_ia5_string.o \ +ltc/pk/asn1/der/ia5/der_length_ia5_string.o ltc/pk/asn1/der/integer/der_decode_integer.o \ +ltc/pk/asn1/der/integer/der_encode_integer.o ltc/pk/asn1/der/integer/der_length_integer.o \ +ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ +ltc/pk/asn1/der/object_identifier/der_length_object_identifier.o ltc/pk/asn1/der/octet/der_decode_octet_string.o \ +ltc/pk/asn1/der/octet/der_encode_octet_string.o ltc/pk/asn1/der/octet/der_length_octet_string.o \ +ltc/pk/asn1/der/printable_string/der_decode_printable_string.o ltc/pk/asn1/der/printable_string/der_encode_printable_string.o \ +ltc/pk/asn1/der/printable_string/der_length_printable_string.o ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o \ +ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o \ +ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o \ +ltc/pk/asn1/der/sequence/der_length_sequence.o ltc/pk/asn1/der/sequence/der_sequence_free.o \ +ltc/pk/asn1/der/sequence/der_sequence_shrink.o ltc/pk/asn1/der/set/der_encode_set.o \ +ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ ltc/pk/asn1/der/short_integer/der_encode_short_integer.o ltc/pk/asn1/der/short_integer/der_length_short_integer.o \ ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.o ltc/pk/asn1/der/teletex_string/der_length_teletex_string.o \ ltc/pk/asn1/der/utctime/der_decode_utctime.o ltc/pk/asn1/der/utctime/der_encode_utctime.o \ ltc/pk/asn1/der/utctime/der_length_utctime.o ltc/pk/asn1/der/utf8/der_decode_utf8_string.o \ ltc/pk/asn1/der/utf8/der_encode_utf8_string.o ltc/pk/asn1/der/utf8/der_length_utf8_string.o \ -ltc/pk/asn1/x509/x509_decode_subject_public_key_info.o ltc/pk/asn1/x509/x509_encode_subject_public_key_info.o \ -ltc/pk/dh/dh.o ltc/pk/dh/dh_check_pubkey.o ltc/pk/dh/dh_export.o ltc/pk/dh/dh_export_key.o \ -ltc/pk/dh/dh_free.o ltc/pk/dh/dh_generate_key.o ltc/pk/dh/dh_import.o ltc/pk/dh/dh_set.o \ -ltc/pk/dh/dh_set_pg_dhparam.o ltc/pk/dh/dh_shared_secret.o ltc/pk/dsa/dsa_decrypt_key.o \ -ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o ltc/pk/dsa/dsa_free.o ltc/pk/dsa/dsa_generate_key.o \ -ltc/pk/dsa/dsa_generate_pqg.o ltc/pk/dsa/dsa_import.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_set.o \ -ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \ -ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \ -ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o \ -ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_find_curve.o \ -ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_key.o ltc/pk/ecc/ecc_get_oid_str.o ltc/pk/ecc/ecc_get_size.o \ -ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o ltc/pk/ecc/ecc_import_pkcs8.o \ -ltc/pk/ecc/ecc_import_x509.o ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_set_curve.o \ +ltc/pk/asn1/oid/pk_get_oid.o ltc/pk/asn1/oid/pk_oid_cmp.o ltc/pk/asn1/oid/pk_oid_str.o \ +ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.o ltc/pk/asn1/x509/x509_decode_subject_public_key_info.o \ +ltc/pk/asn1/x509/x509_encode_subject_public_key_info.o ltc/pk/dh/dh.o ltc/pk/dh/dh_check_pubkey.o \ +ltc/pk/dh/dh_export.o ltc/pk/dh/dh_export_key.o ltc/pk/dh/dh_free.o ltc/pk/dh/dh_generate_key.o \ +ltc/pk/dh/dh_import.o ltc/pk/dh/dh_set.o ltc/pk/dh/dh_set_pg_dhparam.o ltc/pk/dh/dh_shared_secret.o \ +ltc/pk/dsa/dsa_decrypt_key.o ltc/pk/dsa/dsa_encrypt_key.o ltc/pk/dsa/dsa_export.o \ +ltc/pk/dsa/dsa_free.o ltc/pk/dsa/dsa_generate_key.o ltc/pk/dsa/dsa_generate_pqg.o \ +ltc/pk/dsa/dsa_import.o ltc/pk/dsa/dsa_make_key.o ltc/pk/dsa/dsa_set.o ltc/pk/dsa/dsa_set_pqg_dsaparam.o \ +ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o ltc/pk/dsa/dsa_verify_hash.o \ +ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o ltc/pk/ecc/ecc_ansi_x963_import.o \ +ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o ltc/pk/ecc/ecc_export.o \ +ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_find_curve.o ltc/pk/ecc/ecc_free.o \ +ltc/pk/ecc/ecc_get_key.o ltc/pk/ecc/ecc_get_oid_str.o ltc/pk/ecc/ecc_get_size.o ltc/pk/ecc/ecc_import.o \ +ltc/pk/ecc/ecc_import_openssl.o ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_x509.o \ +ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_recover_key.o ltc/pk/ecc/ecc_set_curve.o \ ltc/pk/ecc/ecc_set_curve_internal.o ltc/pk/ecc/ecc_set_key.o ltc/pk/ecc/ecc_shared_secret.o \ ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ltc_ecc_export_point.o \ ltc/pk/ecc/ltc_ecc_import_point.o ltc/pk/ecc/ltc_ecc_is_point.o ltc/pk/ecc/ltc_ecc_is_point_at_infinity.o \ @@ -122,37 +125,39 @@ ltc/pk/rsa/rsa_verify_hash.o ltc/prngs/chacha20.o ltc/prngs/fortuna.o ltc/prngs/ ltc/prngs/rng_get_bytes.o ltc/prngs/rng_make_prng.o ltc/prngs/sober128.o ltc/prngs/sprng.o \ ltc/prngs/yarrow.o ltc/stream/chacha/chacha_crypt.o ltc/stream/chacha/chacha_done.o \ ltc/stream/chacha/chacha_ivctr32.o ltc/stream/chacha/chacha_ivctr64.o ltc/stream/chacha/chacha_keystream.o \ -ltc/stream/chacha/chacha_setup.o ltc/stream/rabbit/rabbit.o ltc/stream/rc4/rc4_stream.o \ +ltc/stream/chacha/chacha_memory.o ltc/stream/chacha/chacha_setup.o ltc/stream/rabbit/rabbit.o \ +ltc/stream/rabbit/rabbit_memory.o ltc/stream/rc4/rc4_stream.o ltc/stream/rc4/rc4_stream_memory.o \ ltc/stream/salsa20/salsa20_crypt.o ltc/stream/salsa20/salsa20_done.o ltc/stream/salsa20/salsa20_ivctr64.o \ -ltc/stream/salsa20/salsa20_keystream.o ltc/stream/salsa20/salsa20_setup.o ltc/stream/salsa20/xsalsa20_setup.o \ -ltc/stream/sober128/sober128_stream.o ltc/stream/sosemanuk/sosemanuk.o ltm/bncore.o \ -ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o ltm/bn_fast_s_mp_mul_digs.o \ -ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o ltm/bn_mp_2expt.o ltm/bn_mp_abs.o \ -ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o ltm/bn_mp_and.o ltm/bn_mp_clamp.o \ -ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o \ -ltm/bn_mp_cnt_lsb.o ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o ltm/bn_mp_div.o ltm/bn_mp_div_2.o \ -ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o ltm/bn_mp_dr_is_modulus.o \ -ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_exch.o ltm/bn_mp_export.o ltm/bn_mp_exptmod.o \ -ltm/bn_mp_exptmod_fast.o ltm/bn_mp_expt_d.o ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o \ -ltm/bn_mp_fread.o ltm/bn_mp_fwrite.o ltm/bn_mp_gcd.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o \ -ltm/bn_mp_grow.o ltm/bn_mp_import.o ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_multi.o \ -ltm/bn_mp_init_set.o ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o \ -ltm/bn_mp_invmod_slow.o ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o \ -ltm/bn_mp_karatsuba_sqr.o ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o \ -ltm/bn_mp_mod_d.o ltm/bn_mp_montgomery_calc_normalization.o ltm/bn_mp_montgomery_reduce.o \ -ltm/bn_mp_montgomery_setup.o ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o ltm/bn_mp_mul_2.o \ -ltm/bn_mp_mul_2d.o ltm/bn_mp_mul_d.o ltm/bn_mp_neg.o ltm/bn_mp_n_root.o ltm/bn_mp_n_root_ex.o \ -ltm/bn_mp_or.o ltm/bn_mp_prime_fermat.o ltm/bn_mp_prime_is_divisible.o ltm/bn_mp_prime_is_prime.o \ -ltm/bn_mp_prime_miller_rabin.o ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o \ -ltm/bn_mp_prime_random_ex.o ltm/bn_mp_radix_size.o ltm/bn_mp_radix_smap.o ltm/bn_mp_rand.o \ -ltm/bn_mp_read_radix.o ltm/bn_mp_read_signed_bin.o ltm/bn_mp_read_unsigned_bin.o \ -ltm/bn_mp_reduce.o ltm/bn_mp_reduce_2k.o ltm/bn_mp_reduce_2k_l.o ltm/bn_mp_reduce_2k_setup.o \ -ltm/bn_mp_reduce_2k_setup_l.o ltm/bn_mp_reduce_is_2k.o ltm/bn_mp_reduce_is_2k_l.o \ -ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o ltm/bn_mp_set.o ltm/bn_mp_set_int.o ltm/bn_mp_set_long.o \ -ltm/bn_mp_shrink.o ltm/bn_mp_signed_bin_size.o ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o \ -ltm/bn_mp_sqrt.o ltm/bn_mp_sqrtmod_prime.o ltm/bn_mp_sub.o ltm/bn_mp_submod.o ltm/bn_mp_sub_d.o \ -ltm/bn_mp_toom_mul.o ltm/bn_mp_toom_sqr.o ltm/bn_mp_toradix.o ltm/bn_mp_toradix_n.o \ -ltm/bn_mp_to_signed_bin.o ltm/bn_mp_to_signed_bin_n.o ltm/bn_mp_to_unsigned_bin.o \ +ltc/stream/salsa20/salsa20_keystream.o ltc/stream/salsa20/salsa20_memory.o ltc/stream/salsa20/salsa20_setup.o \ +ltc/stream/salsa20/xsalsa20_memory.o ltc/stream/salsa20/xsalsa20_setup.o ltc/stream/sober128/sober128_stream.o \ +ltc/stream/sober128/sober128_stream_memory.o ltc/stream/sosemanuk/sosemanuk.o ltc/stream/sosemanuk/sosemanuk_memory.o \ +ltm/bncore.o ltm/bn_error.o ltm/bn_fast_mp_invmod.o ltm/bn_fast_mp_montgomery_reduce.o \ +ltm/bn_fast_s_mp_mul_digs.o ltm/bn_fast_s_mp_mul_high_digs.o ltm/bn_fast_s_mp_sqr.o \ +ltm/bn_mp_2expt.o ltm/bn_mp_abs.o ltm/bn_mp_add.o ltm/bn_mp_addmod.o ltm/bn_mp_add_d.o \ +ltm/bn_mp_and.o ltm/bn_mp_clamp.o ltm/bn_mp_clear.o ltm/bn_mp_clear_multi.o ltm/bn_mp_cmp.o \ +ltm/bn_mp_cmp_d.o ltm/bn_mp_cmp_mag.o ltm/bn_mp_cnt_lsb.o ltm/bn_mp_copy.o ltm/bn_mp_count_bits.o \ +ltm/bn_mp_div.o ltm/bn_mp_div_2.o ltm/bn_mp_div_2d.o ltm/bn_mp_div_3.o ltm/bn_mp_div_d.o \ +ltm/bn_mp_dr_is_modulus.o ltm/bn_mp_dr_reduce.o ltm/bn_mp_dr_setup.o ltm/bn_mp_exch.o \ +ltm/bn_mp_export.o ltm/bn_mp_exptmod.o ltm/bn_mp_exptmod_fast.o ltm/bn_mp_expt_d.o \ +ltm/bn_mp_expt_d_ex.o ltm/bn_mp_exteuclid.o ltm/bn_mp_fread.o ltm/bn_mp_fwrite.o \ +ltm/bn_mp_gcd.o ltm/bn_mp_get_int.o ltm/bn_mp_get_long.o ltm/bn_mp_grow.o ltm/bn_mp_import.o \ +ltm/bn_mp_init.o ltm/bn_mp_init_copy.o ltm/bn_mp_init_multi.o ltm/bn_mp_init_set.o \ +ltm/bn_mp_init_set_int.o ltm/bn_mp_init_size.o ltm/bn_mp_invmod.o ltm/bn_mp_invmod_slow.o \ +ltm/bn_mp_is_square.o ltm/bn_mp_jacobi.o ltm/bn_mp_karatsuba_mul.o ltm/bn_mp_karatsuba_sqr.o \ +ltm/bn_mp_lcm.o ltm/bn_mp_lshd.o ltm/bn_mp_mod.o ltm/bn_mp_mod_2d.o ltm/bn_mp_mod_d.o \ +ltm/bn_mp_montgomery_calc_normalization.o ltm/bn_mp_montgomery_reduce.o ltm/bn_mp_montgomery_setup.o \ +ltm/bn_mp_mul.o ltm/bn_mp_mulmod.o ltm/bn_mp_mul_2.o ltm/bn_mp_mul_2d.o ltm/bn_mp_mul_d.o \ +ltm/bn_mp_neg.o ltm/bn_mp_n_root.o ltm/bn_mp_n_root_ex.o ltm/bn_mp_or.o ltm/bn_mp_prime_fermat.o \ +ltm/bn_mp_prime_is_divisible.o ltm/bn_mp_prime_is_prime.o ltm/bn_mp_prime_miller_rabin.o \ +ltm/bn_mp_prime_next_prime.o ltm/bn_mp_prime_rabin_miller_trials.o ltm/bn_mp_prime_random_ex.o \ +ltm/bn_mp_radix_size.o ltm/bn_mp_radix_smap.o ltm/bn_mp_rand.o ltm/bn_mp_read_radix.o \ +ltm/bn_mp_read_signed_bin.o ltm/bn_mp_read_unsigned_bin.o ltm/bn_mp_reduce.o ltm/bn_mp_reduce_2k.o \ +ltm/bn_mp_reduce_2k_l.o ltm/bn_mp_reduce_2k_setup.o ltm/bn_mp_reduce_2k_setup_l.o \ +ltm/bn_mp_reduce_is_2k.o ltm/bn_mp_reduce_is_2k_l.o ltm/bn_mp_reduce_setup.o ltm/bn_mp_rshd.o \ +ltm/bn_mp_set.o ltm/bn_mp_set_int.o ltm/bn_mp_set_long.o ltm/bn_mp_shrink.o ltm/bn_mp_signed_bin_size.o \ +ltm/bn_mp_sqr.o ltm/bn_mp_sqrmod.o ltm/bn_mp_sqrt.o ltm/bn_mp_sqrtmod_prime.o ltm/bn_mp_sub.o \ +ltm/bn_mp_submod.o ltm/bn_mp_sub_d.o ltm/bn_mp_toom_mul.o ltm/bn_mp_toom_sqr.o ltm/bn_mp_toradix.o \ +ltm/bn_mp_toradix_n.o ltm/bn_mp_to_signed_bin.o ltm/bn_mp_to_signed_bin_n.o ltm/bn_mp_to_unsigned_bin.o \ ltm/bn_mp_to_unsigned_bin_n.o ltm/bn_mp_unsigned_bin_size.o ltm/bn_mp_xor.o ltm/bn_mp_zero.o \ ltm/bn_prime_tab.o ltm/bn_reverse.o ltm/bn_s_mp_add.o ltm/bn_s_mp_exptmod.o ltm/bn_s_mp_mul_digs.o \ ltm/bn_s_mp_mul_high_digs.o ltm/bn_s_mp_sqr.o ltm/bn_s_mp_sub.o diff --git a/src/Makefile.nmake b/src/Makefile.nmake index 05f9f991..47133f7d 100644 --- a/src/Makefile.nmake +++ b/src/Makefile.nmake @@ -44,69 +44,70 @@ ltc/mac/xcbc/xcbc_init.obj ltc/mac/xcbc/xcbc_memory.obj ltc/mac/xcbc/xcbc_memory ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/radix_to_bin.obj \ ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \ ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/copy_or_zeromem.obj \ -ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj \ -ltc/misc/pk_oid_str.obj ltc/misc/zeromem.obj ltc/misc/base16/base16_decode.obj ltc/misc/base16/base16_encode.obj \ -ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj \ -ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \ -ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ -ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \ -ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \ -ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \ -ltc/misc/crypt/crypt_fsa.obj ltc/misc/crypt/crypt_hash_descriptor.obj ltc/misc/crypt/crypt_hash_is_valid.obj \ -ltc/misc/crypt/crypt_inits.obj ltc/misc/crypt/crypt_ltc_mp_descriptor.obj ltc/misc/crypt/crypt_prng_descriptor.obj \ +ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/zeromem.obj \ +ltc/misc/base16/base16_decode.obj ltc/misc/base16/base16_encode.obj ltc/misc/base32/base32_decode.obj \ +ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj \ +ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj \ +ltc/misc/crypt/crypt_cipher_is_valid.obj ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj \ +ltc/misc/crypt/crypt_find_cipher_any.obj ltc/misc/crypt/crypt_find_cipher_id.obj \ +ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj ltc/misc/crypt/crypt_find_hash_id.obj \ +ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj ltc/misc/crypt/crypt_fsa.obj \ +ltc/misc/crypt/crypt_hash_descriptor.obj ltc/misc/crypt/crypt_hash_is_valid.obj ltc/misc/crypt/crypt_inits.obj \ +ltc/misc/crypt/crypt_ltc_mp_descriptor.obj ltc/misc/crypt/crypt_prng_descriptor.obj \ ltc/misc/crypt/crypt_prng_is_valid.obj ltc/misc/crypt/crypt_prng_rng_descriptor.obj \ ltc/misc/crypt/crypt_register_all_ciphers.obj ltc/misc/crypt/crypt_register_all_hashes.obj \ ltc/misc/crypt/crypt_register_all_prngs.obj ltc/misc/crypt/crypt_register_cipher.obj \ ltc/misc/crypt/crypt_register_hash.obj ltc/misc/crypt/crypt_register_prng.obj ltc/misc/crypt/crypt_sizes.obj \ ltc/misc/crypt/crypt_unregister_cipher.obj ltc/misc/crypt/crypt_unregister_hash.obj \ ltc/misc/crypt/crypt_unregister_prng.obj ltc/misc/hkdf/hkdf.obj ltc/misc/padding/padding_depad.obj \ -ltc/misc/padding/padding_pad.obj ltc/misc/pkcs12/pkcs12_kdf.obj ltc/misc/pkcs12/pkcs12_utf8_to_utf16.obj \ -ltc/misc/pkcs5/pkcs_5_1.obj ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj \ -ltc/modes/cbc/cbc_done.obj ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj \ -ltc/modes/cbc/cbc_setiv.obj ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj \ -ltc/modes/cfb/cfb_done.obj ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj \ -ltc/modes/cfb/cfb_setiv.obj ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj \ -ltc/modes/ctr/ctr_done.obj ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj \ -ltc/modes/ctr/ctr_setiv.obj ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj \ -ltc/modes/ecb/ecb_done.obj ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj \ -ltc/modes/ofb/ofb_decrypt.obj ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj \ -ltc/modes/ofb/ofb_getiv.obj ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj \ -ltc/pk/asn1/der/bit/der_decode_bit_string.obj ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj \ -ltc/pk/asn1/der/bit/der_encode_bit_string.obj ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj \ -ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ -ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ -ltc/pk/asn1/der/choice/der_decode_choice.obj ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj \ -ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj ltc/pk/asn1/der/custom_type/der_length_custom_type.obj \ -ltc/pk/asn1/der/general/der_asn1_maps.obj ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj \ -ltc/pk/asn1/der/general/der_decode_asn1_length.obj ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj \ -ltc/pk/asn1/der/general/der_encode_asn1_length.obj ltc/pk/asn1/der/general/der_length_asn1_identifier.obj \ -ltc/pk/asn1/der/general/der_length_asn1_length.obj ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj \ -ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ -ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj \ -ltc/pk/asn1/der/ia5/der_length_ia5_string.obj ltc/pk/asn1/der/integer/der_decode_integer.obj \ -ltc/pk/asn1/der/integer/der_encode_integer.obj ltc/pk/asn1/der/integer/der_length_integer.obj \ -ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ -ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj ltc/pk/asn1/der/octet/der_decode_octet_string.obj \ -ltc/pk/asn1/der/octet/der_encode_octet_string.obj ltc/pk/asn1/der/octet/der_length_octet_string.obj \ -ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj \ -ltc/pk/asn1/der/printable_string/der_length_printable_string.obj ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ -ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ -ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj \ -ltc/pk/asn1/der/sequence/der_length_sequence.obj ltc/pk/asn1/der/sequence/der_sequence_free.obj \ -ltc/pk/asn1/der/sequence/der_sequence_shrink.obj ltc/pk/asn1/der/set/der_encode_set.obj \ -ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ +ltc/misc/padding/padding_pad.obj ltc/misc/pbes/pbes.obj ltc/misc/pbes/pbes1.obj ltc/misc/pbes/pbes2.obj \ +ltc/misc/pkcs12/pkcs12_kdf.obj ltc/misc/pkcs12/pkcs12_utf8_to_utf16.obj ltc/misc/pkcs5/pkcs_5_1.obj \ +ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj ltc/modes/cbc/cbc_done.obj \ +ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj ltc/modes/cbc/cbc_setiv.obj \ +ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj ltc/modes/cfb/cfb_done.obj \ +ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj ltc/modes/cfb/cfb_setiv.obj \ +ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj ltc/modes/ctr/ctr_done.obj \ +ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj ltc/modes/ctr/ctr_setiv.obj \ +ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj ltc/modes/ecb/ecb_done.obj \ +ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj ltc/modes/ofb/ofb_decrypt.obj \ +ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj ltc/modes/ofb/ofb_getiv.obj \ +ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj ltc/pk/asn1/der/bit/der_decode_bit_string.obj \ +ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_encode_bit_string.obj \ +ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_length_bit_string.obj \ +ltc/pk/asn1/der/boolean/der_decode_boolean.obj ltc/pk/asn1/der/boolean/der_encode_boolean.obj \ +ltc/pk/asn1/der/boolean/der_length_boolean.obj ltc/pk/asn1/der/choice/der_decode_choice.obj \ +ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj \ +ltc/pk/asn1/der/custom_type/der_length_custom_type.obj ltc/pk/asn1/der/general/der_asn1_maps.obj \ +ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj ltc/pk/asn1/der/general/der_decode_asn1_length.obj \ +ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj ltc/pk/asn1/der/general/der_encode_asn1_length.obj \ +ltc/pk/asn1/der/general/der_length_asn1_identifier.obj ltc/pk/asn1/der/general/der_length_asn1_length.obj \ +ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ +ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \ +ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \ +ltc/pk/asn1/der/integer/der_decode_integer.obj ltc/pk/asn1/der/integer/der_encode_integer.obj \ +ltc/pk/asn1/der/integer/der_length_integer.obj ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ +ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ +ltc/pk/asn1/der/octet/der_decode_octet_string.obj ltc/pk/asn1/der/octet/der_encode_octet_string.obj \ +ltc/pk/asn1/der/octet/der_length_octet_string.obj ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj \ +ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj ltc/pk/asn1/der/printable_string/der_length_printable_string.obj \ +ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ +ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ +ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \ +ltc/pk/asn1/der/sequence/der_sequence_free.obj ltc/pk/asn1/der/sequence/der_sequence_shrink.obj \ +ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \ ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.obj ltc/pk/asn1/der/teletex_string/der_length_teletex_string.obj \ ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \ ltc/pk/asn1/der/utctime/der_length_utctime.obj ltc/pk/asn1/der/utf8/der_decode_utf8_string.obj \ ltc/pk/asn1/der/utf8/der_encode_utf8_string.obj ltc/pk/asn1/der/utf8/der_length_utf8_string.obj \ -ltc/pk/asn1/x509/x509_decode_subject_public_key_info.obj ltc/pk/asn1/x509/x509_encode_subject_public_key_info.obj \ -ltc/pk/dh/dh.obj ltc/pk/dh/dh_check_pubkey.obj ltc/pk/dh/dh_export.obj ltc/pk/dh/dh_export_key.obj \ -ltc/pk/dh/dh_free.obj ltc/pk/dh/dh_generate_key.obj ltc/pk/dh/dh_import.obj ltc/pk/dh/dh_set.obj \ -ltc/pk/dh/dh_set_pg_dhparam.obj ltc/pk/dh/dh_shared_secret.obj ltc/pk/dsa/dsa_decrypt_key.obj \ -ltc/pk/dsa/dsa_encrypt_key.obj ltc/pk/dsa/dsa_export.obj ltc/pk/dsa/dsa_free.obj \ -ltc/pk/dsa/dsa_generate_key.obj ltc/pk/dsa/dsa_generate_pqg.obj ltc/pk/dsa/dsa_import.obj \ -ltc/pk/dsa/dsa_make_key.obj ltc/pk/dsa/dsa_set.obj ltc/pk/dsa/dsa_set_pqg_dsaparam.obj \ +ltc/pk/asn1/oid/pk_get_oid.obj ltc/pk/asn1/oid/pk_oid_cmp.obj ltc/pk/asn1/oid/pk_oid_str.obj \ +ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.obj ltc/pk/asn1/x509/x509_decode_subject_public_key_info.obj \ +ltc/pk/asn1/x509/x509_encode_subject_public_key_info.obj ltc/pk/dh/dh.obj ltc/pk/dh/dh_check_pubkey.obj \ +ltc/pk/dh/dh_export.obj ltc/pk/dh/dh_export_key.obj ltc/pk/dh/dh_free.obj ltc/pk/dh/dh_generate_key.obj \ +ltc/pk/dh/dh_import.obj ltc/pk/dh/dh_set.obj ltc/pk/dh/dh_set_pg_dhparam.obj ltc/pk/dh/dh_shared_secret.obj \ +ltc/pk/dsa/dsa_decrypt_key.obj ltc/pk/dsa/dsa_encrypt_key.obj ltc/pk/dsa/dsa_export.obj \ +ltc/pk/dsa/dsa_free.obj ltc/pk/dsa/dsa_generate_key.obj ltc/pk/dsa/dsa_generate_pqg.obj \ +ltc/pk/dsa/dsa_import.obj ltc/pk/dsa/dsa_make_key.obj ltc/pk/dsa/dsa_set.obj ltc/pk/dsa/dsa_set_pqg_dsaparam.obj \ ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \ ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \ ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_encrypt_key.obj \ @@ -114,27 +115,30 @@ ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_find_ ltc/pk/ecc/ecc_free.obj ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_oid_str.obj \ ltc/pk/ecc/ecc_get_size.obj ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_openssl.obj \ ltc/pk/ecc/ecc_import_pkcs8.obj ltc/pk/ecc/ecc_import_x509.obj ltc/pk/ecc/ecc_make_key.obj \ -ltc/pk/ecc/ecc_set_curve.obj ltc/pk/ecc/ecc_set_curve_internal.obj ltc/pk/ecc/ecc_set_key.obj \ -ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj \ -ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ltc_ecc_export_point.obj ltc/pk/ecc/ltc_ecc_import_point.obj \ -ltc/pk/ecc/ltc_ecc_is_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj ltc/pk/ecc/ltc_ecc_map.obj \ -ltc/pk/ecc/ltc_ecc_mul2add.obj ltc/pk/ecc/ltc_ecc_mulmod.obj ltc/pk/ecc/ltc_ecc_mulmod_timing.obj \ -ltc/pk/ecc/ltc_ecc_points.obj ltc/pk/ecc/ltc_ecc_projective_add_point.obj ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj \ -ltc/pk/ecc/ltc_ecc_verify_key.obj ltc/pk/pkcs1/pkcs_1_i2osp.obj ltc/pk/pkcs1/pkcs_1_mgf1.obj \ -ltc/pk/pkcs1/pkcs_1_oaep_decode.obj ltc/pk/pkcs1/pkcs_1_oaep_encode.obj ltc/pk/pkcs1/pkcs_1_os2ip.obj \ -ltc/pk/pkcs1/pkcs_1_pss_decode.obj ltc/pk/pkcs1/pkcs_1_pss_encode.obj ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj \ -ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj ltc/pk/rsa/rsa_decrypt_key.obj ltc/pk/rsa/rsa_encrypt_key.obj \ -ltc/pk/rsa/rsa_export.obj ltc/pk/rsa/rsa_exptmod.obj ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj \ -ltc/pk/rsa/rsa_import.obj ltc/pk/rsa/rsa_import_pkcs8.obj ltc/pk/rsa/rsa_import_x509.obj \ -ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_set.obj ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj \ -ltc/pk/rsa/rsa_verify_hash.obj ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj \ -ltc/prngs/rng_get_bytes.obj ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj \ -ltc/prngs/yarrow.obj ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj \ -ltc/stream/chacha/chacha_ivctr32.obj ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj \ -ltc/stream/chacha/chacha_setup.obj ltc/stream/rabbit/rabbit.obj ltc/stream/rc4/rc4_stream.obj \ -ltc/stream/salsa20/salsa20_crypt.obj ltc/stream/salsa20/salsa20_done.obj ltc/stream/salsa20/salsa20_ivctr64.obj \ -ltc/stream/salsa20/salsa20_keystream.obj ltc/stream/salsa20/salsa20_setup.obj ltc/stream/salsa20/xsalsa20_setup.obj \ -ltc/stream/sober128/sober128_stream.obj ltc/stream/sosemanuk/sosemanuk.obj ltm/bncore.obj \ +ltc/pk/ecc/ecc_recover_key.obj ltc/pk/ecc/ecc_set_curve.obj ltc/pk/ecc/ecc_set_curve_internal.obj \ +ltc/pk/ecc/ecc_set_key.obj ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj \ +ltc/pk/ecc/ecc_sizes.obj ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ltc_ecc_export_point.obj \ +ltc/pk/ecc/ltc_ecc_import_point.obj ltc/pk/ecc/ltc_ecc_is_point.obj ltc/pk/ecc/ltc_ecc_is_point_at_infinity.obj \ +ltc/pk/ecc/ltc_ecc_map.obj ltc/pk/ecc/ltc_ecc_mul2add.obj ltc/pk/ecc/ltc_ecc_mulmod.obj \ +ltc/pk/ecc/ltc_ecc_mulmod_timing.obj ltc/pk/ecc/ltc_ecc_points.obj ltc/pk/ecc/ltc_ecc_projective_add_point.obj \ +ltc/pk/ecc/ltc_ecc_projective_dbl_point.obj ltc/pk/ecc/ltc_ecc_verify_key.obj ltc/pk/pkcs1/pkcs_1_i2osp.obj \ +ltc/pk/pkcs1/pkcs_1_mgf1.obj ltc/pk/pkcs1/pkcs_1_oaep_decode.obj ltc/pk/pkcs1/pkcs_1_oaep_encode.obj \ +ltc/pk/pkcs1/pkcs_1_os2ip.obj ltc/pk/pkcs1/pkcs_1_pss_decode.obj ltc/pk/pkcs1/pkcs_1_pss_encode.obj \ +ltc/pk/pkcs1/pkcs_1_v1_5_decode.obj ltc/pk/pkcs1/pkcs_1_v1_5_encode.obj ltc/pk/rsa/rsa_decrypt_key.obj \ +ltc/pk/rsa/rsa_encrypt_key.obj ltc/pk/rsa/rsa_export.obj ltc/pk/rsa/rsa_exptmod.obj \ +ltc/pk/rsa/rsa_free.obj ltc/pk/rsa/rsa_get_size.obj ltc/pk/rsa/rsa_import.obj ltc/pk/rsa/rsa_import_pkcs8.obj \ +ltc/pk/rsa/rsa_import_x509.obj ltc/pk/rsa/rsa_make_key.obj ltc/pk/rsa/rsa_set.obj \ +ltc/pk/rsa/rsa_sign_hash.obj ltc/pk/rsa/rsa_sign_saltlen_get.obj ltc/pk/rsa/rsa_verify_hash.obj \ +ltc/prngs/chacha20.obj ltc/prngs/fortuna.obj ltc/prngs/rc4.obj ltc/prngs/rng_get_bytes.obj \ +ltc/prngs/rng_make_prng.obj ltc/prngs/sober128.obj ltc/prngs/sprng.obj ltc/prngs/yarrow.obj \ +ltc/stream/chacha/chacha_crypt.obj ltc/stream/chacha/chacha_done.obj ltc/stream/chacha/chacha_ivctr32.obj \ +ltc/stream/chacha/chacha_ivctr64.obj ltc/stream/chacha/chacha_keystream.obj ltc/stream/chacha/chacha_memory.obj \ +ltc/stream/chacha/chacha_setup.obj ltc/stream/rabbit/rabbit.obj ltc/stream/rabbit/rabbit_memory.obj \ +ltc/stream/rc4/rc4_stream.obj ltc/stream/rc4/rc4_stream_memory.obj ltc/stream/salsa20/salsa20_crypt.obj \ +ltc/stream/salsa20/salsa20_done.obj ltc/stream/salsa20/salsa20_ivctr64.obj ltc/stream/salsa20/salsa20_keystream.obj \ +ltc/stream/salsa20/salsa20_memory.obj ltc/stream/salsa20/salsa20_setup.obj ltc/stream/salsa20/xsalsa20_memory.obj \ +ltc/stream/salsa20/xsalsa20_setup.obj ltc/stream/sober128/sober128_stream.obj ltc/stream/sober128/sober128_stream_memory.obj \ +ltc/stream/sosemanuk/sosemanuk.obj ltc/stream/sosemanuk/sosemanuk_memory.obj ltm/bncore.obj \ ltm/bn_error.obj ltm/bn_fast_mp_invmod.obj ltm/bn_fast_mp_montgomery_reduce.obj ltm/bn_fast_s_mp_mul_digs.obj \ ltm/bn_fast_s_mp_mul_high_digs.obj ltm/bn_fast_s_mp_sqr.obj ltm/bn_mp_2expt.obj ltm/bn_mp_abs.obj \ ltm/bn_mp_add.obj ltm/bn_mp_addmod.obj ltm/bn_mp_add_d.obj ltm/bn_mp_and.obj ltm/bn_mp_clamp.obj \ diff --git a/src/ltc/headers/tomcrypt_cipher.h b/src/ltc/headers/tomcrypt_cipher.h index 5c3a5e63..90573b3f 100644 --- a/src/ltc/headers/tomcrypt_cipher.h +++ b/src/ltc/headers/tomcrypt_cipher.h @@ -1009,6 +1009,9 @@ int chacha_crypt(chacha_state *st, const unsigned char *in, unsigned long inlen, int chacha_keystream(chacha_state *st, unsigned char *out, unsigned long outlen); int chacha_done(chacha_state *st); int chacha_test(void); +int chacha_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *iv, unsigned long ivlen, ulong64 counter, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout); #endif /* LTC_CHACHA */ @@ -1028,6 +1031,9 @@ int salsa20_crypt(salsa20_state *st, const unsigned char *in, unsigned long inle int salsa20_keystream(salsa20_state *st, unsigned char *out, unsigned long outlen); int salsa20_done(salsa20_state *st); int salsa20_test(void); +int salsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *iv, unsigned long ivlen, ulong64 counter, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout); #endif /* LTC_SALSA20 */ @@ -1037,6 +1043,9 @@ int xsalsa20_setup(salsa20_state *st, const unsigned char *key, unsigned long const unsigned char *nonce, unsigned long noncelen, int rounds); int xsalsa20_test(void); +int xsalsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout); #endif /* LTC_XSALSA20 */ @@ -1055,12 +1064,16 @@ typedef struct { unsigned ptr; } sosemanuk_state; -int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long keylen); -int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ivlen); -int sosemanuk_crypt(sosemanuk_state *ss, const unsigned char *in, unsigned long inlen, unsigned char *out); -int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen); -int sosemanuk_done(sosemanuk_state *ss); +int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen); +int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen); +int sosemanuk_crypt(sosemanuk_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out); +int sosemanuk_keystream(sosemanuk_state *st, unsigned char *out, unsigned long outlen); +int sosemanuk_done(sosemanuk_state *st); int sosemanuk_test(void); +int sosemanuk_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); #endif /* LTC_SOSEMANUK */ @@ -1085,6 +1098,10 @@ int rabbit_crypt(rabbit_state* st, const unsigned char *in, unsigned long inlen, int rabbit_keystream(rabbit_state* st, unsigned char *out, unsigned long outlen); int rabbit_done(rabbit_state *st); int rabbit_test(void); +int rabbit_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); #endif /* LTC_RABBIT */ @@ -1100,6 +1117,9 @@ int rc4_stream_crypt(rc4_state *st, const unsigned char *in, unsigned long inlen int rc4_stream_keystream(rc4_state *st, unsigned char *out, unsigned long outlen); int rc4_stream_done(rc4_state *st); int rc4_stream_test(void); +int rc4_stream_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); #endif /* LTC_RC4_STREAM */ @@ -1119,6 +1139,10 @@ int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen); int sober128_stream_done(sober128_state *st); int sober128_stream_test(void); +int sober128_stream_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout); #endif /* LTC_SOBER128_STREAM */ diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h index a151187f..1ec2a304 100644 --- a/src/ltc/headers/tomcrypt_custom.h +++ b/src/ltc/headers/tomcrypt_custom.h @@ -463,6 +463,7 @@ #define LTC_PKCS_1 #define LTC_PKCS_5 +#define LTC_PKCS_8 #define LTC_PKCS_12 /* Include ASN.1 DER (required by DSA/RSA) */ @@ -495,6 +496,8 @@ #define LTC_PADDING +#define LTC_PBES + #endif /* LTC_NO_MISC */ /* cleanup */ @@ -560,6 +563,15 @@ #define LTC_PKCS_1 #endif +#if defined(LTC_MRSA) || defined(LTC_MECC) + #define LTC_PKCS_8 +#endif + +#ifdef LTC_PKCS_8 + #define LTC_PADDING + #define LTC_PBES +#endif + #if defined(LTC_PELICAN) && !defined(LTC_RIJNDAEL) #error Pelican-MAC requires LTC_RIJNDAEL #endif diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h index b4e5fffd..64b39db5 100644 --- a/src/ltc/headers/tomcrypt_pk.h +++ b/src/ltc/headers/tomcrypt_pk.h @@ -244,6 +244,16 @@ typedef struct { void *k; } ecc_key; +/** Formats of ECC signatures */ +typedef enum ecc_signature_type_ { + /* ASN.1 encoded, ANSI X9.62 */ + LTC_ECCSIG_ANSIX962 = 0x0, + /* raw R, S values */ + LTC_ECCSIG_RFC7518 = 0x1, + /* raw R, S, V (+27) values */ + LTC_ECCSIG_ETH27 = 0x2 +} ecc_signature_type; + /** the ECC params provided */ extern const ltc_ecc_curve ltc_ecc_curves[]; @@ -287,21 +297,30 @@ int ecc_decrypt_key(const unsigned char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, const ecc_key *key); -int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key); +#define ecc_sign_hash_rfc7518(in_, inlen_, out_, outlen_, prng_, wprng_, key_) \ + ecc_sign_hash_ex(in_, inlen_, out_, outlen_, prng_, wprng_, LTC_ECCSIG_RFC7518, NULL, key_) + +#define ecc_sign_hash(in_, inlen_, out_, outlen_, prng_, wprng_, key_) \ + ecc_sign_hash_ex(in_, inlen_, out_, outlen_, prng_, wprng_, LTC_ECCSIG_ANSIX962, NULL, key_) + +#define ecc_verify_hash_rfc7518(sig_, siglen_, hash_, hashlen_, stat_, key_) \ + ecc_verify_hash_ex(sig_, siglen_, hash_, hashlen_, LTC_ECCSIG_RFC7518, stat_, key_) + +#define ecc_verify_hash(sig_, siglen_, hash_, hashlen_, stat_, key_) \ + ecc_verify_hash_ex(sig_, siglen_, hash_, hashlen_, LTC_ECCSIG_ANSIX962, stat_, key_) -int ecc_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key); +int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_signature_type sigformat, + int *recid, const ecc_key *key); -int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key); +int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ecc_signature_type sigformat, int *stat, const ecc_key *key); -int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, +int ecc_recover_key(const unsigned char *sig, unsigned long siglen, const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key); + int recid, ecc_signature_type sigformat, ecc_key *key); #endif diff --git a/src/ltc/headers/tomcrypt_private.h b/src/ltc/headers/tomcrypt_private.h index 7fe4b014..bd5a9d7f 100644 --- a/src/ltc/headers/tomcrypt_private.h +++ b/src/ltc/headers/tomcrypt_private.h @@ -19,7 +19,7 @@ * Internal Enums */ -enum public_key_algorithms { +enum ltc_oid_id { PKA_RSA, PKA_DSA, PKA_EC, @@ -30,18 +30,42 @@ enum public_key_algorithms { * Internal Types */ -typedef struct Oid { - unsigned long OID[16]; - /** Number of OID digits in use */ - unsigned long OIDlen; -} oid_st; - typedef struct { int size; const char *name, *base, *prime; } ltc_dh_set_type; +typedef int (*fn_kdf_t)(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen); + +typedef struct { + /* KDF */ + fn_kdf_t kdf; + /* Hash or HMAC */ + const char* h; + /* cipher */ + const char* c; + unsigned long keylen; + /* not used for pbkdf2 */ + unsigned long blocklen; +} pbes_properties; + +typedef struct +{ + pbes_properties type; + const void *pwd; + unsigned long pwdlen; + ltc_asn1_list *enc_data; + ltc_asn1_list *salt; + ltc_asn1_list *iv; + unsigned long iterations; + /* only used for RC2 */ + unsigned long key_bits; +} pbes_arg; + /* * Internal functions */ @@ -173,13 +197,18 @@ void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const void copy_or_zeromem(const unsigned char* src, unsigned char* dest, unsigned long len, int coz); +int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *dec_size); + +int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res); +int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res); + /* tomcrypt_pk.h */ int rand_bn_bits(void *N, int bits, prng_state *prng, int wprng); int rand_bn_upto(void *N, void *limit, prng_state *prng, int wprng); -int pk_get_oid(int pk, oid_st *st); +int pk_get_oid(enum ltc_oid_id id, const char **st); int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen); int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, unsigned long *outlen); @@ -265,6 +294,9 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat); #endif /* LTC_MDSA */ #ifdef LTC_DER + +#define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t))) + /* DER handling */ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen, ltc_asn1_list *root, @@ -303,10 +335,22 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i unsigned int algorithm, void* public_key, unsigned long* public_key_len, ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); +int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size); +int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2); + #endif /* LTC_DER */ /* tomcrypt_pkcs.h */ +#ifdef LTC_PKCS_8 + +int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen, + const void *pwd, unsigned long pwdlen, + ltc_asn1_list **decoded_list); + +#endif /* LTC_PKCS_8 */ + + #ifdef LTC_PKCS_12 int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen, diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c index 0b4912c4..a90732fa 100644 --- a/src/ltc/misc/crypt/crypt.c +++ b/src/ltc/misc/crypt/crypt.c @@ -436,6 +436,9 @@ const char *crypt_build_settings = #if defined(LTC_PKCS_5) " PKCS#5 " #endif +#if defined(LTC_PKCS_8) + " PKCS#8 " +#endif #if defined(LTC_PKCS_12) " PKCS#12 " #endif @@ -445,6 +448,10 @@ const char *crypt_build_settings = #if defined(LTC_HKDF) " HKDF " #endif +#if defined(LTC_PBES) + " PBES1 " + " PBES2 " +#endif #if defined(LTC_DEVRANDOM) " LTC_DEVRANDOM " #endif diff --git a/src/ltc/misc/pbes/pbes.c b/src/ltc/misc/pbes/pbes.c new file mode 100644 index 00000000..ab2f735e --- /dev/null +++ b/src/ltc/misc/pbes/pbes.c @@ -0,0 +1,83 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_PBES + +/** + Decrypt Data encrypted via either PBES1 or PBES2 + + @param arg The according PBES parameters + @param dec_data [out] The decrypted data + @param dec_size [in/out] The length of the encrypted resp. decrypted data + @return CRYPT_OK on success +*/ +int pbes_decrypt(const pbes_arg *arg, unsigned char *dec_data, unsigned long *dec_size) +{ + int err, hid = -1, cid = -1; + unsigned char k[32], *iv; + unsigned long klen, keylen, dlen; + long diff; + symmetric_CBC cbc; + + LTC_ARGCHK(arg != NULL); + LTC_ARGCHK(arg->type.kdf != NULL); + LTC_ARGCHK(dec_data != NULL); + LTC_ARGCHK(dec_size != NULL); + + hid = find_hash(arg->type.h); + if (hid == -1) return CRYPT_INVALID_HASH; + cid = find_cipher(arg->type.c); + if (cid == -1) return CRYPT_INVALID_CIPHER; + + klen = arg->type.keylen; + + /* RC2 special case */ + if (arg->key_bits != 0) { + /* We can't handle odd lengths of Key Bits */ + if ((arg->key_bits % 8) != 0) return CRYPT_INVALID_KEYSIZE; + /* Internally we use bytes, not bits */ + klen = arg->key_bits / 8; + } + keylen = klen; + + if (arg->iv != NULL) { + iv = arg->iv->data; + } else { + iv = k + klen; + klen += arg->type.blocklen; + } + + if (klen > sizeof(k)) return CRYPT_INVALID_ARG; + + if ((err = arg->type.kdf(arg->pwd, arg->pwdlen, arg->salt->data, arg->salt->size, arg->iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_start(cid, iv, k, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_decrypt(arg->enc_data->data, dec_data, arg->enc_data->size, &cbc)) != CRYPT_OK) goto LBL_ERROR; + if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; + dlen = arg->enc_data->size; + if ((err = padding_depad(dec_data, &dlen, LTC_PAD_PKCS7)) != CRYPT_OK) goto LBL_ERROR; + diff = (long)arg->enc_data->size - (long)dlen; + if ((diff <= 0) || (diff > cipher_descriptor[cid].block_length)) { + err = CRYPT_PK_INVALID_PADDING; + goto LBL_ERROR; + } + *dec_size = dlen; + return CRYPT_OK; + +LBL_ERROR: + zeromem(k, sizeof(k)); + zeromem(dec_data, *dec_size); + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/pbes/pbes1.c b/src/ltc/misc/pbes/pbes1.c new file mode 100644 index 00000000..45b1a464 --- /dev/null +++ b/src/ltc/misc/pbes/pbes1.c @@ -0,0 +1,127 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_PBES + +static int _pkcs_5_alg1_wrap(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + LTC_UNUSED_PARAM(salt_len); + return pkcs_5_alg1(password, password_len, salt, iteration_count, hash_idx, out, outlen); +} + +static int _pkcs_12_wrap(const unsigned char *password, unsigned long password_len, + const unsigned char *salt, unsigned long salt_len, + int iteration_count, int hash_idx, + unsigned char *out, unsigned long *outlen) +{ + int err; + /* convert password to unicode/utf16-be */ + unsigned long pwlen = password_len * 2; + unsigned char* pw; + if (*outlen < 32) return CRYPT_INVALID_ARG; + pw = XMALLOC(pwlen + 2); + if (pw == NULL) return CRYPT_MEM; + if ((err = pkcs12_utf8_to_utf16(password, password_len, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR; + pw[pwlen++] = 0; + pw[pwlen++] = 0; + /* derive KEY */ + if ((err = pkcs12_kdf(hash_idx, pw, pwlen, salt, salt_len, iteration_count, 1, out, 24)) != CRYPT_OK) goto LBL_ERROR; + /* derive IV */ + if ((err = pkcs12_kdf(hash_idx, pw, pwlen, salt, salt_len, iteration_count, 2, out+24, 8)) != CRYPT_OK) goto LBL_ERROR; + + *outlen = 32; +LBL_ERROR: + zeromem(pw, pwlen); + XFREE(pw); + return err; +} + +static const pbes_properties _pbes1_types[] = { + { _pkcs_5_alg1_wrap, "md2", "des", 8, 8 }, + { _pkcs_5_alg1_wrap, "md2", "rc2", 8, 8 }, + { _pkcs_5_alg1_wrap, "md5", "des", 8, 8 }, + { _pkcs_5_alg1_wrap, "md5", "rc2", 8, 8 }, + { _pkcs_5_alg1_wrap, "sha1", "des", 8, 8 }, + { _pkcs_5_alg1_wrap, "sha1", "rc2", 8, 8 }, + { _pkcs_12_wrap, "sha1", "3des", 24, 8 }, +}; + +typedef struct { + const pbes_properties *data; + const char *oid; +} oid_to_pbes; + +static const oid_to_pbes _pbes1_list[] = { + { &_pbes1_types[0], "1.2.840.113549.1.5.1" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.1 pbeWithMD2AndDES-CBC */ + { &_pbes1_types[1], "1.2.840.113549.1.5.4" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.4 pbeWithMD2AndRC2-CBC */ + { &_pbes1_types[2], "1.2.840.113549.1.5.3" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.3 pbeWithMD5AndDES-CBC */ + { &_pbes1_types[3], "1.2.840.113549.1.5.6" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.6 pbeWithMD5AndRC2-CBC */ + { &_pbes1_types[4], "1.2.840.113549.1.5.10" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.10 pbeWithSHA1AndDES-CBC */ + { &_pbes1_types[5], "1.2.840.113549.1.5.11" }, /* http://www.oid-info.com/get/1.2.840.113549.1.5.11 pbeWithSHA1AndRC2-CBC */ + { &_pbes1_types[6], "1.2.840.113549.1.12.1.3" }, /* http://www.oid-info.com/get/1.2.840.113549.1.12.1.3 pbeWithSHAAnd3-KeyTripleDES-CBC */ + { 0 }, +}; + +static int _pbes1_from_oid(const ltc_asn1_list *oid, pbes_properties *res) +{ + unsigned int i; + for (i = 0; _pbes1_list[i].data != NULL; ++i) { + if (pk_oid_cmp_with_asn1(_pbes1_list[i].oid, oid) == CRYPT_OK) { + if (res != NULL) *res = *_pbes1_list[i].data; + return CRYPT_OK; + } + } + return CRYPT_INVALID_ARG; +} + +/** + Extract PBES1 parameters + + @param s The start of the sequence with potential PBES1 parameters + @param res Pointer to where the extracted parameters should be stored + @return CRYPT_OK on success +*/ +int pbes1_extract(const ltc_asn1_list *s, pbes_arg *res) +{ + int err; + + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(res != NULL); + + if ((err = _pbes1_from_oid(s, &res->type)) != CRYPT_OK) return err; + + if (!LTC_ASN1_IS_TYPE(s->next, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(s->next->child, LTC_ASN1_OCTET_STRING) || + !LTC_ASN1_IS_TYPE(s->next->child->next, LTC_ASN1_INTEGER)) { + return CRYPT_INVALID_PACKET; + } + /* PBES1: encrypted pkcs8 - pbeWithMD5AndDES-CBC: + * 0:d=0 hl=4 l= 329 cons: SEQUENCE + * 4:d=1 hl=2 l= 27 cons: SEQUENCE + * 6:d=2 hl=2 l= 9 prim: OBJECT :pbeWithMD5AndDES-CBC (== 1.2.840.113549.1.5.3) (== *s) + * 17:d=2 hl=2 l= 14 cons: SEQUENCE (== *lalgparam) + * 19:d=3 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:8EDF749A06CCDE51 (== salt) + * 29:d=3 hl=2 l= 2 prim: INTEGER :0800 (== iterations) + * 33:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) + */ + res->salt = s->next->child; + res->iterations = mp_get_int(s->next->child->next->data); + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/pbes/pbes2.c b/src/ltc/misc/pbes/pbes2.c new file mode 100644 index 00000000..fcf5c309 --- /dev/null +++ b/src/ltc/misc/pbes/pbes2.c @@ -0,0 +1,201 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_PBES + +static const char *_oid_pbes2 = "1.2.840.113549.1.5.13"; +static const char *_oid_pbkdf2 = "1.2.840.113549.1.5.12"; + +typedef struct { + const char *oid; + const char *id; +} oid_id_st; + +static const oid_id_st _hmac_oid_names[] = { + { "1.2.840.113549.2.7", "sha1" }, + { "1.2.840.113549.2.8", "sha224" }, + { "1.2.840.113549.2.9", "sha256" }, + { "1.2.840.113549.2.10", "sha384" }, + { "1.2.840.113549.2.11", "sha512" }, + { "1.2.840.113549.2.12", "sha512-224" }, + { "1.2.840.113549.2.13", "sha512-256" }, +}; + +static const pbes_properties _pbes2_default_types[] = { + { pkcs_5_alg2, "sha1", "des", 8, 0 }, + { pkcs_5_alg2, "sha1", "rc2", 4, 0 }, + { pkcs_5_alg2, "sha1", "3des", 24, 0 }, + { pkcs_5_alg2, "sha1", "aes", 16, 0 }, + { pkcs_5_alg2, "sha1", "aes", 24, 0 }, + { pkcs_5_alg2, "sha1", "aes", 32, 0 }, +}; + +typedef struct { + const pbes_properties *data; + const char* oid; +} oid_to_pbes; + +static const oid_to_pbes _pbes2_list[] = { + { &_pbes2_default_types[0], "1.3.14.3.2.7" }, /* http://www.oid-info.com/get/1.3.14.3.2.7 desCBC */ + { &_pbes2_default_types[1], "1.2.840.113549.3.2" }, /* http://www.oid-info.com/get/1.2.840.113549.3.2 rc2CBC */ + { &_pbes2_default_types[2], "1.2.840.113549.3.7" }, /* http://www.oid-info.com/get/1.2.840.113549.3.7 des-EDE3-CBC */ + { &_pbes2_default_types[3], "2.16.840.1.101.3.4.1.2" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.2 aes128-CBC */ + { &_pbes2_default_types[4], "2.16.840.1.101.3.4.1.22" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.22 aes192-CBC */ + { &_pbes2_default_types[5], "2.16.840.1.101.3.4.1.42" }, /* http://www.oid-info.com/get/2.16.840.1.101.3.4.1.42 aes256-CBC */ +}; + +static int _pbes2_from_oid(const ltc_asn1_list *cipher_oid, const ltc_asn1_list *hmac_oid, pbes_properties *res) +{ + unsigned int i; + for (i = 0; i < sizeof(_pbes2_list)/sizeof(_pbes2_list[0]); ++i) { + if (pk_oid_cmp_with_asn1(_pbes2_list[i].oid, cipher_oid) == CRYPT_OK) { + *res = *_pbes2_list[i].data; + break; + } + } + if (res->c == NULL) return CRYPT_INVALID_CIPHER; + if (hmac_oid != NULL) { + for (i = 0; i < sizeof(_hmac_oid_names)/sizeof(_hmac_oid_names[0]); ++i) { + if (pk_oid_cmp_with_asn1(_hmac_oid_names[i].oid, hmac_oid) == CRYPT_OK) { + res->h = _hmac_oid_names[i].id; + return CRYPT_OK; + } + } + return CRYPT_INVALID_HASH; + } + return CRYPT_OK; +} + + +/** + Extract PBES2 parameters + + @param s The start of the sequence with potential PBES2 parameters + @param res Pointer to where the extracted parameters should be stored + @return CRYPT_OK on success +*/ +int pbes2_extract(const ltc_asn1_list *s, pbes_arg *res) +{ + unsigned long klen; + ltc_asn1_list *lkdf, *lenc, *loptseq, *lhmac; + int err; + + LTC_ARGCHK(s != NULL); + LTC_ARGCHK(res != NULL); + + if ((err = pk_oid_cmp_with_asn1(_oid_pbes2, s)) != CRYPT_OK) return err; + + if (!LTC_ASN1_IS_TYPE(s->next, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(s->next->child, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(s->next->child->child, LTC_ASN1_OBJECT_IDENTIFIER) || + !LTC_ASN1_IS_TYPE(s->next->child->child->next, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(s->next->child->next, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(s->next->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER)) { + return CRYPT_INVALID_PACKET; + } + /* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc: + * 0:d=0 hl=4 l= 380 cons: SEQUENCE + * 4:d=1 hl=2 l= 78 cons: SEQUENCE + * 6:d=2 hl=2 l= 9 prim: OBJECT :PBES2 (== 1.2.840.113549.1.5.13) (== *s) + * 17:d=2 hl=2 l= 65 cons: SEQUENCE + * 19:d=3 hl=2 l= 41 cons: SEQUENCE + * 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 (== *lkdf) + * 32:d=4 hl=2 l= 28 cons: SEQUENCE + * 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== res->salt) + * 44:d=5 hl=2 l= 2 prim: INTEGER :0800 (== res->iterations) + * 48:d=5 hl=2 l= 12 cons: SEQUENCE (== *loptseq - this sequence is optional, may be missing) + * 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 (== *lhmac) + * 60:d=6 hl=2 l= 0 prim: NULL + * 62:d=3 hl=2 l= 20 cons: SEQUENCE + * 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc (== *lenc) + * 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:B1404C4688DC9A5A + * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) + */ + lkdf = s->next->child->child; + lenc = s->next->child->next->child; + + if ((err = pk_oid_cmp_with_asn1(_oid_pbkdf2, lkdf)) != CRYPT_OK) return err; + + if (!LTC_ASN1_IS_TYPE(lkdf->next, LTC_ASN1_SEQUENCE) || + !LTC_ASN1_IS_TYPE(lkdf->next->child, LTC_ASN1_OCTET_STRING) || + !LTC_ASN1_IS_TYPE(lkdf->next->child->next, LTC_ASN1_INTEGER)) { + return CRYPT_INVALID_PACKET; + } + + loptseq = lkdf->next->child->next->next; + res->salt = lkdf->next->child; + res->iterations = mp_get_int(lkdf->next->child->next->data); + + /* this sequence is optional */ + lhmac = NULL; + if (LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_SEQUENCE) && + LTC_ASN1_IS_TYPE(loptseq->child, LTC_ASN1_OBJECT_IDENTIFIER)) { + lhmac = loptseq->child; + } + if ((err = _pbes2_from_oid(lenc, lhmac, &res->type)) != CRYPT_OK) return err; + + if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_OCTET_STRING)) { + /* 'NON-RC2'-CBC */ + res->iv = lenc->next; + } else if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_SEQUENCE)) { + /* RC2-CBC is a bit special ... + * + * RC2-CBC-Parameter ::= SEQUENCE { + * rc2ParameterVersion INTEGER OPTIONAL, + * iv OCTET STRING (SIZE(8)) } + */ + if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_INTEGER) && + LTC_ASN1_IS_TYPE(lenc->next->child->next, LTC_ASN1_OCTET_STRING)) { + klen = mp_get_int(lenc->next->child->data); + res->iv = lenc->next->child->next; + /* + * Effective Key Bits Encoding + * 40 160 + * 64 120 + * 128 58 + * b >= 256 b + */ + switch (klen) { + case 160: + res->key_bits = 40; + break; + case 120: + res->key_bits = 64; + break; + case 58: + res->key_bits = 128; + break; + default: + /* We don't handle undefined Key Bits */ + if (klen < 256) return CRYPT_INVALID_KEYSIZE; + + res->key_bits = klen; + break; + } + } else if (LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_OCTET_STRING)) { + res->iv = lenc->next->child; + /* + * If the rc2ParameterVersion field is omitted, the "effective key bits" + * defaults to 32. + */ + res->key_bits = 32; + } else { + return CRYPT_INVALID_PACKET; + } + } + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/pk_get_oid.c b/src/ltc/misc/pk_get_oid.c deleted file mode 100644 index 35e35d6b..00000000 --- a/src/ltc/misc/pk_get_oid.c +++ /dev/null @@ -1,60 +0,0 @@ -/* LibTomCrypt, modular cryptographic library -- Tom St Denis - * - * LibTomCrypt is a library that provides various cryptographic - * algorithms in a highly modular and flexible manner. - * - * The library is free for all purposes without any express - * guarantee it works. - */ -#include "tomcrypt_private.h" - -#ifdef LTC_DER -static const oid_st rsa_oid = { - { 1, 2, 840, 113549, 1, 1, 1 }, - 7, -}; - -static const oid_st dsa_oid = { - { 1, 2, 840, 10040, 4, 1 }, - 6, -}; - -static const oid_st ec_oid = { - { 1, 2, 840, 10045, 2, 1 }, - 6, -}; - -static const oid_st ec_primef = { - { 1, 2, 840, 10045, 1, 1 }, - 6, -}; - -/* - Returns the OID of the public key algorithm. - @return CRYPT_OK if valid -*/ -int pk_get_oid(int pk, oid_st *st) -{ - switch (pk) { - case PKA_RSA: - XMEMCPY(st, &rsa_oid, sizeof(*st)); - break; - case PKA_DSA: - XMEMCPY(st, &dsa_oid, sizeof(*st)); - break; - case PKA_EC: - XMEMCPY(st, &ec_oid, sizeof(*st)); - break; - case PKA_EC_PRIMEF: - XMEMCPY(st, &ec_primef, sizeof(*st)); - break; - default: - return CRYPT_INVALID_ARG; - } - return CRYPT_OK; -} -#endif - -/* ref: $Format:%D$ */ -/* git commit: $Format:%H$ */ -/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/pkcs12/pkcs12_kdf.c b/src/ltc/misc/pkcs12/pkcs12_kdf.c index d097e8a9..a67b4fa8 100644 --- a/src/ltc/misc/pkcs12/pkcs12_kdf.c +++ b/src/ltc/misc/pkcs12/pkcs12_kdf.c @@ -27,7 +27,7 @@ int pkcs12_kdf( int hash_id, unsigned int tmp, i, j, n; unsigned char ch; unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE]; - unsigned char *I = NULL, *key = NULL; + unsigned char *I, *key; int err = CRYPT_ERROR; LTC_ARGCHK(pw != NULL); diff --git a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c index f4978627..23dcf770 100644 --- a/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c +++ b/src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c @@ -71,8 +71,13 @@ int der_decode_object_identifier(const unsigned char *in, unsigned long inle y++; } else { if (y == 0) { - words[0] = t / 40; - words[1] = t % 40; + if (t <= 79) { + words[0] = t / 40; + words[1] = t % 40; + } else { + words[0] = 2; + words[1] = t - 80; + } y = 2; } else { words[y++] = t; diff --git a/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c index cc22a3c9..e6cff37a 100644 --- a/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c +++ b/src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c @@ -48,8 +48,8 @@ int der_length_object_identifier(const unsigned long *words, unsigned long nword return CRYPT_INVALID_ARG; } - /* word1 = 0,1,2,3 and word2 0..39 */ - if (words[0] > 3 || (words[0] < 2 && words[1] > 39)) { + /* word1 = 0,1,2 and word2 0..39 */ + if (words[0] > 2 || (words[0] < 2 && words[1] > 39)) { return CRYPT_INVALID_ARG; } diff --git a/src/ltc/pk/asn1/oid/pk_get_oid.c b/src/ltc/pk/asn1/oid/pk_get_oid.c new file mode 100644 index 00000000..529cf66a --- /dev/null +++ b/src/ltc/pk/asn1/oid/pk_get_oid.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_DER + +typedef struct { + enum ltc_oid_id id; + const char* oid; +} oid_table_entry; + +static const oid_table_entry pka_oids[] = { + { PKA_RSA, "1.2.840.113549.1.1.1" }, + { PKA_DSA, "1.2.840.10040.4.1" }, + { PKA_EC, "1.2.840.10045.2.1" }, + { PKA_EC_PRIMEF, "1.2.840.10045.1.1" }, +}; + +/* + Returns the OID requested. + @return CRYPT_OK if valid +*/ +int pk_get_oid(enum ltc_oid_id id, const char **st) +{ + unsigned int i; + LTC_ARGCHK(st != NULL); + for (i = 0; i < sizeof(pka_oids)/sizeof(pka_oids[0]); ++i) { + if (pka_oids[i].id == id) { + *st = pka_oids[i].oid; + return CRYPT_OK; + } + } + return CRYPT_INVALID_ARG; +} +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/oid/pk_oid_cmp.c b/src/ltc/pk/asn1/oid/pk_oid_cmp.c new file mode 100644 index 00000000..5e3f1207 --- /dev/null +++ b/src/ltc/pk/asn1/oid/pk_oid_cmp.c @@ -0,0 +1,54 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_DER + +/* + Compare an OID string to an array of `unsigned long`. + @return CRYPT_OK if equal +*/ +int pk_oid_cmp_with_ulong(const char *o1, const unsigned long *o2, unsigned long o2size) +{ + unsigned long i; + char tmp[256] = { 0 }; + int err; + + if (o1 == NULL || o2 == NULL) return CRYPT_ERROR; + + i = sizeof(tmp); + if ((err = pk_oid_num_to_str(o2, o2size, tmp, &i)) != CRYPT_OK) { + return err; + } + + if (XSTRCMP(o1, tmp) != 0) { + return CRYPT_PK_INVALID_TYPE; + } + + return CRYPT_OK; +} + +/* + Compare an OID string to an OID element decoded from ASN.1. + @return CRYPT_OK if equal +*/ +int pk_oid_cmp_with_asn1(const char *o1, const ltc_asn1_list *o2) +{ + if (o1 == NULL || o2 == NULL) return CRYPT_ERROR; + + if (o2->type != LTC_ASN1_OBJECT_IDENTIFIER) return CRYPT_INVALID_ARG; + + return pk_oid_cmp_with_ulong(o1, o2->data, o2->size); +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/pk_oid_str.c b/src/ltc/pk/asn1/oid/pk_oid_str.c index ef83fb18..afe6a1e8 100644 --- a/src/ltc/misc/pk_oid_str.c +++ b/src/ltc/pk/asn1/oid/pk_oid_str.c @@ -11,29 +11,38 @@ int pk_oid_str_to_num(const char *OID, unsigned long *oid, unsigned long *oidlen) { - unsigned long i, j, limit; + unsigned long i, j, limit, OID_len, oid_j; - LTC_ARGCHK(oid != NULL); LTC_ARGCHK(oidlen != NULL); limit = *oidlen; *oidlen = 0; /* make sure that we return zero oidlen on error */ for (i = 0; i < limit; i++) oid[i] = 0; - if ((OID == NULL) || (strlen(OID) == 0)) return CRYPT_OK; + if (OID == NULL) return CRYPT_OK; + + OID_len = strlen(OID); + if (OID_len == 0) return CRYPT_OK; - for (i = 0, j = 0; i < strlen(OID); i++) { + for (i = 0, j = 0; i < OID_len; i++) { if (OID[i] == '.') { - if (++j >= limit) return CRYPT_ERROR; + if (++j >= limit) continue; } else if ((OID[i] >= '0') && (OID[i] <= '9')) { + if ((j >= limit) || (oid == NULL)) continue; + oid_j = oid[j]; oid[j] = oid[j] * 10 + (OID[i] - '0'); + if (oid[j] < oid_j) return CRYPT_OVERFLOW; } else { return CRYPT_ERROR; } } if (j == 0) return CRYPT_ERROR; + if (j >= limit) { + *oidlen = j; + return CRYPT_BUFFER_OVERFLOW; + } *oidlen = j + 1; return CRYPT_OK; } @@ -43,7 +52,6 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, int i; unsigned long j, k; char tmp[256] = { 0 }; - unsigned long tmpsz = sizeof(tmp); LTC_ARGCHK(oid != NULL); LTC_ARGCHK(OID != NULL); @@ -53,18 +61,18 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID, j = oid[i]; if (j == 0) { tmp[k] = '0'; - if (++k >= tmpsz) return CRYPT_ERROR; + if (++k >= sizeof(tmp)) return CRYPT_ERROR; } else { while (j > 0) { tmp[k] = '0' + (j % 10); - if (++k >= tmpsz) return CRYPT_ERROR; + if (++k >= sizeof(tmp)) return CRYPT_ERROR; j /= 10; } } if (i > 0) { tmp[k] = '.'; - if (++k >= tmpsz) return CRYPT_ERROR; + if (++k >= sizeof(tmp)) return CRYPT_ERROR; } } if (*outlen < k + 1) { diff --git a/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c b/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c new file mode 100644 index 00000000..eef2f410 --- /dev/null +++ b/src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c @@ -0,0 +1,107 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt_private.h" + +#ifdef LTC_PKCS_8 + +/** + PKCS#8 decrypt if necessary & flexi-decode + + @param in Pointer to the ASN.1 encoded input data + @param inlen Length of the input data + @param pwd Pointer to the password that was used when encrypting + @param pwdlen Length of the password + @param decoded_list Pointer to a pointer for the flexi-decoded list + @return CRYPT_OK on success +*/ +int pkcs8_decode_flexi(const unsigned char *in, unsigned long inlen, + const void *pwd, unsigned long pwdlen, + ltc_asn1_list **decoded_list) +{ + unsigned long len = inlen; + unsigned long dec_size; + unsigned char *dec_data = NULL; + ltc_asn1_list *l = NULL; + int err; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(decoded_list != NULL); + + *decoded_list = NULL; + if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) { + /* the following "if" detects whether it is encrypted or not */ + /* PKCS8 Setup + * 0:d=0 hl=4 l= 380 cons: SEQUENCE + * 4:d=1 hl=2 l= 78 cons: SEQUENCE + * 6:d=2 hl=2 l= 9 prim: OBJECT :OID indicating PBES1 or PBES2 (== *lalgoid) + * 17:d=2 hl=2 l= 65 cons: SEQUENCE + * Stuff in between is dependent on whether it's PBES1 or PBES2 + * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) + */ + if (l->type == LTC_ASN1_SEQUENCE && + LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_SEQUENCE) && + LTC_ASN1_IS_TYPE(l->child->child, LTC_ASN1_OBJECT_IDENTIFIER) && + LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) && + LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) { + ltc_asn1_list *lalgoid = l->child->child; + pbes_arg pbes; + + XMEMSET(&pbes, 0, sizeof(pbes)); + + if (pbes1_extract(lalgoid, &pbes) == CRYPT_OK) { + /* Successfully extracted PBES1 parameters */ + } else if (pbes2_extract(lalgoid, &pbes) == CRYPT_OK) { + /* Successfully extracted PBES2 parameters */ + } else { + /* unsupported encryption */ + err = CRYPT_INVALID_PACKET; + goto LBL_DONE; + } + + pbes.enc_data = l->child->next; + pbes.pwd = pwd; + pbes.pwdlen = pwdlen; + + dec_size = pbes.enc_data->size; + if ((dec_data = XMALLOC(dec_size)) == NULL) { + err = CRYPT_MEM; + goto LBL_DONE; + } + + if ((err = pbes_decrypt(&pbes, dec_data, &dec_size)) != CRYPT_OK) goto LBL_DONE; + + der_free_sequence_flexi(l); + l = NULL; + err = der_decode_sequence_flexi(dec_data, &dec_size, &l); + if (err != CRYPT_OK) goto LBL_DONE; + *decoded_list = l; + } + else { + /* not encrypted */ + err = CRYPT_OK; + *decoded_list = l; + } + /* Set l to NULL so it won't be free'd */ + l = NULL; + } + +LBL_DONE: + if (l) der_free_sequence_flexi(l); + if (dec_data) { + zeromem(dec_data, dec_size); + XFREE(dec_data); + } + return err; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c index ba51f292..bd84e7c7 100644 --- a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c @@ -43,7 +43,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i { int err; unsigned long len, alg_id_num; - oid_st oid; + const char* oid; unsigned char *tmpbuf; unsigned long tmpoid[16]; ltc_asn1_list alg_id[2]; @@ -92,11 +92,9 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i *parameters_len = alg_id[1].size; } - if ((alg_id[0].size != oid.OIDlen) || - XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0])) != 0) { - /* OID mismatch */ - err = CRYPT_PK_INVALID_TYPE; - goto LBL_ERR; + if ((err = pk_oid_cmp_with_asn1(oid, &alg_id[0])) != CRYPT_OK) { + /* OID mismatch */ + goto LBL_ERR; } len = subject_pubkey[1].size/8; diff --git a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c index bb29fed8..c9607b1c 100644 --- a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c @@ -43,17 +43,22 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle { int err; ltc_asn1_list alg_id[2]; - oid_st oid; + const char *OID; + unsigned long oid[16], oidlen; LTC_ARGCHK(out != NULL); LTC_ARGCHK(outlen != NULL); - err = pk_get_oid(algorithm, &oid); - if (err != CRYPT_OK) { + if ((err = pk_get_oid(algorithm, &OID)) != CRYPT_OK) { return err; } - LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); + oidlen = sizeof(oid)/sizeof(oid[0]); + if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { + return err; + } + + LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen); LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); return der_encode_sequence_multi(out, outlen, diff --git a/src/ltc/pk/ecc/ecc_export_openssl.c b/src/ltc/pk/ecc/ecc_export_openssl.c index 08056fea..ab48ae5c 100644 --- a/src/ltc/pk/ecc/ecc_export_openssl.c +++ b/src/ltc/pk/ecc/ecc_export_openssl.c @@ -27,7 +27,8 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons unsigned char bin_a[256], bin_b[256], bin_k[256], bin_g[512], bin_xy[512]; unsigned long len_a, len_b, len_k, len_g, len_xy; unsigned long cofactor, one = 1; - oid_st oid; + const char *OID; + unsigned long oid[16], oidlen; ltc_asn1_list seq_fieldid[2], seq_curve[2], seq_ecparams[6], seq_priv[4], pub_xy, ecparams; int flag_oid = type & PK_CURVEOID ? 1 : 0; int flag_com = type & PK_COMPRESSED ? 1 : 0; @@ -72,7 +73,7 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons cofactor = key->dp.cofactor; /* we support only prime-field EC */ - if ((err = pk_get_oid(PKA_EC_PRIMEF, &oid)) != CRYPT_OK) { goto error; } + if ((err = pk_get_oid(PKA_EC_PRIMEF, &OID)) != CRYPT_OK) { goto error; } if (flag_oid) { /* http://tools.ietf.org/html/rfc5912 @@ -102,8 +103,13 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons } */ + oidlen = sizeof(oid)/sizeof(oid[0]); + if ((err = pk_oid_str_to_num(OID, oid, &oidlen)) != CRYPT_OK) { + goto error; + } + /* FieldID SEQUENCE */ - LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); + LTC_SET_ASN1(seq_fieldid, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, oidlen); LTC_SET_ASN1(seq_fieldid, 1, LTC_ASN1_INTEGER, prime, 1UL); /* Curve SEQUENCE */ diff --git a/src/ltc/pk/ecc/ecc_import_pkcs8.c b/src/ltc/pk/ecc/ecc_import_pkcs8.c index e606699b..8db49da7 100644 --- a/src/ltc/pk/ecc/ecc_import_pkcs8.c +++ b/src/ltc/pk/ecc/ecc_import_pkcs8.c @@ -11,345 +11,32 @@ #ifdef LTC_MECC -#define LTC_ASN1_IS_TYPE(e, t) (((e) != NULL) && ((e)->type == (t))) - -enum algorithm_oid { - PBE_MD2_DES, /* 0 */ - PBE_MD2_RC2, - PBE_MD5_DES, - PBE_MD5_RC2, - PBE_SHA1_DES, - PBE_SHA1_RC2, /* 5 */ - PBES2, - PBKDF2, - DES_CBC, - RC2_CBC, - DES_EDE3_CBC, /* 10 */ - HMAC_WITH_SHA1, - HMAC_WITH_SHA224, - HMAC_WITH_SHA256, - HMAC_WITH_SHA384, - HMAC_WITH_SHA512, /* 15 */ - PBE_SHA1_3DES -}; - -static const oid_st oid_list[] = { - { { 1,2,840,113549,1,5,1 }, 7 }, /* [0] http://www.oid-info.com/get/1.2.840.113549.1.5.1 pbeWithMD2AndDES-CBC */ - { { 1,2,840,113549,1,5,4 }, 7 }, /* [1] http://www.oid-info.com/get/1.2.840.113549.1.5.4 pbeWithMD2AndRC2-CBC */ - { { 1,2,840,113549,1,5,3 }, 7 }, /* [2] http://www.oid-info.com/get/1.2.840.113549.1.5.3 pbeWithMD5AndDES-CBC */ - { { 1,2,840,113549,1,5,6 }, 7 }, /* [3] http://www.oid-info.com/get/1.2.840.113549.1.5.6 pbeWithMD5AndRC2-CBC */ - { { 1,2,840,113549,1,5,10 }, 7 }, /* [4] http://www.oid-info.com/get/1.2.840.113549.1.5.10 pbeWithSHA1AndDES-CBC */ - { { 1,2,840,113549,1,5,11 }, 7 }, /* [5] http://www.oid-info.com/get/1.2.840.113549.1.5.11 pbeWithSHA1AndRC2-CBC */ - { { 1,2,840,113549,1,5,13 }, 7 }, /* [6] http://www.oid-info.com/get/1.2.840.113549.1.5.13 pbes2 */ - { { 1,2,840,113549,1,5,12 }, 7 }, /* [7] http://www.oid-info.com/get/1.2.840.113549.1.5.12 pBKDF2 */ - { { 1,3,14,3,2,7 }, 6 }, /* [8] http://www.oid-info.com/get/1.3.14.3.2.7 desCBC */ - { { 1,2,840,113549,3,2 }, 6 }, /* [9] http://www.oid-info.com/get/1.2.840.113549.3.2 rc2CBC */ - { { 1,2,840,113549,3,7 }, 6 }, /* [10] http://www.oid-info.com/get/1.2.840.113549.3.7 des-EDE3-CBC */ - { { 1,2,840,113549,2,7 }, 6 }, /* [11] http://www.oid-info.com/get/1.2.840.113549.2.7 hmacWithSHA1 */ - { { 1,2,840,113549,2,8 }, 6 }, /* [12] http://www.oid-info.com/get/1.2.840.113549.2.8 hmacWithSHA224 */ - { { 1,2,840,113549,2,9 }, 6 }, /* [13] http://www.oid-info.com/get/1.2.840.113549.2.9 hmacWithSHA256 */ - { { 1,2,840,113549,2,10 }, 6 }, /* [14] http://www.oid-info.com/get/1.2.840.113549.2.10 hmacWithSHA384 */ - { { 1,2,840,113549,2,11 }, 6 }, /* [15] http://www.oid-info.com/get/1.2.840.113549.2.11 hmacWithSHA512 */ - { { 1,2,840,113549,1,12,1,3 }, 8 }, /* [16] http://www.oid-info.com/get/1.2.840.113549.1.12.1.3 pbeWithSHAAnd3-KeyTripleDES-CBC */ - { { 0 }, 0 }, -}; - -static int _oid_to_id(const unsigned long *oid, unsigned long oid_size) -{ - int i, j; - for (j = 0; oid_list[j].OIDlen > 0; j++) { - int match = 1; - if (oid_list[j].OIDlen != oid_size) continue; - for (i = 0; i < (int)oid_size && match; i++) if (oid_list[j].OID[i] != oid[i]) match = 0; - if (match) return j; - } - return -1; -} - -static int _pbes1_decrypt(const unsigned char *enc_data, unsigned long enc_size, - const unsigned char *pass, unsigned long pass_size, - const unsigned char *salt, unsigned long salt_size, - unsigned long iterations, - const unsigned long *oid, unsigned long oid_size, - unsigned char *dec_data, unsigned long *dec_size) -{ - int id = _oid_to_id(oid, oid_size); - int err, hid = -1, cid = -1; - unsigned int keylen, blklen; - unsigned char key_iv[32] = { 0 }, pad; - unsigned long len = sizeof(key_iv), pwlen = pass_size; - symmetric_CBC cbc; - unsigned char *pw = NULL; - - /* https://tools.ietf.org/html/rfc8018#section-6.1.2 */ - if (id == PBE_MD2_DES || id == PBE_MD2_RC2) hid = find_hash("md2"); - if (id == PBE_MD5_DES || id == PBE_MD5_RC2) hid = find_hash("md5"); - if (id == PBE_SHA1_DES || id == PBE_SHA1_RC2 || id == PBE_SHA1_3DES) hid = find_hash("sha1"); - - if (id == PBE_MD2_RC2 || id == PBE_MD5_RC2 || id == PBE_SHA1_RC2) { - cid = find_cipher("rc2"); - keylen = 8; - blklen = 8; - } - if (id == PBE_MD2_DES || id == PBE_MD5_DES || id == PBE_SHA1_DES) { - cid = find_cipher("des"); - keylen = 8; - blklen = 8; - } - if (id == PBE_SHA1_3DES) { - cid = find_cipher("3des"); - keylen = 24; - blklen = 8; - } - - if (id == PBE_SHA1_3DES) { - /* convert password to unicode/utf16-be */ - pwlen = pass_size * 2; - pw = XMALLOC(pwlen + 2); - if (pw == NULL) goto LBL_ERROR; - if ((err = pkcs12_utf8_to_utf16(pass, pass_size, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR; - pw[pwlen++] = 0; - pw[pwlen++] = 0; - /* derive KEY */ - if ((err = pkcs12_kdf(hid, pw, pwlen, salt, salt_size, iterations, 1, key_iv, keylen)) != CRYPT_OK) goto LBL_ERROR; - /* derive IV */ - if ((err = pkcs12_kdf(hid, pw, pwlen, salt, salt_size, iterations, 2, key_iv+24, blklen)) != CRYPT_OK) goto LBL_ERROR; - } - else { - if ((err = pkcs_5_alg1(pass, pass_size, salt, iterations, hid, key_iv, &len)) != CRYPT_OK) goto LBL_ERROR; - /* the output has 16 bytes: [KEY-8-bytes][IV-8-bytes] */ - } - - if (hid != -1 && cid != -1) { - if (salt_size != 8 || enc_size < blklen) goto LBL_ERROR; - if ((err = cbc_start(cid, key_iv + keylen, key_iv, keylen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; - pad = dec_data[enc_size-1]; - if (pad < 1 || pad > blklen) goto LBL_ERROR; - *dec_size = enc_size - pad; - err = CRYPT_OK; - goto LBL_DONE; - } - -LBL_ERROR: - err = CRYPT_INVALID_ARG; -LBL_DONE: - zeromem(key_iv, sizeof(key_iv)); - if (pw) { zeromem(pw, pwlen); XFREE(pw); } - return err; -} - -static int _pbes2_pbkdf2_decrypt(const unsigned char *enc_data, unsigned long enc_size, - const unsigned char *pass, unsigned long pass_size, - const unsigned char *salt, unsigned long salt_size, - const unsigned char *iv, unsigned long iv_size, - unsigned long iterations, - int hmacid, - int encid, - int extra_arg, - unsigned char *dec_data, unsigned long *dec_size) -{ - int err, hid = -1, cid = -1; - unsigned char k[32], pad; - unsigned long klen = sizeof(k); - symmetric_CBC cbc; - - /* https://tools.ietf.org/html/rfc8018#section-6.2.2 */ - - if (hmacid == HMAC_WITH_SHA1) hid = find_hash("sha1"); - if (hmacid == HMAC_WITH_SHA224) hid = find_hash("sha224"); - if (hmacid == HMAC_WITH_SHA256) hid = find_hash("sha256"); - if (hmacid == HMAC_WITH_SHA384) hid = find_hash("sha384"); - if (hmacid == HMAC_WITH_SHA512) hid = find_hash("sha512"); - if (hid == -1) return CRYPT_INVALID_ARG; - - if (encid == DES_EDE3_CBC) { - /* https://tools.ietf.org/html/rfc8018#appendix-B.2.2 */ - cid = find_cipher("3des"); - klen = 24; - if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; - if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; - pad = dec_data[enc_size-1]; - if (pad < 1 || pad > 8) goto LBL_ERROR; - *dec_size = enc_size - pad; - return CRYPT_OK; - } - - if (encid == DES_CBC) { - /* https://tools.ietf.org/html/rfc8018#appendix-B.2.1 */ - cid = find_cipher("des"); - klen = 8; /* 64 bits */ - if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; - if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; - pad = dec_data[enc_size-1]; - if (pad < 1 || pad > 8) goto LBL_ERROR; - *dec_size = enc_size - pad; - return CRYPT_OK; - } - - if (encid == RC2_CBC) { - /* https://tools.ietf.org/html/rfc8018#appendix-B.2.3 */ - cid = find_cipher("rc2"); - klen = 4; /* default: 32 bits */ - if (extra_arg == 160) klen = 5; - if (extra_arg == 120) klen = 8; - if (extra_arg == 58) klen = 16; - if (extra_arg >= 256) klen = extra_arg / 8; - if (klen > sizeof(k) || iv_size != 8 || iv == NULL || cid == -1) goto LBL_ERROR; - if ((err = pkcs_5_alg2(pass, pass_size, salt, salt_size, iterations, hid, k, &klen)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_start(cid, iv, k, klen, 0, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_decrypt(enc_data, dec_data, enc_size, &cbc)) != CRYPT_OK) goto LBL_ERROR; - if ((err = cbc_done(&cbc)) != CRYPT_OK) goto LBL_ERROR; - pad = dec_data[enc_size-1]; - if (pad < 1 || pad > 8) goto LBL_ERROR; - *dec_size = enc_size - pad; - return CRYPT_OK; - } - -LBL_ERROR: - zeromem(k, sizeof(k)); - return CRYPT_INVALID_ARG; -} - -static int _der_decode_pkcs8_flexi(const unsigned char *in, unsigned long inlen, - const void *pwd, unsigned long pwdlen, - ltc_asn1_list **decoded_list) +typedef struct { + ltc_asn1_type t; + ltc_asn1_list **pp; +} der_flexi_check; + +#define LTC_SET_DER_FLEXI_CHECK(list, index, Type, P) \ + do { \ + int LTC_SDFC_temp##__LINE__ = (index); \ + list[LTC_SDFC_temp##__LINE__].t = Type; \ + list[LTC_SDFC_temp##__LINE__].pp = P; \ + } while (0) + +static int _der_flexi_sequence_cmp(const ltc_asn1_list *flexi, der_flexi_check *check) { - unsigned long len = inlen; - unsigned long dec_size; - unsigned char *dec_data = NULL; - ltc_asn1_list *l = NULL; - int err; - - *decoded_list = NULL; - if ((err = der_decode_sequence_flexi(in, &len, &l)) == CRYPT_OK) { - /* the following "if" detects whether it is encrypted or not */ - if (l->type == LTC_ASN1_SEQUENCE && - LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(l->child->child, LTC_ASN1_OBJECT_IDENTIFIER) && - LTC_ASN1_IS_TYPE(l->child->child->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_OCTET_STRING)) { - ltc_asn1_list *lalgoid = l->child->child; - ltc_asn1_list *lalgparam = l->child->child->next; - unsigned char *enc_data = l->child->next->data; - unsigned long enc_size = l->child->next->size; - dec_size = enc_size; - if ((dec_data = XMALLOC(dec_size)) == NULL) { - err = CRYPT_MEM; - goto LBL_DONE; - } - if (LTC_ASN1_IS_TYPE(lalgparam->child, LTC_ASN1_OCTET_STRING) && - LTC_ASN1_IS_TYPE(lalgparam->child->next, LTC_ASN1_INTEGER)) { - /* PBES1: encrypted pkcs8 - pbeWithMD5AndDES-CBC: - * 0:d=0 hl=4 l= 329 cons: SEQUENCE - * 4:d=1 hl=2 l= 27 cons: SEQUENCE (== *lalg) - * 6:d=2 hl=2 l= 9 prim: OBJECT :pbeWithMD5AndDES-CBC (== 1.2.840.113549.1.5.3) - * 17:d=2 hl=2 l= 14 cons: SEQUENCE (== *lalgparam) - * 19:d=3 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:8EDF749A06CCDE51 (== salt) - * 29:d=3 hl=2 l= 2 prim: INTEGER :0800 (== iterations) - * 33:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) - */ - unsigned long iter = mp_get_int(lalgparam->child->next->data); - unsigned long salt_size = lalgparam->child->size; - unsigned char *salt = lalgparam->child->data; - err = _pbes1_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iter, lalgoid->data, lalgoid->size, dec_data, &dec_size); - if (err != CRYPT_OK) goto LBL_DONE; - } - else if (PBES2 == _oid_to_id(lalgoid->data, lalgoid->size) && - LTC_ASN1_IS_TYPE(lalgparam->child, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lalgparam->child->child, LTC_ASN1_OBJECT_IDENTIFIER) && - LTC_ASN1_IS_TYPE(lalgparam->child->child->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lalgparam->child->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lalgparam->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER)) { - /* PBES2: encrypted pkcs8 - PBES2+PBKDF2+des-ede3-cbc: - * 0:d=0 hl=4 l= 380 cons: SEQUENCE - * 4:d=1 hl=2 l= 78 cons: SEQUENCE (== *lalg) - * 6:d=2 hl=2 l= 9 prim: OBJECT :PBES2 (== 1.2.840.113549.1.5.13) - * 17:d=2 hl=2 l= 65 cons: SEQUENCE (== *lalgparam) - * 19:d=3 hl=2 l= 41 cons: SEQUENCE - * 21:d=4 hl=2 l= 9 prim: OBJECT :PBKDF2 - * 32:d=4 hl=2 l= 28 cons: SEQUENCE - * 34:d=5 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:28BA4ABF6AA76A3D (== salt) - * 44:d=5 hl=2 l= 2 prim: INTEGER :0800 (== iterations) - * 48:d=5 hl=2 l= 12 cons: SEQUENCE (this sequence is optional, may be missing) - * 50:d=6 hl=2 l= 8 prim: OBJECT :hmacWithSHA256 - * 60:d=6 hl=2 l= 0 prim: NULL - * 62:d=3 hl=2 l= 20 cons: SEQUENCE - * 64:d=4 hl=2 l= 8 prim: OBJECT :des-ede3-cbc - * 74:d=4 hl=2 l= 8 prim: OCTET STRING [HEX DUMP]:B1404C4688DC9A5A - * 84:d=1 hl=4 l= 296 prim: OCTET STRING :bytes (== encrypted data) - */ - ltc_asn1_list *lkdf = lalgparam->child->child; - ltc_asn1_list *lenc = lalgparam->child->next->child; - int kdfid = _oid_to_id(lkdf->data, lkdf->size); - int encid = _oid_to_id(lenc->data, lenc->size); - if (PBKDF2 == kdfid && - LTC_ASN1_IS_TYPE(lkdf->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lkdf->next->child, LTC_ASN1_OCTET_STRING) && - LTC_ASN1_IS_TYPE(lkdf->next->child->next, LTC_ASN1_INTEGER)) { - unsigned long iter = mp_get_int(lkdf->next->child->next->data); - unsigned long salt_size = lkdf->next->child->size; - unsigned char *salt = lkdf->next->child->data; - unsigned char *iv = NULL; - unsigned long iv_size = 0; - unsigned long arg = 0; - ltc_asn1_list *loptseq = lkdf->next->child->next->next; - int hmacid = HMAC_WITH_SHA1; /* this is default */ - if (LTC_ASN1_IS_TYPE(loptseq, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(loptseq->child, LTC_ASN1_OBJECT_IDENTIFIER)) { - /* this sequence is optional */ - hmacid = _oid_to_id(loptseq->child->data, loptseq->child->size); - } - if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_OCTET_STRING)) { - /* DES-CBC + DES_EDE3_CBC */ - iv = lenc->next->data; - iv_size = lenc->next->size; - } - else if (LTC_ASN1_IS_TYPE(lenc->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lenc->next->child, LTC_ASN1_INTEGER) && - LTC_ASN1_IS_TYPE(lenc->next->child->next, LTC_ASN1_OCTET_STRING)) { - /* RC2-CBC is a bit special */ - iv = lenc->next->child->next->data; - iv_size = lenc->next->child->next->size; - arg = mp_get_int(lenc->next->child->data); - } - err = _pbes2_pbkdf2_decrypt(enc_data, enc_size, pwd, pwdlen, salt, salt_size, iv, iv_size, iter, hmacid, encid, arg, dec_data, &dec_size); - if (err != CRYPT_OK) goto LBL_DONE; - } - else { - /* non-PBKDF2 algorithms are not supported */ - err = CRYPT_INVALID_PACKET; - goto LBL_DONE; - } - } - else { - /* unsupported encryption */ - err = CRYPT_INVALID_PACKET; - goto LBL_DONE; - } - der_free_sequence_flexi(l); - l = NULL; - err = der_decode_sequence_flexi(dec_data, &dec_size, &l); - if (err != CRYPT_OK) goto LBL_DONE; - *decoded_list = l; - } - else { - /* not encrypted */ - err = CRYPT_OK; - *decoded_list = l; - } + const ltc_asn1_list *cur; + if (flexi->type != LTC_ASN1_SEQUENCE) + return CRYPT_INVALID_PACKET; + cur = flexi->child; + while(check->t != LTC_ASN1_EOL) { + if (!LTC_ASN1_IS_TYPE(cur, check->t)) + return CRYPT_INVALID_PACKET; + if (check->pp != NULL) *check->pp = (ltc_asn1_list*)cur; + cur = cur->next; + check++; } - -LBL_DONE: - if (dec_data) XFREE(dec_data); - return err; + return CRYPT_OK; } /* NOTE: _der_decode_pkcs8_flexi & related stuff can be shared with rsa_import_pkcs8() */ @@ -359,108 +46,108 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, ecc_key *key) { void *a, *b, *gx, *gy; - unsigned long len, cofactor; - oid_st ecoid; + unsigned long len, cofactor, n; + const char *pka_ec_oid; int err; char OID[256]; const ltc_ecc_curve *curve; ltc_asn1_list *p = NULL, *l = NULL; + der_flexi_check flexi_should[7]; + ltc_asn1_list *seq, *priv_key; LTC_ARGCHK(in != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(ltc_mp.name != NULL); /* get EC alg oid */ - err = pk_get_oid(PKA_EC, &ecoid); + err = pk_get_oid(PKA_EC, &pka_ec_oid); if (err != CRYPT_OK) return err; /* init key */ err = mp_init_multi(&a, &b, &gx, &gy, NULL); if (err != CRYPT_OK) return err; - if ((err = _der_decode_pkcs8_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) { - if (l->type == LTC_ASN1_SEQUENCE && - LTC_ASN1_IS_TYPE(l->child, LTC_ASN1_INTEGER) && - LTC_ASN1_IS_TYPE(l->child->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(l->child->next->child, LTC_ASN1_OBJECT_IDENTIFIER) && - LTC_ASN1_IS_TYPE(l->child->next->next, LTC_ASN1_OCTET_STRING)) { - ltc_asn1_list *lseq = l->child->next; - ltc_asn1_list *lpri = l->child->next->next; - ltc_asn1_list *lecoid = l->child->next->child; - if ((lecoid->size != ecoid.OIDlen) || - XMEMCMP(ecoid.OID, lecoid->data, ecoid.OIDlen * sizeof(ecoid.OID[0]))) { - err = CRYPT_PK_INVALID_TYPE; - goto LBL_DONE; - } + if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) { + + /* Setup for basic structure */ + n=0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, NULL); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &seq); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &priv_key); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); - if (LTC_ASN1_IS_TYPE(lseq->child->next, LTC_ASN1_OBJECT_IDENTIFIER)) { + if (((err = _der_flexi_sequence_cmp(l, flexi_should)) == CRYPT_OK) && + (pk_oid_cmp_with_asn1(pka_ec_oid, seq->child) == CRYPT_OK)) { + ltc_asn1_list *version, *field, *point, *point_g, *order, *p_cofactor; + + /* Setup for CASE 2 */ + n=0; + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &version); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &field); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_SEQUENCE, &point); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_OCTET_STRING, &point_g); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &order); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n++, LTC_ASN1_INTEGER, &p_cofactor); + LTC_SET_DER_FLEXI_CHECK(flexi_should, n, LTC_ASN1_EOL, NULL); + + if (LTC_ASN1_IS_TYPE(seq->child->next, LTC_ASN1_OBJECT_IDENTIFIER)) { /* CASE 1: curve by OID (AKA short variant): - * 0:d=0 hl=2 l= 100 cons: SEQUENCE - * 2:d=1 hl=2 l= 1 prim: INTEGER :00 - * 5:d=1 hl=2 l= 16 cons: SEQUENCE (== *lseq) - * 7:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey - * 16:d=2 hl=2 l= 5 prim: OBJECT :secp256k1 (== 1.3.132.0.10) - * 23:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== privatekey) + * 0:d=0 hl=2 l= 100 cons: SEQUENCE + * 2:d=1 hl=2 l= 1 prim: INTEGER :00 + * 5:d=1 hl=2 l= 16 cons: SEQUENCE (== *seq) + * 7:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey + * 16:d=2 hl=2 l= 5 prim: OBJECT :(== *curve_oid (e.g. secp256k1 (== 1.3.132.0.10))) + * 23:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== *priv_key) */ - ltc_asn1_list *loid = lseq->child->next; + ltc_asn1_list *curve_oid = seq->child->next; len = sizeof(OID); - if ((err = pk_oid_num_to_str(loid->data, loid->size, OID, &len)) != CRYPT_OK) { goto LBL_DONE; } + if ((err = pk_oid_num_to_str(curve_oid->data, curve_oid->size, OID, &len)) != CRYPT_OK) { goto LBL_DONE; } if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto LBL_DONE; } if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto LBL_DONE; } } - else if (LTC_ASN1_IS_TYPE(lseq->child->next, LTC_ASN1_SEQUENCE)) { + else if ((err = _der_flexi_sequence_cmp(seq->child->next, flexi_should)) == CRYPT_OK) { /* CASE 2: explicit curve parameters (AKA long variant): * 0:d=0 hl=3 l= 227 cons: SEQUENCE * 3:d=1 hl=2 l= 1 prim: INTEGER :00 - * 6:d=1 hl=3 l= 142 cons: SEQUENCE (== *lseq) + * 6:d=1 hl=3 l= 142 cons: SEQUENCE (== *seq) * 9:d=2 hl=2 l= 7 prim: OBJECT :id-ecPublicKey - * 18:d=2 hl=3 l= 130 cons: SEQUENCE (== *lcurve) + * 18:d=2 hl=3 l= 130 cons: SEQUENCE * 21:d=3 hl=2 l= 1 prim: INTEGER :01 - * 24:d=3 hl=2 l= 44 cons: SEQUENCE (== *lfield) + * 24:d=3 hl=2 l= 44 cons: SEQUENCE (== *field) * 26:d=4 hl=2 l= 7 prim: OBJECT :prime-field - * 35:d=4 hl=2 l= 33 prim: INTEGER :(== curve.prime) - * 70:d=3 hl=2 l= 6 cons: SEQUENCE (== *lpoint) + * 35:d=4 hl=2 l= 33 prim: INTEGER :(== *prime / curve.prime) + * 70:d=3 hl=2 l= 6 cons: SEQUENCE (== *point) * 72:d=4 hl=2 l= 1 prim: OCTET STRING :bytes (== curve.A) * 75:d=4 hl=2 l= 1 prim: OCTET STRING :bytes (== curve.B) - * 78:d=3 hl=2 l= 33 prim: OCTET STRING :bytes (== curve.G-point) - * 113:d=3 hl=2 l= 33 prim: INTEGER :(== curve.order) + * 78:d=3 hl=2 l= 33 prim: OCTET STRING :bytes (== *g_point / curve.G-point) + * 113:d=3 hl=2 l= 33 prim: INTEGER :(== *order / curve.order) * 148:d=3 hl=2 l= 1 prim: INTEGER :(== curve.cofactor) - * 151:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== privatekey) + * 151:d=1 hl=2 l= 77 prim: OCTET STRING :bytes (== *priv_key) */ - ltc_asn1_list *lcurve = lseq->child->next; - if (LTC_ASN1_IS_TYPE(lcurve->child, LTC_ASN1_INTEGER) && - LTC_ASN1_IS_TYPE(lcurve->child->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lcurve->child->next->next, LTC_ASN1_SEQUENCE) && - LTC_ASN1_IS_TYPE(lcurve->child->next->next->next, LTC_ASN1_OCTET_STRING) && - LTC_ASN1_IS_TYPE(lcurve->child->next->next->next->next, LTC_ASN1_INTEGER) && - LTC_ASN1_IS_TYPE(lcurve->child->next->next->next->next->next, LTC_ASN1_INTEGER)) { - - ltc_asn1_list *lfield = lcurve->child->next; - ltc_asn1_list *lpoint = lcurve->child->next->next; - ltc_asn1_list *lg = lcurve->child->next->next->next; - ltc_asn1_list *lorder = lcurve->child->next->next->next->next; - cofactor = mp_get_int(lcurve->child->next->next->next->next->next->data); + if (mp_get_int(version->data) != 1) { + goto LBL_DONE; + } + cofactor = mp_get_int(p_cofactor->data); - if (LTC_ASN1_IS_TYPE(lfield->child, LTC_ASN1_OBJECT_IDENTIFIER) && - LTC_ASN1_IS_TYPE(lfield->child->next, LTC_ASN1_INTEGER) && - LTC_ASN1_IS_TYPE(lpoint->child, LTC_ASN1_OCTET_STRING) && - LTC_ASN1_IS_TYPE(lpoint->child->next, LTC_ASN1_OCTET_STRING)) { + if (LTC_ASN1_IS_TYPE(field->child, LTC_ASN1_OBJECT_IDENTIFIER) && + LTC_ASN1_IS_TYPE(field->child->next, LTC_ASN1_INTEGER) && + LTC_ASN1_IS_TYPE(point->child, LTC_ASN1_OCTET_STRING) && + LTC_ASN1_IS_TYPE(point->child->next, LTC_ASN1_OCTET_STRING)) { - ltc_asn1_list *lprime = lfield->child->next; - if ((err = mp_read_unsigned_bin(a, lpoint->child->data, lpoint->child->size)) != CRYPT_OK) { - goto LBL_DONE; - } - if ((err = mp_read_unsigned_bin(b, lpoint->child->next->data, lpoint->child->next->size)) != CRYPT_OK) { - goto LBL_DONE; - } - if ((err = ltc_ecc_import_point(lg->data, lg->size, lprime->data, a, b, gx, gy)) != CRYPT_OK) { - goto LBL_DONE; - } - if ((err = ecc_set_curve_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { - goto LBL_DONE; - } + ltc_asn1_list *prime = field->child->next; + if ((err = mp_read_unsigned_bin(a, point->child->data, point->child->size)) != CRYPT_OK) { + goto LBL_DONE; + } + if ((err = mp_read_unsigned_bin(b, point->child->next->data, point->child->next->size)) != CRYPT_OK) { + goto LBL_DONE; + } + if ((err = ltc_ecc_import_point(point_g->data, point_g->size, prime->data, a, b, gx, gy)) != CRYPT_OK) { + goto LBL_DONE; + } + if ((err = ecc_set_curve_from_mpis(a, b, prime->data, order->data, gx, gy, cofactor, key)) != CRYPT_OK) { + goto LBL_DONE; } } } @@ -470,8 +157,8 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen, } /* load private key value 'k' */ - len = lpri->size; - if ((err = der_decode_sequence_flexi(lpri->data, &len, &p)) == CRYPT_OK) { + len = priv_key->size; + if ((err = der_decode_sequence_flexi(priv_key->data, &len, &p)) == CRYPT_OK) { if (p->type == LTC_ASN1_SEQUENCE && LTC_ASN1_IS_TYPE(p->child, LTC_ASN1_INTEGER) && LTC_ASN1_IS_TYPE(p->child->next, LTC_ASN1_OCTET_STRING)) { diff --git a/src/ltc/pk/ecc/ecc_recover_key.c b/src/ltc/pk/ecc/ecc_recover_key.c new file mode 100644 index 00000000..25562a23 --- /dev/null +++ b/src/ltc/pk/ecc/ecc_recover_key.c @@ -0,0 +1,249 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_MECC + +#ifdef LTC_ECC_SHAMIR + +/** + @file ecc_recover_key.c + ECC Crypto, Russ Williams +*/ + +/** + Recover ECC public key from signature and hash + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param recid The recovery ID ("v"), can be -1 if signature contains it + @param sigformat The format of the signature (ecc_signature_type) + @param key The recovered public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_recover_key(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + int recid, ecc_signature_type sigformat, ecc_key *key) +{ + ecc_point *mG = NULL, *mQ = NULL, *mR = NULL; + void *p, *m, *a, *b; + void *r, *s, *v, *w, *t1, *t2, *u1, *u2, *v1, *v2, *e, *x, *y, *a_plus3; + void *mu = NULL, *ma = NULL; + void *mp = NULL; + int err; + unsigned long pbits, pbytes, i, shift_right; + unsigned char ch, buf[MAXBLOCKSIZE]; + + LTC_ARGCHK(sig != NULL); + LTC_ARGCHK(hash != NULL); + LTC_ARGCHK(key != NULL); + + /* BEWARE: requires sqrtmod_prime */ + if (ltc_mp.sqrtmod_prime == NULL) { + return CRYPT_ERROR; + } + + /* allocate ints */ + if ((err = mp_init_multi(&r, &s, &v, &w, &t1, &t2, &u1, &u2, &v1, &v2, &e, &x, &y, &a_plus3, NULL)) != CRYPT_OK) { + return err; + } + + p = key->dp.order; + m = key->dp.prime; + a = key->dp.A; + b = key->dp.B; + if ((err = mp_add_d(a, 3, a_plus3)) != CRYPT_OK) { + goto error; + } + + /* allocate points */ + mG = ltc_ecc_new_point(); + mQ = ltc_ecc_new_point(); + mR = ltc_ecc_new_point(); + if (mR == NULL || mQ == NULL || mG == NULL) { + err = CRYPT_MEM; + goto error; + } + + if (sigformat == LTC_ECCSIG_ANSIX962) { + /* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */ + if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } + } + else if (sigformat == LTC_ECCSIG_RFC7518) { + /* RFC7518 format - raw (r,s) */ + i = mp_unsigned_bin_size(key->dp.order); + if (siglen != (2*i)) { + err = CRYPT_INVALID_PACKET; + goto error; + } + if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, i)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+i, i)) != CRYPT_OK) { goto error; } + } + else if (sigformat == LTC_ECCSIG_ETH27) { + /* Ethereum (v,r,s) format */ + if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || + key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + /* Only valid for secp256k1 - OID 1.3.132.0.10 */ + err = CRYPT_ERROR; goto error; + } + if (siglen != 65) { /* Only secp256k1 curves use this format, so must be 65 bytes long */ + err = CRYPT_INVALID_PACKET; + goto error; + } + i = (unsigned long)sig[64]; + if ((i>=27) && (i<31)) i -= 27; /* Ethereum adds 27 to recovery ID */ + if (recid >= 0 && ((unsigned long)recid != i)) { + /* Recovery ID specified, but doesn't match signature */ + err = CRYPT_INVALID_PACKET; + goto error; + } + recid = i; + if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, 32)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+32, 32)) != CRYPT_OK) { goto error; } + } + else { + /* Unknown signature format */ + err = CRYPT_ERROR; + goto error; + } + + if (recid < 0 || (unsigned long)recid >= 2*(key->dp.cofactor+1)) { + /* Recovery ID is out of range, reject it */ + err = CRYPT_INVALID_ARG; + goto error; + } + + /* check for zero */ + if (mp_cmp_d(r, 0) != LTC_MP_GT || mp_cmp_d(s, 0) != LTC_MP_GT || + mp_cmp(r, p) != LTC_MP_LT || mp_cmp(s, p) != LTC_MP_LT) { + err = CRYPT_INVALID_PACKET; + goto error; + } + + /* read hash - truncate if needed */ + pbits = mp_count_bits(p); + pbytes = (pbits+7) >> 3; + if (pbits > hashlen*8) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, hashlen)) != CRYPT_OK) { goto error; } + } + else if (pbits % 8 == 0) { + if ((err = mp_read_unsigned_bin(e, (unsigned char *)hash, pbytes)) != CRYPT_OK) { goto error; } + } + else { + shift_right = 8 - pbits % 8; + for (i=0, ch=0; i<pbytes; i++) { + buf[i] = ch; + ch = (hash[i] << (8-shift_right)); + buf[i] = buf[i] ^ (hash[i] >> shift_right); + } + if ((err = mp_read_unsigned_bin(e, (unsigned char *)buf, pbytes)) != CRYPT_OK) { goto error; } + } + + /* decompress point from r=(x mod p) - BEWARE: requires sqrtmod_prime */ + /* x = r + p*(recid/2) */ + if ((err = mp_set(x, recid/2)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(p, x, m, x)) != CRYPT_OK) { goto error; } + if ((err = mp_add(x, r, x)) != CRYPT_OK) { goto error; } + /* compute x^3 */ + if ((err = mp_sqr(x, t1)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(t1, x, m, t1)) != CRYPT_OK) { goto error; } + /* compute x^3 + a*x */ + if ((err = mp_mulmod(a, x, m, t2)) != CRYPT_OK) { goto error; } + if ((err = mp_add(t1, t2, t1)) != CRYPT_OK) { goto error; } + /* compute x^3 + a*x + b */ + if ((err = mp_add(t1, b, t1)) != CRYPT_OK) { goto error; } + /* compute sqrt(x^3 + a*x + b) */ + if ((err = mp_sqrtmod_prime(t1, m, t2)) != CRYPT_OK) { goto error; } + + /* fill in mR */ + if ((err = mp_copy(x, mR->x)) != CRYPT_OK) { goto error; } + if ((mp_isodd(t2) && (recid%2)) || (!mp_isodd(t2) && !(recid%2))) { + if ((err = mp_mod(t2, m, mR->y)) != CRYPT_OK) { goto error; } + } + else { + if ((err = mp_submod(m, t2, m, mR->y)) != CRYPT_OK) { goto error; } + } + if ((err = mp_set(mR->z, 1)) != CRYPT_OK) { goto error; } + + /* w = r^-1 mod n */ + if ((err = mp_invmod(r, p, w)) != CRYPT_OK) { goto error; } + /* v1 = sw */ + if ((err = mp_mulmod(s, w, p, v1)) != CRYPT_OK) { goto error; } + /* v2 = -ew */ + if ((err = mp_mulmod(e, w, p, v2)) != CRYPT_OK) { goto error; } + if ((err = mp_submod(p, v2, p, v2)) != CRYPT_OK) { goto error; } + + /* w = s^-1 mod n */ + if ((err = mp_invmod(s, p, w)) != CRYPT_OK) { goto error; } + /* u1 = ew */ + if ((err = mp_mulmod(e, w, p, u1)) != CRYPT_OK) { goto error; } + /* u2 = rw */ + if ((err = mp_mulmod(r, w, p, u2)) != CRYPT_OK) { goto error; } + + /* find mG */ + if ((err = ltc_ecc_copy_point(&key->dp.base, mG)) != CRYPT_OK) { goto error; } + + /* find the montgomery mp */ + if ((err = mp_montgomery_setup(m, &mp)) != CRYPT_OK) { goto error; } + + /* for curves with a == -3 keep ma == NULL */ + if (mp_cmp(a_plus3, m) != LTC_MP_EQ) { + if ((err = mp_init_multi(&mu, &ma, NULL)) != CRYPT_OK) { goto error; } + if ((err = mp_montgomery_normalization(mu, m)) != CRYPT_OK) { goto error; } + if ((err = mp_mulmod(a, mu, m, ma)) != CRYPT_OK) { goto error; } + } + + /* recover mQ from mR */ + /* compute v1*mR + v2*mG = mQ using Shamir's trick */ + if ((err = ltc_mp.ecc_mul2add(mR, v1, mG, v2, mQ, ma, m)) != CRYPT_OK) { goto error; } + + /* compute u1*mG + u2*mQ = mG using Shamir's trick */ + if ((err = ltc_mp.ecc_mul2add(mG, u1, mQ, u2, mG, ma, m)) != CRYPT_OK) { goto error; } + + /* v = X_x1 mod n */ + if ((err = mp_mod(mG->x, p, v)) != CRYPT_OK) { goto error; } + + /* does v == r */ + if (mp_cmp(v, r) == LTC_MP_EQ) { + /* found public key which verifies signature */ + if ((err = ltc_ecc_copy_point(mQ, &key->pubkey)) != CRYPT_OK) { goto error; } + /* point on the curve + other checks */ + if ((err = ltc_ecc_verify_key(key)) != CRYPT_OK) { goto error; } + + key->type = PK_PUBLIC; + + err = CRYPT_OK; + } + else { + /* not found - recid is wrong or we're unable to calculate public key for some other reason */ + err = CRYPT_INVALID_ARG; + } + +error: + if (ma != NULL) mp_clear(ma); + if (mu != NULL) mp_clear(mu); + if (mp != NULL) mp_montgomery_free(mp); + if (mR != NULL) ltc_ecc_del_point(mR); + if (mQ != NULL) ltc_ecc_del_point(mQ); + if (mG != NULL) ltc_ecc_del_point(mG); + mp_clear_multi(a_plus3, y, x, e, v2, v1, u2, u1, t2, t1, w, v, s, r, NULL); + return err; +} + +#endif +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/ecc/ecc_sign_hash.c b/src/ltc/pk/ecc/ecc_sign_hash.c index 3302b077..6764dae6 100644 --- a/src/ltc/pk/ecc/ecc_sign_hash.c +++ b/src/ltc/pk/ecc/ecc_sign_hash.c @@ -16,12 +16,27 @@ ECC Crypto, Tom St Denis */ -static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key, int sigformat) +/** + Sign a message digest + @param in The message digest to sign + @param inlen The length of the digest + @param out [out] The destination for the signature + @param outlen [in/out] The max size and resulting size of the signature + @param prng An active PRNG state + @param wprng The index of the PRNG you wish to use + @param sigformat The format of the signature to generate (ecc_signature_type) + @param recid [out] The recovery ID for this signature (optional) + @param key A private ECC key + @return CRYPT_OK if successful +*/ +int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen, + unsigned char *out, unsigned long *outlen, + prng_state *prng, int wprng, ecc_signature_type sigformat, + int *recid, const ecc_key *key) { ecc_key pubkey; void *r, *s, *e, *p, *b; + int v = 0; int err, max_iterations = LTC_PK_MAX_RETRIES; unsigned long pbits, pbytes, i, shift_right; unsigned char ch, buf[MAXBLOCKSIZE]; @@ -69,6 +84,18 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, /* find r = x1 mod n */ if ((err = mp_mod(pubkey.pubkey.x, p, r)) != CRYPT_OK) { goto error; } + if (recid || sigformat==LTC_ECCSIG_ETH27) { + /* find recovery ID (if needed) */ + v = 0; + if (mp_copy(pubkey.pubkey.x, s) != CRYPT_OK) { goto error; } + while (mp_cmp_d(s, 0) == LTC_MP_GT && mp_cmp(s, p) != LTC_MP_LT) { + /* Compute x1 div n... this will almost never be reached for curves with order 1 */ + v += 2; + if ((err = mp_sub(s, p, s)) != CRYPT_OK) { goto error; } + } + if (mp_isodd(pubkey.pubkey.y)) v += 1; + } + if (mp_iszero(r) == LTC_MP_YES) { ecc_free(&pubkey); } else { @@ -92,8 +119,17 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, goto errnokey; } - if (sigformat == 1) { - /* RFC7518 format */ + if (recid) *recid = v; + + if (sigformat == LTC_ECCSIG_ANSIX962) { + /* store as ASN.1 SEQUENCE { r, s -- integer } */ + err = der_encode_sequence_multi(out, outlen, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL); + } + else if (sigformat == LTC_ECCSIG_RFC7518) { + /* RFC7518 format - raw (r,s) */ if (*outlen < 2*pbytes) { err = CRYPT_MEM; goto errnokey; } zeromem(out, 2*pbytes); i = mp_unsigned_bin_size(r); @@ -103,13 +139,29 @@ static int _ecc_sign_hash(const unsigned char *in, unsigned long inlen, *outlen = 2*pbytes; err = CRYPT_OK; } + else if (sigformat == LTC_ECCSIG_ETH27) { + /* Ethereum (v,r,s) format */ + if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || + key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + /* Only valid for secp256k1 - OID 1.3.132.0.10 */ + err = CRYPT_ERROR; goto errnokey; + } + if (*outlen < 65) { err = CRYPT_MEM; goto errnokey; } + zeromem(out, 65); + i = mp_unsigned_bin_size(r); + if ((err = mp_to_unsigned_bin(r, out + 32 - i)) != CRYPT_OK) { goto errnokey; } + i = mp_unsigned_bin_size(s); + if ((err = mp_to_unsigned_bin(s, out + 64 - i)) != CRYPT_OK) { goto errnokey; } + out[64] = (unsigned char)(v + 27); /* Recovery ID is 27/28 for Ethereum */ + *outlen = 65; + err = CRYPT_OK; + } else { - /* store as ASN.1 SEQUENCE { r, s -- integer } */ - err = der_encode_sequence_multi(out, outlen, - LTC_ASN1_INTEGER, 1UL, r, - LTC_ASN1_INTEGER, 1UL, s, - LTC_ASN1_EOL, 0UL, NULL); + /* Unknown signature format */ + err = CRYPT_ERROR; + goto error; } + goto errnokey; error: ecc_free(&pubkey); @@ -118,42 +170,6 @@ errnokey: return err; } -/** - Sign a message digest - @param in The message digest to sign - @param inlen The length of the digest - @param out [out] The destination for the signature - @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param key A private ECC key - @return CRYPT_OK if successful -*/ -int ecc_sign_hash(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) -{ - return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 0); -} - -/** - Sign a message digest in RFC7518 format - @param in The message digest to sign - @param inlen The length of the digest - @param out [out] The destination for the signature - @param outlen [in/out] The max size and resulting size of the signature - @param prng An active PRNG state - @param wprng The index of the PRNG you wish to use - @param key A private ECC key - @return CRYPT_OK if successful -*/ -int ecc_sign_hash_rfc7518(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, - prng_state *prng, int wprng, const ecc_key *key) -{ - return _ecc_sign_hash(in, inlen, out, outlen, prng, wprng, key, 1); -} - #endif /* ref: $Format:%D$ */ diff --git a/src/ltc/pk/ecc/ecc_verify_hash.c b/src/ltc/pk/ecc/ecc_verify_hash.c index f2a58940..d18ef934 100644 --- a/src/ltc/pk/ecc/ecc_verify_hash.c +++ b/src/ltc/pk/ecc/ecc_verify_hash.c @@ -16,12 +16,24 @@ ECC Crypto, Tom St Denis */ -static int _ecc_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key, int sigformat) +/** + Verify an ECC signature in RFC7518 format + @param sig The signature to verify + @param siglen The length of the signature (octets) + @param hash The hash (message digest) that was signed + @param hashlen The length of the hash (octets) + @param sigformat The format of the signature (ecc_signature_type) + @param stat Result of signature, 1==valid, 0==invalid + @param key The corresponding public ECC key + @return CRYPT_OK if successful (even if the signature is not valid) +*/ +int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen, + const unsigned char *hash, unsigned long hashlen, + ecc_signature_type sigformat, int *stat, const ecc_key *key) { - ecc_point *mG = NULL, *mQ = NULL; - void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *a_plus3 = NULL, *mu = NULL, *ma = NULL; + ecc_point *mG = NULL, *mQ = NULL; + void *r, *s, *v, *w, *u1, *u2, *e, *p, *m, *a, *a_plus3; + void *mu = NULL, *ma = NULL; void *mp = NULL; int err; unsigned long pbits, pbytes, i, shift_right; @@ -55,22 +67,41 @@ static int _ecc_verify_hash(const unsigned char *sig, unsigned long siglen, goto error; } - if (sigformat == 1) { - /* RFC7518 format */ - if ((siglen % 2) == 1) { + if (sigformat == LTC_ECCSIG_ANSIX962) { + /* ANSI X9.62 format - ASN.1 encoded SEQUENCE{ INTEGER(r), INTEGER(s) } */ + if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, + LTC_ASN1_INTEGER, 1UL, r, + LTC_ASN1_INTEGER, 1UL, s, + LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } + } + else if (sigformat == LTC_ECCSIG_RFC7518) { + /* RFC7518 format - raw (r,s) */ + i = mp_unsigned_bin_size(key->dp.order); + if (siglen != (2*i)) { err = CRYPT_INVALID_PACKET; goto error; } - i = siglen / 2; if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, i)) != CRYPT_OK) { goto error; } if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+i, i)) != CRYPT_OK) { goto error; } } + else if (sigformat == LTC_ECCSIG_ETH27) { + /* Ethereum (v,r,s) format */ + if (key->dp.oidlen != 5 || key->dp.oid[0] != 1 || key->dp.oid[1] != 3 || + key->dp.oid[2] != 132 || key->dp.oid[3] != 0 || key->dp.oid[4] != 10) { + /* Only valid for secp256k1 - OID 1.3.132.0.10 */ + err = CRYPT_ERROR; goto error; + } + if (siglen != 65) { /* Only secp256k1 curves use this format, so must be 65 bytes long */ + err = CRYPT_INVALID_PACKET; + goto error; + } + if ((err = mp_read_unsigned_bin(r, (unsigned char *)sig, 32)) != CRYPT_OK) { goto error; } + if ((err = mp_read_unsigned_bin(s, (unsigned char *)sig+32, 32)) != CRYPT_OK) { goto error; } + } else { - /* ASN.1 format */ - if ((err = der_decode_sequence_multi_ex(sig, siglen, LTC_DER_SEQ_SEQUENCE | LTC_DER_SEQ_STRICT, - LTC_ASN1_INTEGER, 1UL, r, - LTC_ASN1_INTEGER, 1UL, s, - LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) { goto error; } + /* Unknown signature format */ + err = CRYPT_ERROR; + goto error; } /* check for zero */ @@ -153,46 +184,10 @@ error: if (mu != NULL) mp_clear(mu); if (ma != NULL) mp_clear(ma); mp_clear_multi(r, s, v, w, u1, u2, e, a_plus3, NULL); - if (mp != NULL) { - mp_montgomery_free(mp); - } + if (mp != NULL) mp_montgomery_free(mp); return err; } -/** - Verify an ECC signature - @param sig The signature to verify - @param siglen The length of the signature (octets) - @param hash The hash (message digest) that was signed - @param hashlen The length of the hash (octets) - @param stat Result of signature, 1==valid, 0==invalid - @param key The corresponding public ECC key - @return CRYPT_OK if successful (even if the signature is not valid) -*/ -int ecc_verify_hash(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key) -{ - return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 0); -} - -/** - Verify an ECC signature in RFC7518 format - @param sig The signature to verify - @param siglen The length of the signature (octets) - @param hash The hash (message digest) that was signed - @param hashlen The length of the hash (octets) - @param stat Result of signature, 1==valid, 0==invalid - @param key The corresponding public ECC key - @return CRYPT_OK if successful (even if the signature is not valid) -*/ -int ecc_verify_hash_rfc7518(const unsigned char *sig, unsigned long siglen, - const unsigned char *hash, unsigned long hashlen, - int *stat, const ecc_key *key) -{ - return _ecc_verify_hash(sig, siglen, hash, hashlen, stat, key, 1); -} - #endif /* ref: $Format:%D$ */ diff --git a/src/ltc/pk/rsa/rsa_import_pkcs8.c b/src/ltc/pk/rsa/rsa_import_pkcs8.c index 4deab5ba..04f38507 100644 --- a/src/ltc/pk/rsa/rsa_import_pkcs8.c +++ b/src/ltc/pk/rsa/rsa_import_pkcs8.c @@ -56,9 +56,9 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, unsigned char *buf1 = NULL, *buf2 = NULL; unsigned long buf1len, buf2len; unsigned long oid[16]; - oid_st rsaoid; + const char *rsaoid; ltc_asn1_list alg_seq[2], top_seq[3]; - ltc_asn1_list alg_seq_e[2], key_seq_e[2], top_seq_e[2]; + ltc_asn1_list *l = NULL; unsigned char *decrypted = NULL; unsigned long decryptedlen; @@ -83,25 +83,11 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, if (err != CRYPT_OK) { goto LBL_FREE2; } /* try to decode encrypted priv key */ - LTC_SET_ASN1(key_seq_e, 0, LTC_ASN1_OCTET_STRING, buf1, buf1len); - LTC_SET_ASN1(key_seq_e, 1, LTC_ASN1_INTEGER, iter, 1UL); - LTC_SET_ASN1(alg_seq_e, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); - LTC_SET_ASN1(alg_seq_e, 1, LTC_ASN1_SEQUENCE, key_seq_e, 2UL); - LTC_SET_ASN1(top_seq_e, 0, LTC_ASN1_SEQUENCE, alg_seq_e, 2UL); - LTC_SET_ASN1(top_seq_e, 1, LTC_ASN1_OCTET_STRING, buf2, buf2len); - err=der_decode_sequence(in, inlen, top_seq_e, 2UL); - if (err == CRYPT_OK) { - LTC_UNUSED_PARAM(passwd); - LTC_UNUSED_PARAM(passwdlen); - /* XXX: TODO encrypted pkcs8 not implemented yet */ - /* fprintf(stderr, "decrypt: iter=%ld salt.len=%ld encdata.len=%ld\n", mp_get_int(iter), key_seq_e[0].size, top_seq_e[1].size); */ - err = CRYPT_PK_INVALID_TYPE; + if ((err = pkcs8_decode_flexi(in, inlen, passwd, passwdlen, &l)) != CRYPT_OK) { goto LBL_ERR; } - else { - decrypted = (unsigned char *)in; - decryptedlen = inlen; - } + decrypted = l->data; + decryptedlen = l->size; /* try to decode unencrypted priv key */ LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL); @@ -113,9 +99,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, if (err != CRYPT_OK) { goto LBL_ERR; } /* check alg oid */ - if ((alg_seq[0].size != rsaoid.OIDlen) || - XMEMCMP(rsaoid.OID, alg_seq[0].data, rsaoid.OIDlen * sizeof(rsaoid.OID[0])) != 0) { - err = CRYPT_PK_INVALID_TYPE; + if ((err = pk_oid_cmp_with_asn1(rsaoid, &alg_seq[0])) != CRYPT_OK) { goto LBL_ERR; } @@ -138,6 +122,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen, LBL_ERR: rsa_free(key); LBL_FREE2: + if (l) der_free_sequence_flexi(l); mp_clear_multi(iter, zero, NULL); XFREE(buf2); LBL_FREE1: diff --git a/src/ltc/stream/chacha/chacha_memory.c b/src/ltc/stream/chacha/chacha_memory.c new file mode 100644 index 00000000..96ecf8b4 --- /dev/null +++ b/src/ltc/stream/chacha/chacha_memory.c @@ -0,0 +1,51 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_CHACHA + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with ChaCha + @param key The key + @param keylen The key length + @param iv The initial vector + @param ivlen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param rounds The number of rounds + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int chacha_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *iv, unsigned long ivlen, ulong64 counter, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout) +{ + chacha_state st; + int err; + + LTC_ARGCHK(ivlen <= 8 || counter < 4294967296); /* 2**32 */ + + if ((err = chacha_setup(&st, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY; + if (ivlen > 8) { + if ((err = chacha_ivctr32(&st, iv, ivlen, counter)) != CRYPT_OK) goto WIPE_KEY; + } else { + if ((err = chacha_ivctr64(&st, iv, ivlen, counter)) != CRYPT_OK) goto WIPE_KEY; + } + err = chacha_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + chacha_done(&st); + return err; +} + +#endif /* LTC_CHACHA */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/rabbit/rabbit.c b/src/ltc/stream/rabbit/rabbit.c index 7314d32b..9d7e0dff 100644 --- a/src/ltc/stream/rabbit/rabbit.c +++ b/src/ltc/stream/rabbit/rabbit.c @@ -421,19 +421,25 @@ int rabbit_test(void) if ((err = rabbit_crypt(&st, (unsigned char*)pt + 5, 29, out + 5)) != CRYPT_OK) return err; if ((err = rabbit_crypt(&st, (unsigned char*)pt + 34, 5, out + 34)) != CRYPT_OK) return err; if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV3", 1)) return CRYPT_FAIL_TESTVECTOR; + + /* --- Test 4 (crypt in a single call) ------------------------------------ */ + + if ((err = rabbit_memory(k, sizeof(k), iv, sizeof(iv), + (unsigned char*)pt, sizeof(pt), out)) != CRYPT_OK) return err; + if (compare_testvector(out, ptlen, ct, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR; /* use 'out' (ciphertext) in the next decryption test */ - /* --- Test 4 (decrypt ciphertext) ------------------------------------ */ + /* --- Test 5 (decrypt ciphertext) ------------------------------------ */ /* decrypt ct (out) and compare with pt (start with only setiv() to reset) */ if ((err = rabbit_setiv(&st, iv, sizeof(iv))) != CRYPT_OK) return err; if ((err = rabbit_crypt(&st, out, ptlen, out2)) != CRYPT_OK) return err; - if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV4", 1)) return CRYPT_FAIL_TESTVECTOR; + if (compare_testvector(out2, ptlen, pt, ptlen, "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR; - /* --- Test 5 (wipe state, incl key) ---------------------------------- */ + /* --- Test 6 (wipe state, incl key) ---------------------------------- */ if ((err = rabbit_done(&st)) != CRYPT_OK) return err; - if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV5", 1)) return CRYPT_FAIL_TESTVECTOR; + if (compare_testvector(&st, sizeof(st), nulls, sizeof(st), "RABBIT-TV6", 1)) return CRYPT_FAIL_TESTVECTOR; } diff --git a/src/ltc/stream/rabbit/rabbit_memory.c b/src/ltc/stream/rabbit/rabbit_memory.c new file mode 100644 index 00000000..b3969b60 --- /dev/null +++ b/src/ltc/stream/rabbit/rabbit_memory.c @@ -0,0 +1,50 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +/* The implementation is based on: + * chacha-ref.c version 20080118 + * Public domain from D. J. Bernstein + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_RABBIT + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Rabbit + @param key The key + @param keylen The key length + @param iv The initial vector + @param ivlen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int rabbit_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + rabbit_state st; + int err; + + if ((err = rabbit_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = rabbit_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = rabbit_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + rabbit_done(&st); + return err; +} + +#endif /* LTC_RABBIT */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/rc4/rc4_stream_memory.c b/src/ltc/stream/rc4/rc4_stream_memory.c new file mode 100644 index 00000000..25ce04c7 --- /dev/null +++ b/src/ltc/stream/rc4/rc4_stream_memory.c @@ -0,0 +1,41 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_RC4_STREAM + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with RC4 + @param key The key + @param keylen The key length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int rc4_stream_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + rc4_state st; + int err; + + if ((err = rc4_stream_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + err = rc4_stream_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + rc4_stream_done(&st); + return err; +} + +#endif /* LTC_RC4_STREAM */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/salsa20/salsa20_memory.c b/src/ltc/stream/salsa20/salsa20_memory.c new file mode 100644 index 00000000..ea08c700 --- /dev/null +++ b/src/ltc/stream/salsa20/salsa20_memory.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_SALSA20 + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Salsa20 + @param key The key + @param keylen The key length + @param iv The initial vector + @param ivlen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param rounds The number of rounds + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int salsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *iv, unsigned long ivlen, ulong64 counter, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout) +{ + salsa20_state st; + int err; + + if ((err = salsa20_setup(&st, key, keylen, rounds)) != CRYPT_OK) goto WIPE_KEY; + if ((err = salsa20_ivctr64(&st, iv, ivlen, counter)) != CRYPT_OK) goto WIPE_KEY; + err = salsa20_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + salsa20_done(&st); + return err; +} + +#endif /* LTC_SALSA20 */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/salsa20/xsalsa20_memory.c b/src/ltc/stream/salsa20/xsalsa20_memory.c new file mode 100644 index 00000000..73386a9e --- /dev/null +++ b/src/ltc/stream/salsa20/xsalsa20_memory.c @@ -0,0 +1,44 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_XSALSA20 + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with XSalsa20 + @param key The key + @param keylen The key length + @param nonce The initial vector + @param noncelen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param rounds The number of rounds + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int xsalsa20_memory(const unsigned char *key, unsigned long keylen, unsigned long rounds, + const unsigned char *nonce, unsigned long noncelen, + const unsigned char *datain, unsigned long datalen, unsigned char *dataout) +{ + salsa20_state st; + int err; + + if ((err = xsalsa20_setup(&st, key, keylen, nonce, noncelen, rounds)) != CRYPT_OK) goto WIPE_KEY; + err = salsa20_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + salsa20_done(&st); + return err; +} + +#endif /* LTC_XSALSA20 */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/sober128/sober128_stream_memory.c b/src/ltc/stream/sober128/sober128_stream_memory.c new file mode 100644 index 00000000..084d135e --- /dev/null +++ b/src/ltc/stream/sober128/sober128_stream_memory.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_SOBER128_STREAM + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with SOBER128 + @param key The key + @param keylen The key length + @param iv The initial vector + @param ivlen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int sober128_stream_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + sober128_state st; + int err; + + if ((err = sober128_stream_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = sober128_stream_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = sober128_stream_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + sober128_stream_done(&st); + return err; +} + +#endif /* LTC_SOBER128_STREAM */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/stream/sosemanuk/sosemanuk.c b/src/ltc/stream/sosemanuk/sosemanuk.c index 41371989..1c7cc27b 100644 --- a/src/ltc/stream/sosemanuk/sosemanuk.c +++ b/src/ltc/stream/sosemanuk/sosemanuk.c @@ -196,12 +196,12 @@ /* * Initialize Sosemanuk's state by providing a key. The key is an array of * 1 to 32 bytes. - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param key Key * @param keylen Length of key in bytes * @return CRYPT_OK on success */ -int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long keylen) +int sosemanuk_setup(sosemanuk_state *st, const unsigned char *key, unsigned long keylen) { /* * This key schedule is actually a truncated Serpent key schedule. @@ -216,10 +216,10 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long r2 = w ## o2; \ r3 = w ## o3; \ S(r0, r1, r2, r3, r4); \ - ss->kc[i ++] = r ## d0; \ - ss->kc[i ++] = r ## d1; \ - ss->kc[i ++] = r ## d2; \ - ss->kc[i ++] = r ## d3; \ + st->kc[i ++] = r ## d0; \ + st->kc[i ++] = r ## d1; \ + st->kc[i ++] = r ## d2; \ + st->kc[i ++] = r ## d3; \ } while (0) #define SKS0 SKS(S0, 4, 5, 6, 7, 1, 4, 2, 0) @@ -255,7 +255,7 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long ulong32 w0, w1, w2, w3, w4, w5, w6, w7; int i = 0; - LTC_ARGCHK(ss != NULL); + LTC_ARGCHK(st != NULL); LTC_ARGCHK(key != NULL); LTC_ARGCHK(keylen > 0 && keylen <= 32); @@ -329,22 +329,22 @@ int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long * encryptions/decryptions are to be performed with the same key and * sosemanuk_done() has not been called, only sosemanuk_setiv() need be called * to set the state. - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param iv Initialization vector * @param ivlen Length of iv in bytes * @return CRYPT_OK on success */ -int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ivlen) +int sosemanuk_setiv(sosemanuk_state *st, const unsigned char *iv, unsigned long ivlen) { /* * The Serpent key addition step. */ #define KA(zc, x0, x1, x2, x3) do { \ - x0 ^= ss->kc[(zc)]; \ - x1 ^= ss->kc[(zc) + 1]; \ - x2 ^= ss->kc[(zc) + 2]; \ - x3 ^= ss->kc[(zc) + 3]; \ + x0 ^= st->kc[(zc)]; \ + x1 ^= st->kc[(zc) + 1]; \ + x2 ^= st->kc[(zc) + 2]; \ + x3 ^= st->kc[(zc) + 3]; \ } while (0) /* @@ -374,7 +374,7 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ulong32 r0, r1, r2, r3, r4; unsigned char ivtmp[16] = {0}; - LTC_ARGCHK(ss != NULL); + LTC_ARGCHK(st != NULL); LTC_ARGCHK(ivlen <= 16); LTC_ARGCHK(iv != NULL || ivlen == 0); @@ -404,10 +404,10 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(36, S1, 1, 3, 2, 4, 0, 2, 1, 4, 3); FSS(40, S2, 2, 1, 4, 3, 0, 4, 3, 1, 0); FSS(44, S3, 4, 3, 1, 0, 2, 3, 1, 0, 2); - ss->s09 = r3; - ss->s08 = r1; - ss->s07 = r0; - ss->s06 = r2; + st->s09 = r3; + st->s08 = r1; + st->s07 = r0; + st->s06 = r2; FSS(48, S4, 3, 1, 0, 2, 4, 1, 4, 3, 2); FSS(52, S5, 1, 4, 3, 2, 0, 4, 2, 1, 3); @@ -415,10 +415,10 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(60, S7, 4, 2, 0, 1, 3, 3, 1, 2, 4); FSS(64, S0, 3, 1, 2, 4, 0, 1, 0, 2, 3); FSS(68, S1, 1, 0, 2, 3, 4, 2, 1, 3, 0); - ss->r1 = r2; - ss->s04 = r1; - ss->r2 = r3; - ss->s05 = r0; + st->r1 = r2; + st->s04 = r1; + st->r2 = r3; + st->s05 = r0; FSS(72, S2, 2, 1, 3, 0, 4, 3, 0, 1, 4); FSS(76, S3, 3, 0, 1, 4, 2, 0, 1, 4, 2); @@ -426,12 +426,12 @@ int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long FSS(84, S5, 1, 3, 0, 2, 4, 3, 2, 1, 0); FSS(88, S6, 3, 2, 1, 0, 4, 3, 2, 4, 1); FSF(92, S7, 3, 2, 4, 1, 0, 0, 1, 2, 3); - ss->s03 = r0; - ss->s02 = r1; - ss->s01 = r2; - ss->s00 = r3; + st->s03 = r0; + st->s02 = r1; + st->s01 = r2; + st->s00 = r3; - ss->ptr = sizeof(ss->buf); + st->ptr = sizeof(st->buf); #undef KA #undef FSS @@ -585,7 +585,7 @@ static const ulong32 mul_ia[] = { * Compute the next block of bits of output stream. This is equivalent * to one full rotation of the shift register. */ -static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) +static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *st) { /* * MUL_A(x) computes alpha * x (in F_{2^32}). @@ -656,24 +656,24 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) */ #define SRD(S, x0, x1, x2, x3, ooff) do { \ S(u0, u1, u2, u3, u4); \ - STORE32L(u ## x0 ^ v0, ss->buf + ooff); \ - STORE32L(u ## x1 ^ v1, ss->buf + ooff + 4); \ - STORE32L(u ## x2 ^ v2, ss->buf + ooff + 8); \ - STORE32L(u ## x3 ^ v3, ss->buf + ooff + 12); \ + STORE32L(u ## x0 ^ v0, st->buf + ooff); \ + STORE32L(u ## x1 ^ v1, st->buf + ooff + 4); \ + STORE32L(u ## x2 ^ v2, st->buf + ooff + 8); \ + STORE32L(u ## x3 ^ v3, st->buf + ooff + 12); \ } while (0) - ulong32 s00 = ss->s00; - ulong32 s01 = ss->s01; - ulong32 s02 = ss->s02; - ulong32 s03 = ss->s03; - ulong32 s04 = ss->s04; - ulong32 s05 = ss->s05; - ulong32 s06 = ss->s06; - ulong32 s07 = ss->s07; - ulong32 s08 = ss->s08; - ulong32 s09 = ss->s09; - ulong32 r1 = ss->r1; - ulong32 r2 = ss->r2; + ulong32 s00 = st->s00; + ulong32 s01 = st->s01; + ulong32 s02 = st->s02; + ulong32 s03 = st->s03; + ulong32 s04 = st->s04; + ulong32 s05 = st->s05; + ulong32 s06 = st->s06; + ulong32 s07 = st->s07; + ulong32 s08 = st->s08; + ulong32 s09 = st->s09; + ulong32 r1 = st->r1; + ulong32 r2 = st->r2; ulong32 u0, u1, u2, u3, u4; ulong32 v0, v1, v2, v3; @@ -703,18 +703,18 @@ static LTC_INLINE void _sosemanuk_internal(sosemanuk_state *ss) STEP(09, 00, 01, 02, 03, 04, 05, 06, 07, 08, v3, u3); SRD(S2, 2, 3, 1, 4, 64); - ss->s00 = s00; - ss->s01 = s01; - ss->s02 = s02; - ss->s03 = s03; - ss->s04 = s04; - ss->s05 = s05; - ss->s06 = s06; - ss->s07 = s07; - ss->s08 = s08; - ss->s09 = s09; - ss->r1 = r1; - ss->r2 = r2; + st->s00 = s00; + st->s01 = s01; + st->s02 = s02; + st->s03 = s03; + st->s04 = s04; + st->s05 = s05; + st->s06 = s06; + st->s07 = s07; + st->s08 = s08; + st->s09 = s09; + st->r1 = r1; + st->r2 = r2; } /* @@ -737,41 +737,41 @@ static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in * buffer, combined by XOR with the stream, and the result is written * in the "out" buffer. "in" and "out" must be either equal, or * reference distinct buffers (no partial overlap is allowed). - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param in Data in * @param inlen Length of data in bytes * @param out Data out * @return CRYPT_OK on success */ -int sosemanuk_crypt(sosemanuk_state *ss, +int sosemanuk_crypt(sosemanuk_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) { - LTC_ARGCHK(ss != NULL); + LTC_ARGCHK(st != NULL); LTC_ARGCHK(in != NULL); LTC_ARGCHK(out != NULL); - if (ss->ptr < (sizeof(ss->buf))) { - unsigned long rlen = (sizeof(ss->buf)) - ss->ptr; + if (st->ptr < (sizeof(st->buf))) { + unsigned long rlen = (sizeof(st->buf)) - st->ptr; if (rlen > inlen) { rlen = inlen; } - _xorbuf(ss->buf + ss->ptr, in, out, rlen); + _xorbuf(st->buf + st->ptr, in, out, rlen); in += rlen; out += rlen; inlen -= rlen; - ss->ptr += rlen; + st->ptr += rlen; } while (inlen > 0) { - _sosemanuk_internal(ss); - if (inlen >= sizeof(ss->buf)) { - _xorbuf(ss->buf, in, out, sizeof(ss->buf)); - in += sizeof(ss->buf); - out += sizeof(ss->buf); - inlen -= sizeof(ss->buf); + _sosemanuk_internal(st); + if (inlen >= sizeof(st->buf)) { + _xorbuf(st->buf, in, out, sizeof(st->buf)); + in += sizeof(st->buf); + out += sizeof(st->buf); + inlen -= sizeof(st->buf); } else { - _xorbuf(ss->buf, in, out, inlen); - ss->ptr = inlen; + _xorbuf(st->buf, in, out, inlen); + st->ptr = inlen; inlen = 0; } } @@ -783,29 +783,29 @@ int sosemanuk_crypt(sosemanuk_state *ss, /* * Cipher operation, as a PRNG: the provided output buffer is filled with * pseudo-random bytes as output from the stream cipher. - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @param out Data out * @param outlen Length of output in bytes * @return CRYPT_OK on success */ -int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen) +int sosemanuk_keystream(sosemanuk_state *st, unsigned char *out, unsigned long outlen) { if (outlen == 0) return CRYPT_OK; /* nothing to do */ LTC_ARGCHK(out != NULL); XMEMSET(out, 0, outlen); - return sosemanuk_crypt(ss, out, outlen, out); + return sosemanuk_crypt(st, out, outlen, out); } /* * Terminate and clear Sosemanuk key context - * @param ss The Sosemanuk state + * @param st The Sosemanuk state * @return CRYPT_OK on success */ -int sosemanuk_done(sosemanuk_state *ss) +int sosemanuk_done(sosemanuk_state *st) { - LTC_ARGCHK(ss != NULL); - XMEMSET(ss, 0, sizeof(sosemanuk_state)); + LTC_ARGCHK(st != NULL); + XMEMSET(st, 0, sizeof(sosemanuk_state)); return CRYPT_OK; } diff --git a/src/ltc/stream/sosemanuk/sosemanuk_memory.c b/src/ltc/stream/sosemanuk/sosemanuk_memory.c new file mode 100644 index 00000000..e0eae16a --- /dev/null +++ b/src/ltc/stream/sosemanuk/sosemanuk_memory.c @@ -0,0 +1,45 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt_private.h" + +#ifdef LTC_SOSEMANUK + +/** + Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sosemanuk + @param key The key + @param keylen The key length + @param iv The initial vector + @param ivlen The initial vector length + @param datain The plaintext (or ciphertext) + @param datalen The length of the input and output (octets) + @param dataout [out] The ciphertext (or plaintext) + @return CRYPT_OK if successful +*/ +int sosemanuk_memory(const unsigned char *key, unsigned long keylen, + const unsigned char *iv, unsigned long ivlen, + const unsigned char *datain, unsigned long datalen, + unsigned char *dataout) +{ + sosemanuk_state st; + int err; + + if ((err = sosemanuk_setup(&st, key, keylen)) != CRYPT_OK) goto WIPE_KEY; + if ((err = sosemanuk_setiv(&st, iv, ivlen)) != CRYPT_OK) goto WIPE_KEY; + err = sosemanuk_crypt(&st, datain, datalen, dataout); +WIPE_KEY: + sosemanuk_done(&st); + return err; +} + +#endif /* LTC_SOSEMANUK */ + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ |