summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorKarel Miko <karel.miko@gmail.com>2018-10-04 20:13:36 +0200
committerKarel Miko <karel.miko@gmail.com>2018-10-04 20:13:36 +0200
commitc14794b6f61e93a6716b75c4547b554033612e07 (patch)
tree6ae18006485245a855abcef838752b0ed6324e1f /src
parent3bf90f7e79623e5f5f610fa683032811115b1553 (diff)
libtomcrypt update
Diffstat (limited to 'src')
-rw-r--r--src/Makefile185
-rw-r--r--src/Makefile.nmake150
-rw-r--r--src/ltc/headers/tomcrypt_cipher.h34
-rw-r--r--src/ltc/headers/tomcrypt_custom.h12
-rw-r--r--src/ltc/headers/tomcrypt_pk.h41
-rw-r--r--src/ltc/headers/tomcrypt_private.h60
-rw-r--r--src/ltc/misc/crypt/crypt.c7
-rw-r--r--src/ltc/misc/pbes/pbes.c83
-rw-r--r--src/ltc/misc/pbes/pbes1.c127
-rw-r--r--src/ltc/misc/pbes/pbes2.c201
-rw-r--r--src/ltc/misc/pk_get_oid.c60
-rw-r--r--src/ltc/misc/pkcs12/pkcs12_kdf.c2
-rw-r--r--src/ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.c9
-rw-r--r--src/ltc/pk/asn1/der/object_identifier/der_length_object_identifier.c4
-rw-r--r--src/ltc/pk/asn1/oid/pk_get_oid.c45
-rw-r--r--src/ltc/pk/asn1/oid/pk_oid_cmp.c54
-rw-r--r--src/ltc/pk/asn1/oid/pk_oid_str.c (renamed from src/ltc/misc/pk_oid_str.c)26
-rw-r--r--src/ltc/pk/asn1/pkcs8/pkcs8_decode_flexi.c107
-rw-r--r--src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c10
-rw-r--r--src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c13
-rw-r--r--src/ltc/pk/ecc/ecc_export_openssl.c12
-rw-r--r--src/ltc/pk/ecc/ecc_import_pkcs8.c495
-rw-r--r--src/ltc/pk/ecc/ecc_recover_key.c249
-rw-r--r--src/ltc/pk/ecc/ecc_sign_hash.c108
-rw-r--r--src/ltc/pk/ecc/ecc_verify_hash.c97
-rw-r--r--src/ltc/pk/rsa/rsa_import_pkcs8.c29
-rw-r--r--src/ltc/stream/chacha/chacha_memory.c51
-rw-r--r--src/ltc/stream/rabbit/rabbit.c14
-rw-r--r--src/ltc/stream/rabbit/rabbit_memory.c50
-rw-r--r--src/ltc/stream/rc4/rc4_stream_memory.c41
-rw-r--r--src/ltc/stream/salsa20/salsa20_memory.c45
-rw-r--r--src/ltc/stream/salsa20/xsalsa20_memory.c44
-rw-r--r--src/ltc/stream/sober128/sober128_stream_memory.c45
-rw-r--r--src/ltc/stream/sosemanuk/sosemanuk.c156
-rw-r--r--src/ltc/stream/sosemanuk/sosemanuk_memory.c45
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$ */