summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Makefile103
-rw-r--r--src/Makefile.nmake57
-rw-r--r--src/ltc/ciphers/aes/aes.c24
-rw-r--r--src/ltc/ciphers/aes/aes_desc.c244
-rw-r--r--src/ltc/ciphers/aes/aesni.c371
-rw-r--r--src/ltc/ciphers/camellia.c4
-rw-r--r--src/ltc/encauth/gcm/gcm_add_aad.c2
-rw-r--r--src/ltc/encauth/gcm/gcm_memory.c1
-rw-r--r--src/ltc/headers/tomcrypt_cfg.h16
-rw-r--r--src/ltc/headers/tomcrypt_cipher.h44
-rw-r--r--src/ltc/headers/tomcrypt_custom.h15
-rw-r--r--src/ltc/headers/tomcrypt_hash.h3
-rw-r--r--src/ltc/headers/tomcrypt_mac.h30
-rw-r--r--src/ltc/headers/tomcrypt_macros.h37
-rw-r--r--src/ltc/headers/tomcrypt_math.h6
-rw-r--r--src/ltc/headers/tomcrypt_misc.h7
-rw-r--r--src/ltc/headers/tomcrypt_pk.h92
-rw-r--r--src/ltc/headers/tomcrypt_private.h50
-rw-r--r--src/ltc/math/fp/ltc_ecc_fp_mulmod.c2
-rw-r--r--src/ltc/misc/base64/base64_encode.c65
-rw-r--r--src/ltc/misc/bcrypt/bcrypt.c2
-rw-r--r--src/ltc/misc/crypt/crypt.c3
-rw-r--r--src/ltc/misc/crypt/crypt_register_all_ciphers.c1
-rw-r--r--src/ltc/misc/padding/padding_depad.c6
-rw-r--r--src/ltc/misc/padding/padding_pad.c11
-rw-r--r--src/ltc/misc/pkcs12/pkcs12_kdf.c2
-rw-r--r--src/ltc/misc/ssh/ssh_encode_sequence_multi.c2
-rw-r--r--src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c4
-rw-r--r--src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c9
-rw-r--r--src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c2
-rw-r--r--src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c14
-rw-r--r--src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c4
-rw-r--r--src/ltc/pk/asn1/oid/pk_get_oid.c12
-rw-r--r--src/ltc/pk/asn1/oid/pk_oid_str.c3
-rw-r--r--src/ltc/pk/asn1/x509/x509_decode_public_key_from_certificate.c2
-rw-r--r--src/ltc/pk/dh/dh_free.c2
-rw-r--r--src/ltc/pk/dh/dh_import.c2
-rw-r--r--src/ltc/pk/dh/dh_set.c4
-rw-r--r--src/ltc/pk/dh/dh_set_pg_dhparam.c2
-rw-r--r--src/ltc/pk/dsa/dsa_encrypt_key.c6
-rw-r--r--src/ltc/pk/dsa/dsa_export.c2
-rw-r--r--src/ltc/pk/dsa/dsa_free.c2
-rw-r--r--src/ltc/pk/dsa/dsa_generate_pqg.c6
-rw-r--r--src/ltc/pk/dsa/dsa_import.c20
-rw-r--r--src/ltc/pk/dsa/dsa_set.c2
-rw-r--r--src/ltc/pk/dsa/dsa_set_pqg_dsaparam.c2
-rw-r--r--src/ltc/pk/dsa/dsa_sign_hash.c8
-rw-r--r--src/ltc/pk/dsa/dsa_verify_hash.c8
-rw-r--r--src/ltc/pk/dsa/dsa_verify_key.c4
-rw-r--r--src/ltc/pk/ec25519/ec25519_crypto_ctx.c41
-rw-r--r--src/ltc/pk/ec25519/tweetnacl.c33
-rw-r--r--src/ltc/pk/ecc/ecc_export_openssl.c73
-rw-r--r--src/ltc/pk/ecc/ecc_import_openssl.c4
-rw-r--r--src/ltc/pk/ecc/ecc_import_pkcs8.c12
-rw-r--r--src/ltc/pk/ecc/ecc_import_x509.c10
-rw-r--r--src/ltc/pk/ecc/ecc_recover_key.c10
-rw-r--r--src/ltc/pk/ecc/ecc_sign_hash.c4
-rw-r--r--src/ltc/pk/ecc/ecc_ssh_ecdsa_encode_name.c2
-rw-r--r--src/ltc/pk/ecc/ecc_verify_hash.c10
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_import_point.c4
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_is_point.c4
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c4
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_map.c4
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_points.c4
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_projective_add_point.c6
-rw-r--r--src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c4
-rw-r--r--src/ltc/pk/ed25519/ed25519_export.c2
-rw-r--r--src/ltc/pk/ed25519/ed25519_import.c4
-rw-r--r--src/ltc/pk/ed25519/ed25519_import_pkcs8.c2
-rw-r--r--src/ltc/pk/ed25519/ed25519_import_raw.c2
-rw-r--r--src/ltc/pk/ed25519/ed25519_import_x509.c4
-rw-r--r--src/ltc/pk/ed25519/ed25519_make_key.c2
-rw-r--r--src/ltc/pk/ed25519/ed25519_sign.c92
-rw-r--r--src/ltc/pk/ed25519/ed25519_verify.c101
-rw-r--r--src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c10
-rw-r--r--src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c2
-rw-r--r--src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c8
-rw-r--r--src/ltc/pk/rsa/rsa_decrypt_key.c1
-rw-r--r--src/ltc/pk/rsa/rsa_encrypt_key.c2
-rw-r--r--src/ltc/pk/rsa/rsa_export.c2
-rw-r--r--src/ltc/pk/rsa/rsa_import.c116
-rw-r--r--src/ltc/pk/rsa/rsa_import_pkcs8.c31
-rw-r--r--src/ltc/pk/rsa/rsa_import_x509.c2
-rw-r--r--src/ltc/pk/rsa/rsa_key.c4
-rw-r--r--src/ltc/pk/rsa/rsa_make_key.c4
-rw-r--r--src/ltc/pk/rsa/rsa_verify_hash.c2
-rw-r--r--src/ltc/pk/x25519/x25519_export.c2
-rw-r--r--src/ltc/pk/x25519/x25519_import.c4
-rw-r--r--src/ltc/pk/x25519/x25519_import_pkcs8.c2
-rw-r--r--src/ltc/pk/x25519/x25519_import_raw.c2
-rw-r--r--src/ltc/pk/x25519/x25519_import_x509.c4
-rw-r--r--src/ltc/pk/x25519/x25519_make_key.c2
92 files changed, 1473 insertions, 485 deletions
diff --git a/src/Makefile b/src/Makefile
index 2642bcf4..67595ba7 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,40 +1,41 @@
-OBJS=ltc/ciphers/aes/aes.o ltc/ciphers/anubis.o ltc/ciphers/blowfish.o ltc/ciphers/camellia.o \
-ltc/ciphers/cast5.o ltc/ciphers/des.o ltc/ciphers/idea.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o \
-ltc/ciphers/kseed.o ltc/ciphers/multi2.o ltc/ciphers/noekeon.o ltc/ciphers/rc2.o \
-ltc/ciphers/rc5.o ltc/ciphers/rc6.o ltc/ciphers/safer/safer.o ltc/ciphers/safer/saferp.o \
-ltc/ciphers/serpent.o ltc/ciphers/skipjack.o ltc/ciphers/tea.o ltc/ciphers/twofish/twofish.o \
-ltc/ciphers/xtea.o ltc/encauth/ccm/ccm_add_aad.o ltc/encauth/ccm/ccm_add_nonce.o \
-ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o ltc/encauth/ccm/ccm_memory.o \
-ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o ltc/encauth/chachapoly/chacha20poly1305_add_aad.o \
-ltc/encauth/chachapoly/chacha20poly1305_decrypt.o ltc/encauth/chachapoly/chacha20poly1305_done.o \
-ltc/encauth/chachapoly/chacha20poly1305_encrypt.o ltc/encauth/chachapoly/chacha20poly1305_init.o \
-ltc/encauth/chachapoly/chacha20poly1305_memory.o ltc/encauth/chachapoly/chacha20poly1305_setiv.o \
-ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o ltc/encauth/eax/eax_addheader.o \
-ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o ltc/encauth/eax/eax_done.o \
-ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o ltc/encauth/eax/eax_init.o \
-ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o ltc/encauth/gcm/gcm_done.o \
-ltc/encauth/gcm/gcm_gf_mult.o ltc/encauth/gcm/gcm_init.o ltc/encauth/gcm/gcm_memory.o \
-ltc/encauth/gcm/gcm_mult_h.o ltc/encauth/gcm/gcm_process.o ltc/encauth/gcm/gcm_reset.o \
-ltc/encauth/ocb3/ocb3_add_aad.o ltc/encauth/ocb3/ocb3_decrypt.o ltc/encauth/ocb3/ocb3_decrypt_last.o \
-ltc/encauth/ocb3/ocb3_decrypt_verify_memory.o ltc/encauth/ocb3/ocb3_done.o ltc/encauth/ocb3/ocb3_encrypt.o \
-ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.o ltc/encauth/ocb3/ocb3_encrypt_last.o \
-ltc/encauth/ocb3/ocb3_init.o ltc/encauth/ocb3/ocb3_int_ntz.o ltc/encauth/ocb3/ocb3_int_xor_blocks.o \
-ltc/hashes/blake2b.o ltc/hashes/blake2s.o ltc/hashes/chc/chc.o ltc/hashes/helper/hash_file.o \
-ltc/hashes/helper/hash_filehandle.o ltc/hashes/helper/hash_memory.o ltc/hashes/helper/hash_memory_multi.o \
-ltc/hashes/md2.o ltc/hashes/md4.o ltc/hashes/md5.o ltc/hashes/rmd128.o ltc/hashes/rmd160.o \
-ltc/hashes/rmd256.o ltc/hashes/rmd320.o ltc/hashes/sha1.o ltc/hashes/sha2/sha224.o \
-ltc/hashes/sha2/sha256.o ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o ltc/hashes/sha2/sha512_224.o \
-ltc/hashes/sha2/sha512_256.o ltc/hashes/sha3.o ltc/hashes/sha3_test.o ltc/hashes/tiger.o \
-ltc/hashes/whirl/whirl.o ltc/mac/blake2/blake2bmac.o ltc/mac/blake2/blake2bmac_file.o \
-ltc/mac/blake2/blake2bmac_memory.o ltc/mac/blake2/blake2bmac_memory_multi.o ltc/mac/blake2/blake2smac.o \
-ltc/mac/blake2/blake2smac_file.o ltc/mac/blake2/blake2smac_memory.o ltc/mac/blake2/blake2smac_memory_multi.o \
-ltc/mac/f9/f9_done.o ltc/mac/f9/f9_file.o ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o \
-ltc/mac/f9/f9_memory_multi.o ltc/mac/f9/f9_process.o ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o \
-ltc/mac/hmac/hmac_init.o ltc/mac/hmac/hmac_memory.o ltc/mac/hmac/hmac_memory_multi.o \
-ltc/mac/hmac/hmac_process.o ltc/mac/omac/omac_done.o ltc/mac/omac/omac_file.o ltc/mac/omac/omac_init.o \
-ltc/mac/omac/omac_memory.o ltc/mac/omac/omac_memory_multi.o ltc/mac/omac/omac_process.o \
-ltc/mac/pelican/pelican.o ltc/mac/pelican/pelican_memory.o ltc/mac/pmac/pmac_done.o \
-ltc/mac/pmac/pmac_file.o ltc/mac/pmac/pmac_init.o ltc/mac/pmac/pmac_memory.o ltc/mac/pmac/pmac_memory_multi.o \
+OBJS=ltc/ciphers/aes/aes.o ltc/ciphers/aes/aes_desc.o ltc/ciphers/aes/aesni.o ltc/ciphers/anubis.o \
+ltc/ciphers/blowfish.o ltc/ciphers/camellia.o ltc/ciphers/cast5.o ltc/ciphers/des.o \
+ltc/ciphers/idea.o ltc/ciphers/kasumi.o ltc/ciphers/khazad.o ltc/ciphers/kseed.o \
+ltc/ciphers/multi2.o ltc/ciphers/noekeon.o ltc/ciphers/rc2.o ltc/ciphers/rc5.o ltc/ciphers/rc6.o \
+ltc/ciphers/safer/safer.o ltc/ciphers/safer/saferp.o ltc/ciphers/serpent.o ltc/ciphers/skipjack.o \
+ltc/ciphers/tea.o ltc/ciphers/twofish/twofish.o ltc/ciphers/xtea.o ltc/encauth/ccm/ccm_add_aad.o \
+ltc/encauth/ccm/ccm_add_nonce.o ltc/encauth/ccm/ccm_done.o ltc/encauth/ccm/ccm_init.o \
+ltc/encauth/ccm/ccm_memory.o ltc/encauth/ccm/ccm_process.o ltc/encauth/ccm/ccm_reset.o \
+ltc/encauth/chachapoly/chacha20poly1305_add_aad.o ltc/encauth/chachapoly/chacha20poly1305_decrypt.o \
+ltc/encauth/chachapoly/chacha20poly1305_done.o ltc/encauth/chachapoly/chacha20poly1305_encrypt.o \
+ltc/encauth/chachapoly/chacha20poly1305_init.o ltc/encauth/chachapoly/chacha20poly1305_memory.o \
+ltc/encauth/chachapoly/chacha20poly1305_setiv.o ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.o \
+ltc/encauth/eax/eax_addheader.o ltc/encauth/eax/eax_decrypt.o ltc/encauth/eax/eax_decrypt_verify_memory.o \
+ltc/encauth/eax/eax_done.o ltc/encauth/eax/eax_encrypt.o ltc/encauth/eax/eax_encrypt_authenticate_memory.o \
+ltc/encauth/eax/eax_init.o ltc/encauth/gcm/gcm_add_aad.o ltc/encauth/gcm/gcm_add_iv.o \
+ltc/encauth/gcm/gcm_done.o ltc/encauth/gcm/gcm_gf_mult.o ltc/encauth/gcm/gcm_init.o \
+ltc/encauth/gcm/gcm_memory.o ltc/encauth/gcm/gcm_mult_h.o ltc/encauth/gcm/gcm_process.o \
+ltc/encauth/gcm/gcm_reset.o ltc/encauth/ocb3/ocb3_add_aad.o ltc/encauth/ocb3/ocb3_decrypt.o \
+ltc/encauth/ocb3/ocb3_decrypt_last.o ltc/encauth/ocb3/ocb3_decrypt_verify_memory.o \
+ltc/encauth/ocb3/ocb3_done.o ltc/encauth/ocb3/ocb3_encrypt.o ltc/encauth/ocb3/ocb3_encrypt_authenticate_memory.o \
+ltc/encauth/ocb3/ocb3_encrypt_last.o ltc/encauth/ocb3/ocb3_init.o ltc/encauth/ocb3/ocb3_int_ntz.o \
+ltc/encauth/ocb3/ocb3_int_xor_blocks.o ltc/hashes/blake2b.o ltc/hashes/blake2s.o \
+ltc/hashes/chc/chc.o ltc/hashes/helper/hash_file.o ltc/hashes/helper/hash_filehandle.o \
+ltc/hashes/helper/hash_memory.o ltc/hashes/helper/hash_memory_multi.o ltc/hashes/md2.o \
+ltc/hashes/md4.o ltc/hashes/md5.o ltc/hashes/rmd128.o ltc/hashes/rmd160.o ltc/hashes/rmd256.o \
+ltc/hashes/rmd320.o ltc/hashes/sha1.o ltc/hashes/sha2/sha224.o ltc/hashes/sha2/sha256.o \
+ltc/hashes/sha2/sha384.o ltc/hashes/sha2/sha512.o ltc/hashes/sha2/sha512_224.o ltc/hashes/sha2/sha512_256.o \
+ltc/hashes/sha3.o ltc/hashes/sha3_test.o ltc/hashes/tiger.o ltc/hashes/whirl/whirl.o \
+ltc/mac/blake2/blake2bmac.o ltc/mac/blake2/blake2bmac_file.o ltc/mac/blake2/blake2bmac_memory.o \
+ltc/mac/blake2/blake2bmac_memory_multi.o ltc/mac/blake2/blake2smac.o ltc/mac/blake2/blake2smac_file.o \
+ltc/mac/blake2/blake2smac_memory.o ltc/mac/blake2/blake2smac_memory_multi.o ltc/mac/f9/f9_done.o \
+ltc/mac/f9/f9_file.o ltc/mac/f9/f9_init.o ltc/mac/f9/f9_memory.o ltc/mac/f9/f9_memory_multi.o \
+ltc/mac/f9/f9_process.o ltc/mac/hmac/hmac_done.o ltc/mac/hmac/hmac_file.o ltc/mac/hmac/hmac_init.o \
+ltc/mac/hmac/hmac_memory.o ltc/mac/hmac/hmac_memory_multi.o ltc/mac/hmac/hmac_process.o \
+ltc/mac/omac/omac_done.o ltc/mac/omac/omac_file.o ltc/mac/omac/omac_init.o ltc/mac/omac/omac_memory.o \
+ltc/mac/omac/omac_memory_multi.o ltc/mac/omac/omac_process.o ltc/mac/pelican/pelican.o \
+ltc/mac/pelican/pelican_memory.o ltc/mac/pmac/pmac_done.o ltc/mac/pmac/pmac_file.o \
+ltc/mac/pmac/pmac_init.o ltc/mac/pmac/pmac_memory.o ltc/mac/pmac/pmac_memory_multi.o \
ltc/mac/pmac/pmac_ntz.o ltc/mac/pmac/pmac_process.o ltc/mac/pmac/pmac_shift_xor.o \
ltc/mac/poly1305/poly1305.o ltc/mac/poly1305/poly1305_file.o ltc/mac/poly1305/poly1305_memory.o \
ltc/mac/poly1305/poly1305_memory_multi.o ltc/mac/xcbc/xcbc_done.o ltc/mac/xcbc/xcbc_file.o \
@@ -105,20 +106,20 @@ ltc/pk/dh/dh_set_pg_dhparam.o ltc/pk/dh/dh_shared_secret.o ltc/pk/dsa/dsa_decryp
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/ec25519/ec25519_export.o \
-ltc/pk/ec25519/ec25519_import_pkcs8.o ltc/pk/ec25519/tweetnacl.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_ssh_ecdsa_encode_name.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 ltc/pk/ecc/ltc_ecc_map.o ltc/pk/ecc/ltc_ecc_mul2add.o \
-ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o ltc/pk/ecc/ltc_ecc_points.o \
-ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \
+ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ec25519/ec25519_crypto_ctx.o \
+ltc/pk/ec25519/ec25519_export.o ltc/pk/ec25519/ec25519_import_pkcs8.o ltc/pk/ec25519/tweetnacl.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_ssh_ecdsa_encode_name.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 ltc/pk/ecc/ltc_ecc_map.o \
+ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o ltc/pk/ecc/ltc_ecc_mulmod_timing.o \
+ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o ltc/pk/ecc/ltc_ecc_projective_dbl_point.o \
ltc/pk/ecc/ltc_ecc_verify_key.o ltc/pk/ed25519/ed25519_export.o ltc/pk/ed25519/ed25519_import.o \
ltc/pk/ed25519/ed25519_import_pkcs8.o ltc/pk/ed25519/ed25519_import_raw.o ltc/pk/ed25519/ed25519_import_x509.o \
ltc/pk/ed25519/ed25519_make_key.o ltc/pk/ed25519/ed25519_sign.o ltc/pk/ed25519/ed25519_verify.o \
diff --git a/src/Makefile.nmake b/src/Makefile.nmake
index 5e2cd2da..0afef2fe 100644
--- a/src/Makefile.nmake
+++ b/src/Makefile.nmake
@@ -1,17 +1,18 @@
-OBJS=ltc/ciphers/aes/aes.obj ltc/ciphers/anubis.obj ltc/ciphers/blowfish.obj ltc/ciphers/camellia.obj \
-ltc/ciphers/cast5.obj ltc/ciphers/des.obj ltc/ciphers/idea.obj ltc/ciphers/kasumi.obj \
-ltc/ciphers/khazad.obj ltc/ciphers/kseed.obj ltc/ciphers/multi2.obj ltc/ciphers/noekeon.obj \
-ltc/ciphers/rc2.obj ltc/ciphers/rc5.obj ltc/ciphers/rc6.obj ltc/ciphers/safer/safer.obj \
-ltc/ciphers/safer/saferp.obj ltc/ciphers/serpent.obj ltc/ciphers/skipjack.obj ltc/ciphers/tea.obj \
-ltc/ciphers/twofish/twofish.obj ltc/ciphers/xtea.obj ltc/encauth/ccm/ccm_add_aad.obj \
-ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj ltc/encauth/ccm/ccm_init.obj \
-ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj ltc/encauth/ccm/ccm_reset.obj \
-ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj \
-ltc/encauth/chachapoly/chacha20poly1305_done.obj ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj \
-ltc/encauth/chachapoly/chacha20poly1305_init.obj ltc/encauth/chachapoly/chacha20poly1305_memory.obj \
-ltc/encauth/chachapoly/chacha20poly1305_setiv.obj ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj \
-ltc/encauth/eax/eax_addheader.obj ltc/encauth/eax/eax_decrypt.obj ltc/encauth/eax/eax_decrypt_verify_memory.obj \
-ltc/encauth/eax/eax_done.obj ltc/encauth/eax/eax_encrypt.obj ltc/encauth/eax/eax_encrypt_authenticate_memory.obj \
+OBJS=ltc/ciphers/aes/aes.obj ltc/ciphers/aes/aes_desc.obj ltc/ciphers/aes/aesni.obj ltc/ciphers/anubis.obj \
+ltc/ciphers/blowfish.obj ltc/ciphers/camellia.obj ltc/ciphers/cast5.obj ltc/ciphers/des.obj \
+ltc/ciphers/idea.obj ltc/ciphers/kasumi.obj ltc/ciphers/khazad.obj ltc/ciphers/kseed.obj \
+ltc/ciphers/multi2.obj ltc/ciphers/noekeon.obj ltc/ciphers/rc2.obj ltc/ciphers/rc5.obj \
+ltc/ciphers/rc6.obj ltc/ciphers/safer/safer.obj ltc/ciphers/safer/saferp.obj ltc/ciphers/serpent.obj \
+ltc/ciphers/skipjack.obj ltc/ciphers/tea.obj ltc/ciphers/twofish/twofish.obj ltc/ciphers/xtea.obj \
+ltc/encauth/ccm/ccm_add_aad.obj ltc/encauth/ccm/ccm_add_nonce.obj ltc/encauth/ccm/ccm_done.obj \
+ltc/encauth/ccm/ccm_init.obj ltc/encauth/ccm/ccm_memory.obj ltc/encauth/ccm/ccm_process.obj \
+ltc/encauth/ccm/ccm_reset.obj ltc/encauth/chachapoly/chacha20poly1305_add_aad.obj \
+ltc/encauth/chachapoly/chacha20poly1305_decrypt.obj ltc/encauth/chachapoly/chacha20poly1305_done.obj \
+ltc/encauth/chachapoly/chacha20poly1305_encrypt.obj ltc/encauth/chachapoly/chacha20poly1305_init.obj \
+ltc/encauth/chachapoly/chacha20poly1305_memory.obj ltc/encauth/chachapoly/chacha20poly1305_setiv.obj \
+ltc/encauth/chachapoly/chacha20poly1305_setiv_rfc7905.obj ltc/encauth/eax/eax_addheader.obj \
+ltc/encauth/eax/eax_decrypt.obj ltc/encauth/eax/eax_decrypt_verify_memory.obj ltc/encauth/eax/eax_done.obj \
+ltc/encauth/eax/eax_encrypt.obj ltc/encauth/eax/eax_encrypt_authenticate_memory.obj \
ltc/encauth/eax/eax_init.obj ltc/encauth/gcm/gcm_add_aad.obj ltc/encauth/gcm/gcm_add_iv.obj \
ltc/encauth/gcm/gcm_done.obj ltc/encauth/gcm/gcm_gf_mult.obj ltc/encauth/gcm/gcm_init.obj \
ltc/encauth/gcm/gcm_memory.obj ltc/encauth/gcm/gcm_mult_h.obj ltc/encauth/gcm/gcm_process.obj \
@@ -112,20 +113,20 @@ 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/ec25519/ec25519_export.obj ltc/pk/ec25519/ec25519_import_pkcs8.obj \
-ltc/pk/ec25519/tweetnacl.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 \
-ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_find_curve.obj \
-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_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_ssh_ecdsa_encode_name.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/dsa/dsa_verify_key.obj ltc/pk/ec25519/ec25519_crypto_ctx.obj ltc/pk/ec25519/ec25519_export.obj \
+ltc/pk/ec25519/ec25519_import_pkcs8.obj ltc/pk/ec25519/tweetnacl.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 ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj \
+ltc/pk/ecc/ecc_find_curve.obj 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_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_ssh_ecdsa_encode_name.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/ed25519/ed25519_export.obj ltc/pk/ed25519/ed25519_import.obj \
ltc/pk/ed25519/ed25519_import_pkcs8.obj ltc/pk/ed25519/ed25519_import_raw.obj ltc/pk/ed25519/ed25519_import_x509.obj \
ltc/pk/ed25519/ed25519_make_key.obj ltc/pk/ed25519/ed25519_sign.obj ltc/pk/ed25519/ed25519_verify.obj \
diff --git a/src/ltc/ciphers/aes/aes.c b/src/ltc/ciphers/aes/aes.c
index dd6f14e8..507d5c57 100644
--- a/src/ltc/ciphers/aes/aes.c
+++ b/src/ltc/ciphers/aes/aes.c
@@ -44,15 +44,6 @@ const struct ltc_cipher_descriptor rijndael_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-const struct ltc_cipher_descriptor aes_desc =
-{
- "aes",
- 6,
- 16, 32, 16, 10,
- SETUP, ECB_ENC, ECB_DEC, ECB_TEST, ECB_DONE, ECB_KS,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
#else
#define SETUP rijndael_enc_setup
@@ -69,15 +60,6 @@ const struct ltc_cipher_descriptor rijndael_enc_desc =
NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
};
-const struct ltc_cipher_descriptor aes_enc_desc =
-{
- "aes",
- 6,
- 16, 32, 16, 10,
- SETUP, ECB_ENC, NULL, NULL, ECB_DONE, ECB_KS,
- NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
-};
-
#endif
#define LTC_AES_TAB_C
@@ -114,6 +96,7 @@ static ulong32 setup_mix2(ulong32 temp)
int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
{
int i;
+ unsigned char *K;
ulong32 temp, *rk;
#ifndef ENCRYPT_ONLY
ulong32 *rrk;
@@ -130,6 +113,10 @@ int SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *s
}
skey->rijndael.Nr = 10 + ((keylen/8)-2)*2;
+ K = (void*)((((size_t)&skey->rijndael.K[15]) >> 4) << 4);
+ skey->rijndael.eK = (ulong32*)K;
+ K += (60 * sizeof(ulong32));
+ skey->rijndael.dK = (ulong32*)K;
/* setup the forward key */
i = 0;
@@ -741,4 +728,3 @@ int ECB_KS(int *keysize)
}
#endif
-
diff --git a/src/ltc/ciphers/aes/aes_desc.c b/src/ltc/ciphers/aes/aes_desc.c
new file mode 100644
index 00000000..5b42d92b
--- /dev/null
+++ b/src/ltc/ciphers/aes/aes_desc.c
@@ -0,0 +1,244 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* Auto-detection of AES implementation by Steffen Jaeckel */
+/**
+ @file aes_desc.c
+ Run-time detection of correct AES implementation
+*/
+
+#include "tomcrypt_private.h"
+
+#if defined(LTC_RIJNDAEL)
+
+#ifndef ENCRYPT_ONLY
+
+#define AES_SETUP aes_setup
+#define AES_ENC aes_ecb_encrypt
+#define AES_DEC aes_ecb_decrypt
+#define AES_DONE aes_done
+#define AES_TEST aes_test
+#define AES_KS aes_keysize
+
+const struct ltc_cipher_descriptor aes_desc =
+{
+ "aes",
+ 6,
+ 16, 32, 16, 10,
+ AES_SETUP, AES_ENC, AES_DEC, AES_TEST, AES_DONE, AES_KS,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+#else
+
+#define AES_SETUP aes_enc_setup
+#define AES_ENC aes_enc_ecb_encrypt
+#define AES_DONE aes_enc_done
+#define AES_KS aes_enc_keysize
+
+const struct ltc_cipher_descriptor aes_enc_desc =
+{
+ "aes",
+ 6,
+ 16, 32, 16, 10,
+ AES_SETUP, AES_ENC, NULL, NULL, AES_DONE, AES_KS,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+#endif
+
+/* Code partially borrowed from https://software.intel.com/content/www/us/en/develop/articles/intel-sha-extensions.html */
+#if defined(LTC_HAS_AES_NI)
+static LTC_INLINE int s_aesni_is_supported(void)
+{
+ static int initialized = 0, is_supported = 0;
+
+ if (initialized == 0) {
+ int a, b, c, d;
+
+ /* Look for CPUID.1.0.ECX[25]
+ * EAX = 1, ECX = 0
+ */
+ a = 1;
+ c = 0;
+
+ asm volatile ("cpuid"
+ :"=a"(a), "=b"(b), "=c"(c), "=d"(d)
+ :"a"(a), "c"(c)
+ );
+
+ is_supported = ((c >> 25) & 1);
+ initialized = 1;
+ }
+
+ return is_supported;
+}
+
+#ifndef ENCRYPT_ONLY
+int aesni_is_supported(void)
+{
+ return s_aesni_is_supported();
+}
+#endif
+#endif
+
+ /**
+ Initialize the AES (Rijndael) block cipher
+ @param key The symmetric key you wish to pass
+ @param keylen The key length in bytes
+ @param num_rounds The number of rounds desired (0 for default)
+ @param skey The key in as scheduled by this function.
+ @return CRYPT_OK if successful
+ */
+int AES_SETUP(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
+{
+#ifdef LTC_HAS_AES_NI
+ if (s_aesni_is_supported()) {
+ return aesni_setup(key, keylen, num_rounds, skey);
+ }
+#endif
+ /* Last resort, software AES */
+ return rijndael_setup(key, keylen, num_rounds, skey);
+}
+
+/**
+ Encrypts a block of text with AES
+ @param pt The input plaintext (16 bytes)
+ @param ct The output ciphertext (16 bytes)
+ @param skey The key as scheduled
+ @return CRYPT_OK if successful
+*/
+int AES_ENC(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
+{
+#ifdef LTC_HAS_AES_NI
+ if (s_aesni_is_supported()) {
+ return aesni_ecb_encrypt(pt, ct, skey);
+ }
+#endif
+ return rijndael_ecb_encrypt(pt, ct, skey);
+}
+
+
+/**
+ Decrypts a block of text with AES
+ @param ct The input ciphertext (16 bytes)
+ @param pt The output plaintext (16 bytes)
+ @param skey The key as scheduled
+ @return CRYPT_OK if successful
+*/
+int AES_DEC(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
+{
+#ifdef LTC_HAS_AES_NI
+ if (s_aesni_is_supported()) {
+ return aesni_ecb_decrypt(ct, pt, skey);
+ }
+#endif
+ return rijndael_ecb_decrypt(ct, pt, skey);
+}
+
+/**
+ Performs a self-test of the AES block cipher
+ @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
+*/
+int AES_TEST(void)
+{
+ #ifndef LTC_TEST
+ return CRYPT_NOP;
+ #else
+ int err;
+ static const struct {
+ int keylen;
+ unsigned char key[32], pt[16], ct[16];
+ } tests[] = {
+ { 16,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+ 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
+ }, {
+ 24,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+ 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
+ }, {
+ 32,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+ 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
+ }
+ };
+
+ symmetric_key key;
+ unsigned char tmp[2][16];
+ int i, y;
+
+ for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
+ zeromem(&key, sizeof(key));
+ if ((err = aes_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
+ return err;
+ }
+
+ aes_ecb_encrypt(tests[i].pt, tmp[0], &key);
+ aes_ecb_decrypt(tmp[0], tmp[1], &key);
+ if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES Encrypt", i) ||
+ compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES Decrypt", i)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
+ for (y = 0; y < 16; y++) tmp[0][y] = 0;
+ for (y = 0; y < 1000; y++) aes_ecb_encrypt(tmp[0], tmp[0], &key);
+ for (y = 0; y < 1000; y++) aes_ecb_decrypt(tmp[0], tmp[0], &key);
+ for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
+ }
+ return CRYPT_OK;
+ #endif
+}
+
+
+/** Terminate the context
+ @param skey The scheduled key
+*/
+void AES_DONE(symmetric_key *skey)
+{
+ LTC_UNUSED_PARAM(skey);
+}
+
+
+/**
+ Gets suitable key size
+ @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
+ @return CRYPT_OK if the input key size is acceptable.
+*/
+int AES_KS(int *keysize)
+{
+ LTC_ARGCHK(keysize != NULL);
+
+ if (*keysize < 16) {
+ return CRYPT_INVALID_KEYSIZE;
+ }
+ if (*keysize < 24) {
+ *keysize = 16;
+ return CRYPT_OK;
+ }
+ if (*keysize < 32) {
+ *keysize = 24;
+ return CRYPT_OK;
+ }
+ *keysize = 32;
+ return CRYPT_OK;
+}
+
+#endif
+
diff --git a/src/ltc/ciphers/aes/aesni.c b/src/ltc/ciphers/aes/aesni.c
new file mode 100644
index 00000000..e730177a
--- /dev/null
+++ b/src/ltc/ciphers/aes/aesni.c
@@ -0,0 +1,371 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+
+/* AES-NI implementation by Steffen Jaeckel */
+/**
+ @file aesni.c
+ Implementation of AES via the AES-NI instruction on x86_64
+*/
+
+#include "tomcrypt_private.h"
+
+#if defined(LTC_HAS_AES_NI)
+
+const struct ltc_cipher_descriptor aesni_desc =
+{
+ "aes",
+ 6,
+ 16, 32, 16, 10,
+ aesni_setup, aesni_ecb_encrypt, aesni_ecb_decrypt, aesni_test, aesni_done, aesni_keysize,
+ NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL
+};
+
+#include <emmintrin.h>
+#include <smmintrin.h>
+#include <wmmintrin.h>
+
+#define setup_mix(t, c) _mm_extract_epi32(_mm_aeskeygenassist_si128(t, 0), c)
+#define temp_load(k) _mm_loadu_si128((__m128i*)(k))
+#define temp_update(t, k) _mm_insert_epi32(t, k, 3)
+#define temp_invert(k) _mm_aesimc_si128(*((__m128i*)(k)))
+
+
+static const ulong32 rcon[] = {
+ 0x01UL, 0x02UL, 0x04UL, 0x08UL, 0x10UL, 0x20UL, 0x40UL, 0x80UL, 0x1BUL, 0x36UL
+};
+
+ /**
+ Initialize the AES (Rijndael) block cipher
+ @param key The symmetric key you wish to pass
+ @param keylen The key length in bytes
+ @param num_rounds The number of rounds desired (0 for default)
+ @param skey The key in as scheduled by this function.
+ @return CRYPT_OK if successful
+ */
+int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey)
+{
+ int i;
+ unsigned char *K;
+ __m128i temp;
+ ulong32 *rk;
+ ulong32 *rrk;
+ LTC_ARGCHK(key != NULL);
+ LTC_ARGCHK(skey != NULL);
+
+ if (keylen != 16 && keylen != 24 && keylen != 32) {
+ return CRYPT_INVALID_KEYSIZE;
+ }
+
+ if (num_rounds != 0 && num_rounds != (keylen / 4 + 6)) {
+ return CRYPT_INVALID_ROUNDS;
+ }
+
+ skey->rijndael.Nr = keylen / 4 + 6;
+ K = (void*)((((size_t)&skey->rijndael.K[15]) >> 4) << 4);
+ skey->rijndael.eK = (ulong32*)K;
+ K += (60 * sizeof(ulong32));
+ skey->rijndael.dK = (ulong32*)K;
+
+ /* setup the forward key */
+ i = 0;
+ rk = skey->rijndael.eK;
+ LOAD32L(rk[0], key);
+ LOAD32L(rk[1], key + 4);
+ LOAD32L(rk[2], key + 8);
+ LOAD32L(rk[3], key + 12);
+ if (keylen == 16) {
+ temp = temp_load(key);
+ for (;;) {
+ rk[4] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
+ rk[5] = rk[1] ^ rk[4];
+ rk[6] = rk[2] ^ rk[5];
+ rk[7] = rk[3] ^ rk[6];
+ if (++i == 10) {
+ break;
+ }
+ temp = temp_update(temp, rk[7]);
+ rk += 4;
+ }
+ } else if (keylen == 24) {
+ LOAD32L(rk[4], key + 16);
+ LOAD32L(rk[5], key + 20);
+ temp = temp_load(key + 8);
+ for (;;) {
+ rk[6] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
+ rk[7] = rk[1] ^ rk[6];
+ rk[8] = rk[2] ^ rk[7];
+ rk[9] = rk[3] ^ rk[8];
+ if (++i == 8) {
+ break;
+ }
+ rk[10] = rk[4] ^ rk[9];
+ rk[11] = rk[5] ^ rk[10];
+ temp = temp_update(temp, rk[11]);
+ rk += 6;
+ }
+ } else if (keylen == 32) {
+ LOAD32L(rk[4], key + 16);
+ LOAD32L(rk[5], key + 20);
+ LOAD32L(rk[6], key + 24);
+ LOAD32L(rk[7], key + 28);
+ temp = temp_load(key + 16);
+ for (;;) {
+ rk[8] = rk[0] ^ setup_mix(temp, 3) ^ rcon[i];
+ rk[9] = rk[1] ^ rk[8];
+ rk[10] = rk[2] ^ rk[9];
+ rk[11] = rk[3] ^ rk[10];
+ if (++i == 7) {
+ break;
+ }
+ temp = temp_update(temp, rk[11]);
+ rk[12] = rk[4] ^ setup_mix(temp, 2);
+ rk[13] = rk[5] ^ rk[12];
+ rk[14] = rk[6] ^ rk[13];
+ rk[15] = rk[7] ^ rk[14];
+ temp = temp_update(temp, rk[15]);
+ rk += 8;
+ }
+ } else {
+ /* this can't happen */
+ /* coverity[dead_error_line] */
+ return CRYPT_ERROR;
+ }
+
+ /* setup the inverse key now */
+ rk = skey->rijndael.dK;
+ rrk = skey->rijndael.eK + skey->rijndael.Nr * 4;
+
+ /* apply the inverse MixColumn transform to all round keys but the first and the last: */
+ /* copy first */
+ *rk++ = *rrk++;
+ *rk++ = *rrk++;
+ *rk++ = *rrk++;
+ *rk = *rrk;
+ rk -= 3;
+ rrk -= 3;
+
+ for (i = 1; i < skey->rijndael.Nr; i++) {
+ rrk -= 4;
+ rk += 4;
+ temp = temp_invert(rk);
+ *((__m128i*) rk) = temp_invert(rrk);
+ }
+
+ /* copy last */
+ rrk -= 4;
+ rk += 4;
+ *rk++ = *rrk++;
+ *rk++ = *rrk++;
+ *rk++ = *rrk++;
+ *rk = *rrk;
+
+ return CRYPT_OK;
+}
+
+/**
+ Encrypts a block of text with AES
+ @param pt The input plaintext (16 bytes)
+ @param ct The output ciphertext (16 bytes)
+ @param skey The key as scheduled
+ @return CRYPT_OK if successful
+*/
+#ifdef LTC_CLEAN_STACK
+static int s_aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
+#else
+int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
+#endif
+{
+ int Nr, r;
+ const __m128i *skeys;
+ __m128i block;
+
+ LTC_ARGCHK(pt != NULL);
+ LTC_ARGCHK(ct != NULL);
+ LTC_ARGCHK(skey != NULL);
+
+ Nr = skey->rijndael.Nr;
+
+ if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;
+
+ skeys = (__m128i*) skey->rijndael.eK;
+ block = _mm_loadu_si128((const __m128i*) (pt));
+
+ block = _mm_xor_si128(block, skeys[0]);
+ for (r = 1; r < Nr - 1; r += 2) {
+ block = _mm_aesenc_si128(block, skeys[r]);
+ block = _mm_aesenc_si128(block, skeys[r + 1]);
+ }
+ block = _mm_aesenc_si128(block, skeys[Nr - 1]);
+ block = _mm_aesenclast_si128(block, skeys[Nr]);
+
+ _mm_storeu_si128((__m128i*) ct, block);
+
+ return CRYPT_OK;
+}
+
+#ifdef LTC_CLEAN_STACK
+int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey)
+{
+ int err = s_aesni_ecb_encrypt(pt, ct, skey);
+ burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
+ return err;
+}
+#endif
+
+
+/**
+ Decrypts a block of text with AES
+ @param ct The input ciphertext (16 bytes)
+ @param pt The output plaintext (16 bytes)
+ @param skey The key as scheduled
+ @return CRYPT_OK if successful
+*/
+#ifdef LTC_CLEAN_STACK
+static int s_aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
+#else
+int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
+#endif
+{
+ int Nr, r;
+ const __m128i *skeys;
+ __m128i block;
+
+ LTC_ARGCHK(pt != NULL);
+ LTC_ARGCHK(ct != NULL);
+ LTC_ARGCHK(skey != NULL);
+
+ Nr = skey->rijndael.Nr;
+
+ if (Nr < 2 || Nr > 16) return CRYPT_INVALID_ROUNDS;
+
+ skeys = (__m128i*) skey->rijndael.dK;
+ block = _mm_loadu_si128((const __m128i*) (ct));
+
+ block = _mm_xor_si128(block, skeys[0]);
+ for (r = 1; r < Nr - 1; r += 2) {
+ block = _mm_aesdec_si128(block, skeys[r]);
+ block = _mm_aesdec_si128(block, skeys[r + 1]);
+ }
+ block = _mm_aesdec_si128(block, skeys[Nr - 1]);
+ block = _mm_aesdeclast_si128(block, skeys[Nr]);
+
+ _mm_storeu_si128((__m128i*) pt, block);
+
+ return CRYPT_OK;
+}
+
+
+#ifdef LTC_CLEAN_STACK
+int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey)
+{
+ int err = s_aesni_ecb_decrypt(ct, pt, skey);
+ burn_stack(sizeof(unsigned long)*8 + sizeof(unsigned long*) + sizeof(int)*2);
+ return err;
+}
+#endif
+
+/**
+ Performs a self-test of the AES block cipher
+ @return CRYPT_OK if functional, CRYPT_NOP if self-test has been disabled
+*/
+int aesni_test(void)
+{
+ #ifndef LTC_TEST
+ return CRYPT_NOP;
+ #else
+ int err;
+ static const struct {
+ int keylen;
+ unsigned char key[32], pt[16], ct[16];
+ } tests[] = {
+ { 16,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0x69, 0xc4, 0xe0, 0xd8, 0x6a, 0x7b, 0x04, 0x30,
+ 0xd8, 0xcd, 0xb7, 0x80, 0x70, 0xb4, 0xc5, 0x5a }
+ }, {
+ 24,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17 },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0xdd, 0xa9, 0x7c, 0xa4, 0x86, 0x4c, 0xdf, 0xe0,
+ 0x6e, 0xaf, 0x70, 0xa0, 0xec, 0x0d, 0x71, 0x91 }
+ }, {
+ 32,
+ { 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
+ 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
+ 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
+ 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f },
+ { 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
+ 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff },
+ { 0x8e, 0xa2, 0xb7, 0xca, 0x51, 0x67, 0x45, 0xbf,
+ 0xea, 0xfc, 0x49, 0x90, 0x4b, 0x49, 0x60, 0x89 }
+ }
+ };
+
+ symmetric_key key;
+ unsigned char tmp[2][16];
+ int i, y;
+
+ for (i = 0; i < (int)(sizeof(tests)/sizeof(tests[0])); i++) {
+ zeromem(&key, sizeof(key));
+ if ((err = aesni_setup(tests[i].key, tests[i].keylen, 0, &key)) != CRYPT_OK) {
+ return err;
+ }
+
+ aesni_ecb_encrypt(tests[i].pt, tmp[0], &key);
+ aesni_ecb_decrypt(tmp[0], tmp[1], &key);
+ if (compare_testvector(tmp[0], 16, tests[i].ct, 16, "AES-NI Encrypt", i) ||
+ compare_testvector(tmp[1], 16, tests[i].pt, 16, "AES-NI Decrypt", i)) {
+ return CRYPT_FAIL_TESTVECTOR;
+ }
+
+ /* now see if we can encrypt all zero bytes 1000 times, decrypt and come back where we started */
+ for (y = 0; y < 16; y++) tmp[0][y] = 0;
+ for (y = 0; y < 1000; y++) aesni_ecb_encrypt(tmp[0], tmp[0], &key);
+ for (y = 0; y < 1000; y++) aesni_ecb_decrypt(tmp[0], tmp[0], &key);
+ for (y = 0; y < 16; y++) if (tmp[0][y] != 0) return CRYPT_FAIL_TESTVECTOR;
+ }
+ return CRYPT_OK;
+ #endif
+}
+
+
+/** Terminate the context
+ @param skey The scheduled key
+*/
+void aesni_done(symmetric_key *skey)
+{
+ LTC_UNUSED_PARAM(skey);
+}
+
+
+/**
+ Gets suitable key size
+ @param keysize [in/out] The length of the recommended key (in bytes). This function will store the suitable size back in this variable.
+ @return CRYPT_OK if the input key size is acceptable.
+*/
+int aesni_keysize(int *keysize)
+{
+ LTC_ARGCHK(keysize != NULL);
+
+ if (*keysize < 16) {
+ return CRYPT_INVALID_KEYSIZE;
+ }
+ if (*keysize < 24) {
+ *keysize = 16;
+ return CRYPT_OK;
+ }
+ if (*keysize < 32) {
+ *keysize = 24;
+ return CRYPT_OK;
+ }
+ *keysize = 32;
+ return CRYPT_OK;
+}
+
+#endif
diff --git a/src/ltc/ciphers/camellia.c b/src/ltc/ciphers/camellia.c
index 7f13f621..733e9639 100644
--- a/src/ltc/ciphers/camellia.c
+++ b/src/ltc/ciphers/camellia.c
@@ -621,6 +621,9 @@ int camellia_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symme
int camellia_test(void)
{
+#ifndef LTC_TEST
+ return CRYPT_NOP;
+#else
static const struct {
int keylen;
unsigned char key[32], pt[16], ct[16];
@@ -697,6 +700,7 @@ int camellia_test(void)
}
}
return CRYPT_OK;
+#endif
}
void camellia_done(symmetric_key *skey)
diff --git a/src/ltc/encauth/gcm/gcm_add_aad.c b/src/ltc/encauth/gcm/gcm_add_aad.c
index 1e71639f..5c3793eb 100644
--- a/src/ltc/encauth/gcm/gcm_add_aad.c
+++ b/src/ltc/encauth/gcm/gcm_add_aad.c
@@ -83,7 +83,7 @@ int gcm_add_aad(gcm_state *gcm,
x = 0;
#ifdef LTC_FAST
- if (gcm->buflen == 0) {
+ if (gcm->buflen == 0 && adatalen > 15) {
for (x = 0; x < (adatalen & ~15); x += 16) {
for (y = 0; y < 16; y += sizeof(LTC_FAST_TYPE)) {
*(LTC_FAST_TYPE_PTR_CAST(&gcm->X[y])) ^= *(LTC_FAST_TYPE_PTR_CAST(&adata[x + y]));
diff --git a/src/ltc/encauth/gcm/gcm_memory.c b/src/ltc/encauth/gcm/gcm_memory.c
index e16f0b88..4da5d542 100644
--- a/src/ltc/encauth/gcm/gcm_memory.c
+++ b/src/ltc/encauth/gcm/gcm_memory.c
@@ -106,6 +106,7 @@ int gcm_memory( int cipher,
err = CRYPT_INVALID_ARG;
}
LTC_ERR:
+ gcm_reset(gcm);
XFREE(orig);
return err;
}
diff --git a/src/ltc/headers/tomcrypt_cfg.h b/src/ltc/headers/tomcrypt_cfg.h
index 994a084b..2a024aa4 100644
--- a/src/ltc/headers/tomcrypt_cfg.h
+++ b/src/ltc/headers/tomcrypt_cfg.h
@@ -3,7 +3,7 @@
/* This is the build config file.
*
- * With this you can setup what to inlcude/exclude automatically during any build. Just comment
+ * With this you can setup what to include/exclude automatically during any build. Just comment
* out the line that #define's the word for the thing you want to remove. phew!
*/
@@ -91,6 +91,11 @@ LTC_EXPORT int LTC_CALL XSTRCMP(const char *s1, const char *s2);
#define ENDIAN_LITTLE
#define ENDIAN_64BITWORD
#define LTC_FAST
+ #if defined(__SSE4_1__)
+ #if __SSE4_1__ == 1
+ #define LTC_AMD64_SSE4_1
+ #endif
+ #endif
#endif
/* detect PPC32 */
@@ -295,6 +300,15 @@ typedef unsigned long ltc_mp_digit;
#define LTC_ALIGN(n)
#endif
+/* Define `LTC_NO_NULL_TERMINATION_CHECK` in the user code
+ * before including `tomcrypt.h` to disable this functionality.
+ */
+#if defined(__GNUC__) && __GNUC__ >= 4 && !defined(LTC_NO_NULL_TERMINATION_CHECK)
+# define LTC_NULL_TERMINATED __attribute__((sentinel))
+#else
+# define LTC_NULL_TERMINATED
+#endif
+
#if defined(__GNUC__) && (__GNUC__ * 100 + __GNUC_MINOR__ >= 405)
# define LTC_DEPRECATED(s) __attribute__((deprecated("replaced by " #s)))
# define PRIVATE_LTC_DEPRECATED_PRAGMA(s) _Pragma(#s)
diff --git a/src/ltc/headers/tomcrypt_cipher.h b/src/ltc/headers/tomcrypt_cipher.h
index a3ba8f30..06e61247 100644
--- a/src/ltc/headers/tomcrypt_cipher.h
+++ b/src/ltc/headers/tomcrypt_cipher.h
@@ -35,8 +35,10 @@ struct saferp_key {
#ifdef LTC_RIJNDAEL
struct rijndael_key {
- ulong32 eK[60], dK[60];
+ ulong32 *eK;
+ ulong32 *dK;
int Nr;
+ unsigned char K[(60 + 60 + 4) * sizeof(ulong32)];
};
#endif
@@ -688,18 +690,19 @@ extern const struct ltc_cipher_descriptor safer_k64_desc, safer_k128_desc, safer
#endif
#ifdef LTC_RIJNDAEL
-
-/* make aes an alias */
-#define aes_setup rijndael_setup
-#define aes_ecb_encrypt rijndael_ecb_encrypt
-#define aes_ecb_decrypt rijndael_ecb_decrypt
-#define aes_test rijndael_test
-#define aes_done rijndael_done
-#define aes_keysize rijndael_keysize
-
-#define aes_enc_setup rijndael_enc_setup
-#define aes_enc_ecb_encrypt rijndael_enc_ecb_encrypt
-#define aes_enc_keysize rijndael_enc_keysize
+/* declare aes properly now */
+int aes_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+int aes_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
+int aes_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
+int aes_test(void);
+void aes_done(symmetric_key *skey);
+int aes_keysize(int *keysize);
+int aes_enc_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+int aes_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
+void aes_enc_done(symmetric_key *skey);
+int aes_enc_keysize(int *keysize);
+extern const struct ltc_cipher_descriptor aes_desc;
+extern const struct ltc_cipher_descriptor aes_enc_desc;
int rijndael_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
int rijndael_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
@@ -711,8 +714,19 @@ int rijndael_enc_setup(const unsigned char *key, int keylen, int num_rounds, sym
int rijndael_enc_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
void rijndael_enc_done(symmetric_key *skey);
int rijndael_enc_keysize(int *keysize);
-extern const struct ltc_cipher_descriptor rijndael_desc, aes_desc;
-extern const struct ltc_cipher_descriptor rijndael_enc_desc, aes_enc_desc;
+extern const struct ltc_cipher_descriptor rijndael_desc;
+extern const struct ltc_cipher_descriptor rijndael_enc_desc;
+#endif
+
+#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
+int aesni_is_supported(void);
+int aesni_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey);
+int aesni_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey);
+int aesni_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey);
+int aesni_test(void);
+void aesni_done(symmetric_key *skey);
+int aesni_keysize(int *keysize);
+extern const struct ltc_cipher_descriptor aesni_desc;
#endif
#ifdef LTC_XTEA
diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h
index b13c2e08..f0a65fef 100644
--- a/src/ltc/headers/tomcrypt_custom.h
+++ b/src/ltc/headers/tomcrypt_custom.h
@@ -114,7 +114,7 @@
#define LTC_NO_MISC
#define LTC_BASE64
-#endif
+#endif /* LTC_EASY */
/* The minimal set of functionality to run the tests */
#ifdef LTC_MINIMAL
@@ -129,7 +129,7 @@
#define LTC_TRY_URANDOM_FIRST
#undef LTC_NO_FILE
-#endif
+#endif /* LTC_MINIMAL */
/* Enable self-test test vector checking */
#ifndef LTC_NO_TEST
@@ -179,6 +179,7 @@
#define LTC_RC6
#define LTC_SAFERP
#define LTC_RIJNDAEL
+#define LTC_AES_NI
#define LTC_XTEA
/* _TABLES tells it to use tables during setup, _SMALL means to use the smaller scheduled key format
* (saves 4KB of ram), _ALL_TABLES enables all tables during setup */
@@ -357,7 +358,7 @@
#define LTC_YARROW_AES 2
#endif
-#endif
+#endif /* LTC_YARROW */
#ifdef LTC_FORTUNA
@@ -553,7 +554,7 @@
#define LTC_ECC_SECP384R1
#define LTC_ECC_SECP521R1
#endif
-#endif
+#endif /* LTC_MECC */
#if defined(LTC_DER)
#ifndef LTC_DER_MAX_RECURSION
@@ -690,15 +691,13 @@
#define LTC_MUTEX_UNLOCK(x)
#define LTC_MUTEX_DESTROY(x)
-#endif
+#endif /* LTC_PTHREAD */
/* Debuggers */
/* define this if you use Valgrind, note: it CHANGES the way SOBER-128 and RC4 work (see the code) */
/* #define LTC_VALGRIND */
-#endif
-
#ifndef LTC_NO_FILE
/* buffer size for reading from a file via fread(..) */
#ifndef LTC_FILE_READ_BUFSIZE
@@ -739,3 +738,5 @@
#define LTC_ECC_SECP521R1
#undef LTC_ECC521
#endif
+
+#endif /* TOMCRYPT_CUSTOM_H_ */
diff --git a/src/ltc/headers/tomcrypt_hash.h b/src/ltc/headers/tomcrypt_hash.h
index 4eb07126..3c4bcf5a 100644
--- a/src/ltc/headers/tomcrypt_hash.h
+++ b/src/ltc/headers/tomcrypt_hash.h
@@ -494,7 +494,8 @@ int hash_memory(int hash,
const unsigned char *in, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
int hash_memory_multi(int hash, unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
#ifndef LTC_NO_FILE
int hash_filehandle(int hash, FILE *in, unsigned char *out, unsigned long *outlen);
diff --git a/src/ltc/headers/tomcrypt_mac.h b/src/ltc/headers/tomcrypt_mac.h
index 549903c2..c8f4a322 100644
--- a/src/ltc/headers/tomcrypt_mac.h
+++ b/src/ltc/headers/tomcrypt_mac.h
@@ -19,7 +19,8 @@ int hmac_memory(int hash,
int hmac_memory_multi(int hash,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int hmac_file(int hash, const char *fname, const unsigned char *key,
unsigned long keylen,
unsigned char *out, unsigned long *outlen);
@@ -47,7 +48,8 @@ int omac_memory(int cipher,
int omac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int omac_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
@@ -83,7 +85,8 @@ int pmac_memory(int cipher,
int pmac_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int pmac_file(int cipher,
const unsigned char *key, unsigned long keylen,
@@ -112,7 +115,10 @@ int poly1305_init(poly1305_state *st, const unsigned char *key, unsigned long ke
int poly1305_process(poly1305_state *st, const unsigned char *in, unsigned long inlen);
int poly1305_done(poly1305_state *st, unsigned char *mac, unsigned long *maclen);
int poly1305_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int poly1305_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
+int poly1305_memory_multi(const unsigned char *key, unsigned long keylen,
+ unsigned char *mac, unsigned long *maclen,
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int poly1305_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int poly1305_test(void);
#endif /* LTC_POLY1305 */
@@ -123,7 +129,10 @@ int blake2smac_init(blake2smac_state *st, unsigned long outlen, const unsigned c
int blake2smac_process(blake2smac_state *st, const unsigned char *in, unsigned long inlen);
int blake2smac_done(blake2smac_state *st, unsigned char *mac, unsigned long *maclen);
int blake2smac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
+int blake2smac_memory_multi(const unsigned char *key, unsigned long keylen,
+ unsigned char *mac, unsigned long *maclen,
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int blake2smac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int blake2smac_test(void);
#endif /* LTC_BLAKE2SMAC */
@@ -134,7 +143,10 @@ int blake2bmac_init(blake2bmac_state *st, unsigned long outlen, const unsigned c
int blake2bmac_process(blake2bmac_state *st, const unsigned char *in, unsigned long inlen);
int blake2bmac_done(blake2bmac_state *st, unsigned char *mac, unsigned long *maclen);
int blake2bmac_memory(const unsigned char *key, unsigned long keylen, const unsigned char *in, unsigned long inlen, unsigned char *mac, unsigned long *maclen);
-int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen, const unsigned char *in, unsigned long inlen, ...);
+int blake2bmac_memory_multi(const unsigned char *key, unsigned long keylen,
+ unsigned char *mac, unsigned long *maclen,
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int blake2bmac_file(const char *fname, const unsigned char *key, unsigned long keylen, unsigned char *mac, unsigned long *maclen);
int blake2bmac_test(void);
#endif /* LTC_BLAKE2BMAC */
@@ -186,7 +198,8 @@ int xcbc_memory(int cipher,
int xcbc_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int xcbc_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *filename,
@@ -220,7 +233,8 @@ int f9_memory(int cipher,
int f9_memory_multi(int cipher,
const unsigned char *key, unsigned long keylen,
unsigned char *out, unsigned long *outlen,
- const unsigned char *in, unsigned long inlen, ...);
+ const unsigned char *in, unsigned long inlen, ...)
+ LTC_NULL_TERMINATED;
int f9_file(int cipher,
const unsigned char *key, unsigned long keylen,
const char *fname,
diff --git a/src/ltc/headers/tomcrypt_macros.h b/src/ltc/headers/tomcrypt_macros.h
index 94aa7c32..257f5238 100644
--- a/src/ltc/headers/tomcrypt_macros.h
+++ b/src/ltc/headers/tomcrypt_macros.h
@@ -1,6 +1,11 @@
/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
/* SPDX-License-Identifier: Unlicense */
+
+#define LTC_TMPVAR__(n, l) n ## l
+#define LTC_TMPVAR_(n, l) LTC_TMPVAR__(n, l)
+#define LTC_TMPVAR(n) LTC_TMPVAR_(LTC_ ## n ## _, __LINE__)
+
/* ---- HELPER MACROS ---- */
#ifdef ENDIAN_NEUTRAL
@@ -275,20 +280,20 @@ static inline ulong32 ROR(ulong32 word, int i)
#ifndef LTC_NO_ROLC
#define ROLc(word,i) ({ \
- ulong32 ROLc_tmp = (word); \
+ ulong32 LTC_TMPVAR(ROLc) = (word); \
__asm__ ("roll %2, %0" : \
- "=r" (ROLc_tmp) : \
- "0" (ROLc_tmp), \
+ "=r" (LTC_TMPVAR(ROLc)) : \
+ "0" (LTC_TMPVAR(ROLc)), \
"I" (i)); \
- ROLc_tmp; \
+ LTC_TMPVAR(ROLc); \
})
#define RORc(word,i) ({ \
- ulong32 RORc_tmp = (word); \
+ ulong32 LTC_TMPVAR(RORc) = (word); \
__asm__ ("rorl %2, %0" : \
- "=r" (RORc_tmp) : \
- "0" (RORc_tmp), \
+ "=r" (LTC_TMPVAR(RORc)) : \
+ "0" (LTC_TMPVAR(RORc)), \
"I" (i)); \
- RORc_tmp; \
+ LTC_TMPVAR(RORc); \
})
#else
@@ -393,20 +398,20 @@ static inline ulong64 ROR64(ulong64 word, int i)
#ifndef LTC_NO_ROLC
#define ROL64c(word,i) ({ \
- ulong64 ROL64c_tmp = word; \
+ ulong64 LTC_TMPVAR(ROL64c) = word; \
__asm__ ("rolq %2, %0" : \
- "=r" (ROL64c_tmp) : \
- "0" (ROL64c_tmp), \
+ "=r" (LTC_TMPVAR(ROL64c)) : \
+ "0" (LTC_TMPVAR(ROL64c)), \
"J" (i)); \
- ROL64c_tmp; \
+ LTC_TMPVAR(ROL64c); \
})
#define ROR64c(word,i) ({ \
- ulong64 ROR64c_tmp = word; \
+ ulong64 LTC_TMPVAR(ROR64c) = word; \
__asm__ ("rorq %2, %0" : \
- "=r" (ROR64c_tmp) : \
- "0" (ROR64c_tmp), \
+ "=r" (LTC_TMPVAR(ROR64c)) : \
+ "0" (LTC_TMPVAR(ROR64c)), \
"J" (i)); \
- ROR64c_tmp; \
+ LTC_TMPVAR(ROR64c); \
})
#else /* LTC_NO_ROLC */
diff --git a/src/ltc/headers/tomcrypt_math.h b/src/ltc/headers/tomcrypt_math.h
index bb49915f..b7dedf6b 100644
--- a/src/ltc/headers/tomcrypt_math.h
+++ b/src/ltc/headers/tomcrypt_math.h
@@ -502,9 +502,9 @@ typedef struct {
extern ltc_math_descriptor ltc_mp;
-int ltc_init_multi(void **a, ...);
-void ltc_deinit_multi(void *a, ...);
-void ltc_cleanup_multi(void **a, ...);
+int ltc_init_multi(void **a, ...) LTC_NULL_TERMINATED;
+void ltc_deinit_multi(void *a, ...) LTC_NULL_TERMINATED;
+void ltc_cleanup_multi(void **a, ...) LTC_NULL_TERMINATED;
#ifdef LTM_DESC
extern const ltc_math_descriptor ltm_desc;
diff --git a/src/ltc/headers/tomcrypt_misc.h b/src/ltc/headers/tomcrypt_misc.h
index ae861fe3..3a2b7b12 100644
--- a/src/ltc/headers/tomcrypt_misc.h
+++ b/src/ltc/headers/tomcrypt_misc.h
@@ -93,7 +93,7 @@ const char *error_to_string(int err);
extern const char *crypt_build_settings;
/* ---- HMM ---- */
-int crypt_fsa(void *mp, ...);
+int crypt_fsa(void *mp, ...) LTC_NULL_TERMINATED;
/* ---- Dynamic language support ---- */
int crypt_get_constant(const char* namein, int *valueout);
@@ -146,6 +146,7 @@ enum padding_type {
LTC_PAD_ISO_10126 = 0x1000U,
#endif
LTC_PAD_ANSI_X923 = 0x2000U,
+ LTC_PAD_SSH = 0x3000U,
/* The following padding modes don't contain the padding
* length as last byte of the padding.
*/
@@ -171,8 +172,8 @@ typedef enum ssh_data_type_ {
} ssh_data_type;
/* VA list handy helpers with tuples of <type, data> */
-int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
-int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...);
+int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) LTC_NULL_TERMINATED;
+int ssh_decode_sequence_multi(const unsigned char *in, unsigned long *inlen, ...) LTC_NULL_TERMINATED;
#endif /* LTC_SSH */
int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which);
diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h
index 167789e4..903e118d 100644
--- a/src/ltc/headers/tomcrypt_pk.h
+++ b/src/ltc/headers/tomcrypt_pk.h
@@ -355,13 +355,31 @@ int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
curve25519_key *key);
-int ed25519_sign(const unsigned char *msg, unsigned long msglen,
- unsigned char *sig, unsigned long *siglen,
+int ed25519_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
const curve25519_key *private_key);
-
+int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ const curve25519_key *private_key);
+int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ const curve25519_key *private_key);
int ed25519_verify(const unsigned char *msg, unsigned long msglen,
const unsigned char *sig, unsigned long siglen,
- int *stat, const curve25519_key *public_key);
+ int *stat,
+ const curve25519_key *public_key);
+int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ int *stat,
+ const curve25519_key *public_key);
+int ed25519ph_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ int *stat,
+ const curve25519_key *public_key);
/** X25519 Key-Exchange API */
int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key);
@@ -530,43 +548,43 @@ typedef struct ltc_asn1_list_ {
struct ltc_asn1_list_ *prev, *next, *child, *parent;
} ltc_asn1_list;
-#define LTC_SET_ASN1(list, index, Type, Data, Size) \
- do { \
- int LTC_MACRO_temp = (index); \
- ltc_asn1_list *LTC_MACRO_list = (list); \
- LTC_MACRO_list[LTC_MACRO_temp].type = (Type); \
- LTC_MACRO_list[LTC_MACRO_temp].data = (void*)(Data); \
- LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \
- LTC_MACRO_list[LTC_MACRO_temp].used = 0; \
- LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \
- LTC_MACRO_list[LTC_MACRO_temp].klass = 0; \
- LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \
- LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \
+#define LTC_SET_ASN1(list, index, Type, Data, Size) \
+ do { \
+ int LTC_TMPVAR(SA) = (index); \
+ ltc_asn1_list *LTC_TMPVAR(SA_list) = (list); \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].type = (Type); \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].data = (void*)(Data); \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].size = (Size); \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].used = 0; \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].optional = 0; \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].klass = 0; \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].pc = 0; \
+ LTC_TMPVAR(SA_list)[LTC_TMPVAR(SA)].tag = 0; \
} while (0)
-#define LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \
- do { \
- int LTC_MACRO_temp = (index); \
- ltc_asn1_list *LTC_MACRO_list = (list); \
- LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \
- LTC_MACRO_list[LTC_MACRO_temp].klass = (Class); \
- LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \
- LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \
+#define LTC_SET_ASN1_IDENTIFIER(list, index, Class, Pc, Tag) \
+ do { \
+ int LTC_TMPVAR(SAI) = (index); \
+ ltc_asn1_list *LTC_TMPVAR(SAI_list) = (list); \
+ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].type = LTC_ASN1_CUSTOM_TYPE; \
+ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].klass = (Class); \
+ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].pc = (Pc); \
+ LTC_TMPVAR(SAI_list)[LTC_TMPVAR(SAI)].tag = (Tag); \
} while (0)
-#define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \
- do { \
- int LTC_MACRO_temp##__LINE__ = (index); \
- LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, 1); \
- LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \
+#define LTC_SET_ASN1_CUSTOM_CONSTRUCTED(list, index, Class, Tag, Data) \
+ do { \
+ int LTC_TMPVAR(SACC) = (index); \
+ LTC_SET_ASN1(list, LTC_TMPVAR(SACC), LTC_ASN1_CUSTOM_TYPE, Data, 1); \
+ LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(SACC), Class, LTC_ASN1_PC_CONSTRUCTED, Tag); \
} while (0)
-#define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \
- do { \
- int LTC_MACRO_temp##__LINE__ = (index); \
- LTC_SET_ASN1(list, LTC_MACRO_temp##__LINE__, LTC_ASN1_CUSTOM_TYPE, Data, Size); \
- LTC_SET_ASN1_IDENTIFIER(list, LTC_MACRO_temp##__LINE__, Class, LTC_ASN1_PC_PRIMITIVE, Tag); \
- list[LTC_MACRO_temp##__LINE__].used = (int)(Type); \
+#define LTC_SET_ASN1_CUSTOM_PRIMITIVE(list, index, Class, Tag, Type, Data, Size) \
+ do { \
+ int LTC_TMPVAR(SACP) = (index); \
+ LTC_SET_ASN1(list, LTC_TMPVAR(SACP), LTC_ASN1_CUSTOM_TYPE, Data, Size); \
+ LTC_SET_ASN1_IDENTIFIER(list, LTC_TMPVAR(SACP), Class, LTC_ASN1_PC_PRIMITIVE, Tag); \
+ list[LTC_TMPVAR(SACP)].used = (int)(Type); \
} while (0)
extern const char* der_asn1_class_to_string_map[];
@@ -636,8 +654,8 @@ int der_encode_setof(const ltc_asn1_list *list, unsigned long inlen,
unsigned char *out, unsigned long *outlen);
/* VA list handy helpers with triplets of <type, size, data> */
-int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...);
-int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...);
+int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...) LTC_NULL_TERMINATED;
+int der_decode_sequence_multi(const unsigned char *in, unsigned long inlen, ...) LTC_NULL_TERMINATED;
/* FLEXI DECODER handle unknown list decoder */
int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc_asn1_list **out);
diff --git a/src/ltc/headers/tomcrypt_private.h b/src/ltc/headers/tomcrypt_private.h
index 7c1e1724..aa251e2a 100644
--- a/src/ltc/headers/tomcrypt_private.h
+++ b/src/ltc/headers/tomcrypt_private.h
@@ -9,17 +9,25 @@
#define LTC_PAD_MASK (0xF000U)
+/* `NULL` as defined by the standard is not guaranteed to be of a pointer
+ * type. In order to make sure that in vararg API's a pointer type is used,
+ * define our own version and use that one internally.
+ */
+#ifndef LTC_NULL
+ #define LTC_NULL ((void *)0)
+#endif
+
/*
* Internal Enums
*/
enum ltc_oid_id {
- PKA_RSA,
- PKA_DSA,
- PKA_EC,
- PKA_EC_PRIMEF,
- PKA_X25519,
- PKA_ED25519,
+ LTC_OID_RSA,
+ LTC_OID_DSA,
+ LTC_OID_EC,
+ LTC_OID_EC_PRIMEF,
+ LTC_OID_X25519,
+ LTC_OID_ED25519,
};
/*
@@ -69,6 +77,10 @@ typedef struct
/* tomcrypt_cipher.h */
+#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
+#define LTC_HAS_AES_NI
+#endif
+
void blowfish_enc(ulong32 *data, unsigned long blocks, const symmetric_key *skey);
int blowfish_expand(const unsigned char *key, int keylen,
const unsigned char *data, int datalen,
@@ -90,7 +102,8 @@ int func_name (hash_state * md, const unsigned char *in, unsigned long inlen)
if (md-> state_var .curlen > sizeof(md-> state_var .buf)) { \
return CRYPT_INVALID_ARG; \
} \
- if ((md-> state_var .length + inlen * 8) < md-> state_var .length) { \
+ if (((md-> state_var .length + inlen * 8) < md-> state_var .length) \
+ || ((inlen * 8) < inlen)) { \
return CRYPT_HASH_OVERFLOW; \
} \
while (inlen > 0) { \
@@ -202,6 +215,17 @@ void ocb3_int_xor_blocks(unsigned char *out, const unsigned char *block_a, const
/* tomcrypt_misc.h */
+typedef enum {
+ /** Use `\r\n` as line separator */
+ BASE64_PEM_CRLF = 1,
+ /** Create output with 72 chars line length */
+ BASE64_PEM_SSH = 2,
+} base64_pem_flags;
+
+int base64_encode_pem(const unsigned char *in, unsigned long inlen,
+ char *out, unsigned long *outlen,
+ unsigned int flags);
+
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);
@@ -225,6 +249,7 @@ int rsa_init(rsa_key *key);
void rsa_shrink_key(rsa_key *key);
int rsa_make_key_bn_e(prng_state *prng, int wprng, int size, void *e,
rsa_key *key); /* used by op-tee */
+int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key);
#endif /* LTC_MRSA */
/* ---- DH Routines ---- */
@@ -318,16 +343,19 @@ int dsa_int_validate_primes(const dsa_key *key, int *stat);
int tweetnacl_crypto_sign(
unsigned char *sm,unsigned long long *smlen,
const unsigned char *m,unsigned long long mlen,
- const unsigned char *sk, const unsigned char *pk);
+ const unsigned char *sk,const unsigned char *pk,
+ const unsigned char *ctx,unsigned long long cs);
int tweetnacl_crypto_sign_open(
int *stat,
unsigned char *m,unsigned long long *mlen,
const unsigned char *sm,unsigned long long smlen,
+ const unsigned char *ctx, unsigned long long cs,
const unsigned char *pk);
int tweetnacl_crypto_sign_keypair(prng_state *prng, int wprng, unsigned char *pk,unsigned char *sk);
int tweetnacl_crypto_sk_to_pk(unsigned char *pk, const unsigned char *sk);
int tweetnacl_crypto_scalarmult(unsigned char *q, const unsigned char *n, const unsigned char *p);
int tweetnacl_crypto_scalarmult_base(unsigned char *q,const unsigned char *n);
+int tweetnacl_crypto_ph(unsigned char *out, const unsigned char *msg, unsigned long long msglen);
typedef int (*sk_to_pk)(unsigned char *pk ,const unsigned char *sk);
int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
@@ -337,6 +365,9 @@ int ec25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
int ec25519_export( unsigned char *out, unsigned long *outlen,
int which,
const curve25519_key *key);
+int ec25519_crypto_ctx( unsigned char *out, unsigned long *outlen,
+ unsigned char flag,
+ const unsigned char *ctx, unsigned long ctxlen);
#endif /* LTC_CURVE25519 */
#ifdef LTC_DER
@@ -365,7 +396,8 @@ extern const unsigned long der_asn1_tag_to_type_map_sz;
extern const int der_asn1_type_to_identifier_map[];
extern const unsigned long der_asn1_type_to_identifier_map_sz;
-int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...);
+int der_decode_sequence_multi_ex(const unsigned char *in, unsigned long inlen, unsigned int flags, ...)
+ LTC_NULL_TERMINATED;
int der_teletex_char_encode(int c);
int der_teletex_value_decode(int v);
diff --git a/src/ltc/math/fp/ltc_ecc_fp_mulmod.c b/src/ltc/math/fp/ltc_ecc_fp_mulmod.c
index 180b1e2c..5827bf3b 100644
--- a/src/ltc/math/fp/ltc_ecc_fp_mulmod.c
+++ b/src/ltc/math/fp/ltc_ecc_fp_mulmod.c
@@ -1544,7 +1544,7 @@ int ltc_ecc_fp_restore_state(unsigned char *in, unsigned long inlen)
goto ERR_OUT;
}
fp_cache[i].LUT[x] = p;
- if ((err = mp_init_multi(&p->x, &p->y, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&p->x, &p->y, LTC_NULL)) != CRYPT_OK) {
goto ERR_OUT;
}
p->z = NULL;
diff --git a/src/ltc/misc/base64/base64_encode.c b/src/ltc/misc/base64/base64_encode.c
index ad512d83..ef8aee90 100644
--- a/src/ltc/misc/base64/base64_encode.c
+++ b/src/ltc/misc/base64/base64_encode.c
@@ -21,23 +21,45 @@ static const char * const codes_base64url =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
#endif /* LTC_BASE64_URL */
-static int s_base64_encode_internal(const unsigned char *in, unsigned long inlen,
- char *out, unsigned long *outlen,
- const char *codes, int pad)
+enum mode {
+ nopad = 0,
+ pad = 1,
+ lf = 2,
+ cr = 4,
+ ssh = 8,
+ crlf = lf | cr,
+};
+
+static int s_base64_encode_internal(const unsigned char *in, unsigned long inlen,
+ char *out, unsigned long *outlen,
+ const char *codes, unsigned int mode)
{
- unsigned long i, len2, leven;
+ unsigned long i, len2, leven, linelen;
char *p;
- LTC_ARGCHK(in != NULL);
- LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
+ linelen = (mode & ssh) ? 72 : 64;
+
/* valid output size ? */
len2 = 4 * ((inlen + 2) / 3);
+ if ((mode & crlf) == lf) {
+ len2 += len2 / linelen;
+ } else if ((mode & crlf) == crlf) {
+ len2 += (len2 / linelen) * 2;
+ }
if (*outlen < len2 + 1) {
*outlen = len2 + 1;
return CRYPT_BUFFER_OVERFLOW;
}
+
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(out != NULL);
+
+ if ((void*)in == out) {
+ return CRYPT_INVALID_ARG;
+ }
+
p = out;
leven = 3*(inlen / 3);
for (i = 0; i < leven; i += 3) {
@@ -46,6 +68,10 @@ static int s_base64_encode_internal(const unsigned char *in, unsigned long inle
*p++ = codes[(((in[1] & 0xf) << 2) + (in[2] >> 6)) & 0x3F];
*p++ = codes[in[2] & 0x3F];
in += 3;
+ if ((p - out) % linelen == 0) {
+ if (mode & cr) *p++ = '\r';
+ if (mode & lf) *p++ = '\n';
+ }
}
/* Pad it if necessary... */
if (i < inlen) {
@@ -54,7 +80,7 @@ static int s_base64_encode_internal(const unsigned char *in, unsigned long inle
*p++ = codes[(a >> 2) & 0x3F];
*p++ = codes[(((a & 3) << 4) + (b >> 4)) & 0x3F];
- if (pad) {
+ if (mode & pad) {
*p++ = (i+1 < inlen) ? codes[(((b & 0xf) << 2)) & 0x3F] : '=';
*p++ = '=';
}
@@ -83,7 +109,26 @@ static int s_base64_encode_internal(const unsigned char *in, unsigned long inle
int base64_encode(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen)
{
- return s_base64_encode_internal(in, inlen, out, outlen, codes_base64, 1);
+ return s_base64_encode_internal(in, inlen, out, outlen, codes_base64, pad);
+}
+
+/**
+ base64 Encode a buffer for PEM output
+ (NUL terminated with line-break at 64 chars)
+ @param in The input buffer to encode
+ @param inlen The length of the input buffer
+ @param out [out] The destination of the base64 encoded data
+ @param outlen [in/out] The max size and resulting size
+ @param flags \ref base64_pem_flags
+ @return CRYPT_OK if successful
+*/
+int base64_encode_pem(const unsigned char *in, unsigned long inlen,
+ char *out, unsigned long *outlen,
+ unsigned int flags)
+{
+ int use_crlf = flags & BASE64_PEM_CRLF ? pad | crlf : pad | lf;
+ int ssh_style = flags & BASE64_PEM_SSH ? ssh : 0;
+ return s_base64_encode_internal(in, inlen, out, outlen, codes_base64, ssh_style | use_crlf);
}
#endif /* LTC_BASE64 */
@@ -100,13 +145,13 @@ int base64_encode(const unsigned char *in, unsigned long inlen,
int base64url_encode(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen)
{
- return s_base64_encode_internal(in, inlen, out, outlen, codes_base64url, 0);
+ return s_base64_encode_internal(in, inlen, out, outlen, codes_base64url, nopad);
}
int base64url_strict_encode(const unsigned char *in, unsigned long inlen,
char *out, unsigned long *outlen)
{
- return s_base64_encode_internal(in, inlen, out, outlen, codes_base64url, 1);
+ return s_base64_encode_internal(in, inlen, out, outlen, codes_base64url, pad);
}
#endif /* LTC_BASE64_URL */
diff --git a/src/ltc/misc/bcrypt/bcrypt.c b/src/ltc/misc/bcrypt/bcrypt.c
index e1974f6a..1bebdffa 100644
--- a/src/ltc/misc/bcrypt/bcrypt.c
+++ b/src/ltc/misc/bcrypt/bcrypt.c
@@ -139,7 +139,7 @@ int bcrypt_pbkdf_openbsd(const void *secret, unsigned long secret_len,
if ((err = hash_memory_multi(hash_idx, buf[0], &x,
salt, salt_len,
blkbuf, 4uL,
- NULL, 0)) != CRYPT_OK) {
+ LTC_NULL)) != CRYPT_OK) {
goto LBL_ERR;
}
y = MAXBLOCKSIZE;
diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c
index 14576fa7..460cd59d 100644
--- a/src/ltc/misc/crypt/crypt.c
+++ b/src/ltc/misc/crypt/crypt.c
@@ -416,6 +416,9 @@ const char *crypt_build_settings =
#if defined(LTC_ADLER32)
" ADLER32 "
#endif
+#if defined(LTC_AES_NI) && defined(LTC_AMD64_SSE4_1)
+ " AES-NI "
+#endif
#if defined(LTC_BASE64)
" BASE64 "
#endif
diff --git a/src/ltc/misc/crypt/crypt_register_all_ciphers.c b/src/ltc/misc/crypt/crypt_register_all_ciphers.c
index bb2b873e..bfed2e68 100644
--- a/src/ltc/misc/crypt/crypt_register_all_ciphers.c
+++ b/src/ltc/misc/crypt/crypt_register_all_ciphers.c
@@ -16,6 +16,7 @@
int register_all_ciphers(void)
{
#ifdef LTC_RIJNDAEL
+ /* `aesni_desc` is explicitely not registered, since it's handled from within the `aes_desc` */
#ifdef ENCRYPT_ONLY
/* alternative would be
* register_cipher(&rijndael_enc_desc);
diff --git a/src/ltc/misc/padding/padding_depad.c b/src/ltc/misc/padding/padding_depad.c
index 7489de12..e3f71511 100644
--- a/src/ltc/misc/padding/padding_depad.c
+++ b/src/ltc/misc/padding/padding_depad.c
@@ -53,6 +53,12 @@ int padding_depad(const unsigned char *data, unsigned long *length, unsigned lon
/* nop */
break;
#endif
+ case LTC_PAD_SSH:
+ pad = 0x1;
+ for (n = unpadded_length; n < padded_length; ++n) {
+ if (data[n] != pad++) return CRYPT_INVALID_PACKET;
+ }
+ break;
case LTC_PAD_ONE_AND_ZERO:
while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) {
if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET;
diff --git a/src/ltc/misc/padding/padding_pad.c b/src/ltc/misc/padding/padding_pad.c
index 8a775b3d..7d8bbbad 100644
--- a/src/ltc/misc/padding/padding_pad.c
+++ b/src/ltc/misc/padding/padding_pad.c
@@ -32,6 +32,7 @@ static int s_padding_padded_length(unsigned long *length, unsigned long mode)
case LTC_PAD_PKCS7:
case LTC_PAD_ONE_AND_ZERO:
case LTC_PAD_ZERO_ALWAYS:
+ case LTC_PAD_SSH:
t = 1;
break;
#ifdef LTC_RNG_GET_BYTES
@@ -78,10 +79,10 @@ static int s_padding_padded_length(unsigned long *length, unsigned long mode)
*/
int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode)
{
- unsigned long l;
+ unsigned long l, n;
enum padding_type type;
int err;
- unsigned char diff;
+ unsigned char diff, pad;
LTC_ARGCHK(data != NULL);
LTC_ARGCHK(padded_length != NULL);
@@ -125,6 +126,12 @@ int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded
XMEMSET(&data[length], 0, diff-1);
data[l-1] = diff;
break;
+ case LTC_PAD_SSH:
+ pad = 0x1;
+ for (n = length; n < l; ++n) {
+ data[n] = pad++;
+ }
+ break;
case LTC_PAD_ONE_AND_ZERO:
XMEMSET(&data[length + 1], 0, diff);
data[length] = 0x80;
diff --git a/src/ltc/misc/pkcs12/pkcs12_kdf.c b/src/ltc/misc/pkcs12/pkcs12_kdf.c
index 6bbdd168..1739af73 100644
--- a/src/ltc/misc/pkcs12/pkcs12_kdf.c
+++ b/src/ltc/misc/pkcs12/pkcs12_kdf.c
@@ -39,7 +39,7 @@ int pkcs12_kdf( int hash_id,
for (i = 0; i < c; i++) {
Alen = sizeof(A);
- err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */
+ err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, LTC_NULL); /* A = HASH(D || I) */
if (err != CRYPT_OK) goto DONE;
for (j = 1; j < iterations; j++) {
err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */
diff --git a/src/ltc/misc/ssh/ssh_encode_sequence_multi.c b/src/ltc/misc/ssh/ssh_encode_sequence_multi.c
index d2be6897..4bec5e12 100644
--- a/src/ltc/misc/ssh/ssh_encode_sequence_multi.c
+++ b/src/ltc/misc/ssh/ssh_encode_sequence_multi.c
@@ -134,7 +134,7 @@ int ssh_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
STORE32H(size, out);
out += 4;
}
- if ((err = mp_to_unsigned_bin(vdata, out)) != CRYPT_OK) {
+ if (mp_to_unsigned_bin(vdata, out) != CRYPT_OK) {
err = CRYPT_ERROR;
goto error;
}
diff --git a/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c b/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c
index 2e21b4aa..586fb316 100644
--- a/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c
+++ b/src/ltc/pk/asn1/der/custom_type/der_encode_custom_type.c
@@ -36,7 +36,7 @@ int der_encode_custom_type(const ltc_asn1_list *root,
/* get size of output that will be required */
y = 0; z = 0;
- if ((err = der_length_custom_type(root, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG;
+ if (der_length_custom_type(root, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
/* too big ? */
if (*outlen < y) {
@@ -46,7 +46,7 @@ int der_encode_custom_type(const ltc_asn1_list *root,
}
/* get length of the identifier, so we know the offset where to start writing */
- if ((err = der_length_asn1_identifier(root, &id_len)) != CRYPT_OK) return CRYPT_INVALID_ARG;
+ if (der_length_asn1_identifier(root, &id_len) != CRYPT_OK) return CRYPT_INVALID_ARG;
x = id_len;
diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c
index 8807e910..776c2ed7 100644
--- a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c
+++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_multi.c
@@ -34,15 +34,16 @@ static int s_der_decode_sequence_va(const unsigned char *in, unsigned long inlen
x = 0;
for (;;) {
type = (ltc_asn1_type)va_arg(a1, int);
- size = va_arg(a1, unsigned long);
- data = va_arg(a1, void*);
- LTC_UNUSED_PARAM(size);
- LTC_UNUSED_PARAM(data);
if (type == LTC_ASN1_EOL) {
break;
}
+ size = va_arg(a1, unsigned long);
+ data = va_arg(a1, void*);
+ LTC_UNUSED_PARAM(size);
+ LTC_UNUSED_PARAM(data);
+
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c
index d5c81bbd..2ea33a6d 100644
--- a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c
+++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_ex.c
@@ -33,7 +33,7 @@ int der_encode_sequence_ex(const ltc_asn1_list *list, unsigned long inlen,
/* get size of output that will be required */
y = 0; z = 0;
- if ((err = der_length_sequence_ex(list, inlen, &y, &z)) != CRYPT_OK) return CRYPT_INVALID_ARG;
+ if (der_length_sequence_ex(list, inlen, &y, &z) != CRYPT_OK) return CRYPT_INVALID_ARG;
/* too big ? */
if (*outlen < y) {
diff --git a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c
index c0dc09b4..615488d7 100644
--- a/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c
+++ b/src/ltc/pk/asn1/der/sequence/der_encode_sequence_multi.c
@@ -35,15 +35,16 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
x = 0;
for (;;) {
type = (ltc_asn1_type)va_arg(args, int);
- size = va_arg(args, unsigned long);
- data = va_arg(args, void*);
- LTC_UNUSED_PARAM(size);
- LTC_UNUSED_PARAM(data);
if (type == LTC_ASN1_EOL) {
break;
}
+ size = va_arg(args, unsigned long);
+ data = va_arg(args, void*);
+ LTC_UNUSED_PARAM(size);
+ LTC_UNUSED_PARAM(data);
+
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
@@ -89,13 +90,14 @@ int der_encode_sequence_multi(unsigned char *out, unsigned long *outlen, ...)
x = 0;
for (;;) {
type = (ltc_asn1_type)va_arg(args, int);
- size = va_arg(args, unsigned long);
- data = va_arg(args, void*);
if (type == LTC_ASN1_EOL) {
break;
}
+ size = va_arg(args, unsigned long);
+ data = va_arg(args, void*);
+
switch (type) {
case LTC_ASN1_BOOLEAN:
case LTC_ASN1_INTEGER:
diff --git a/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c b/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c
index e596e072..e00702d1 100644
--- a/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c
+++ b/src/ltc/pk/asn1/der/short_integer/der_decode_short_integer.c
@@ -42,6 +42,10 @@ int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsig
return CRYPT_INVALID_PACKET;
}
+ if (len > sizeof(unsigned long)) {
+ return CRYPT_OVERFLOW;
+ }
+
/* read number */
y = 0;
while (len--) {
diff --git a/src/ltc/pk/asn1/oid/pk_get_oid.c b/src/ltc/pk/asn1/oid/pk_get_oid.c
index 618cc801..b3e1ee26 100644
--- a/src/ltc/pk/asn1/oid/pk_get_oid.c
+++ b/src/ltc/pk/asn1/oid/pk_get_oid.c
@@ -10,12 +10,12 @@ typedef struct {
} 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" },
- { PKA_X25519, "1.3.101.110" },
- { PKA_ED25519, "1.3.101.112" },
+ { LTC_OID_RSA, "1.2.840.113549.1.1.1" },
+ { LTC_OID_DSA, "1.2.840.10040.4.1" },
+ { LTC_OID_EC, "1.2.840.10045.2.1" },
+ { LTC_OID_EC_PRIMEF, "1.2.840.10045.1.1" },
+ { LTC_OID_X25519, "1.3.101.110" },
+ { LTC_OID_ED25519, "1.3.101.112" },
};
/*
diff --git a/src/ltc/pk/asn1/oid/pk_oid_str.c b/src/ltc/pk/asn1/oid/pk_oid_str.c
index aa889631..bc21a6f5 100644
--- a/src/ltc/pk/asn1/oid/pk_oid_str.c
+++ b/src/ltc/pk/asn1/oid/pk_oid_str.c
@@ -49,7 +49,7 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID,
char tmp[256] = { 0 };
LTC_ARGCHK(oid != NULL);
- LTC_ARGCHK(OID != NULL);
+ LTC_ARGCHK(oidlen < INT_MAX);
LTC_ARGCHK(outlen != NULL);
for (i = oidlen - 1, k = 0; i >= 0; i--) {
@@ -74,6 +74,7 @@ int pk_oid_num_to_str(const unsigned long *oid, unsigned long oidlen, char *OID,
*outlen = k + 1;
return CRYPT_BUFFER_OVERFLOW;
}
+ LTC_ARGCHK(OID != NULL);
for (j = 0; j < k; j++) OID[j] = tmp[k - j - 1];
OID[k] = '\0';
*outlen = k; /* the length without terminating NUL byte */
diff --git a/src/ltc/pk/asn1/x509/x509_decode_public_key_from_certificate.c b/src/ltc/pk/asn1/x509/x509_decode_public_key_from_certificate.c
index 23822262..feff868f 100644
--- a/src/ltc/pk/asn1/x509/x509_decode_public_key_from_certificate.c
+++ b/src/ltc/pk/asn1/x509/x509_decode_public_key_from_certificate.c
@@ -81,7 +81,7 @@ int x509_decode_public_key_from_certificate(const unsigned char *in, unsigned lo
if ((l->type == LTC_ASN1_SEQUENCE)
&& (l->data != NULL)
&& LOOKS_LIKE_SPKI(l->child)) {
- if (algorithm == PKA_EC) {
+ if (algorithm == LTC_OID_EC) {
err = callback(l->data, l->size, ctx);
} else {
err = x509_decode_subject_public_key_info(l->data, l->size,
diff --git a/src/ltc/pk/dh/dh_free.c b/src/ltc/pk/dh/dh_free.c
index b149a94e..ff56b006 100644
--- a/src/ltc/pk/dh/dh_free.c
+++ b/src/ltc/pk/dh/dh_free.c
@@ -12,7 +12,7 @@
void dh_free(dh_key *key)
{
LTC_ARGCHKVD(key != NULL);
- mp_cleanup_multi(&key->prime, &key->base, &key->y, &key->x, NULL);
+ mp_cleanup_multi(&key->prime, &key->base, &key->y, &key->x, LTC_NULL);
}
#endif /* LTC_MDH */
diff --git a/src/ltc/pk/dh/dh_import.c b/src/ltc/pk/dh/dh_import.c
index 5db1be38..a067a327 100644
--- a/src/ltc/pk/dh/dh_import.c
+++ b/src/ltc/pk/dh/dh_import.c
@@ -22,7 +22,7 @@ int dh_import(const unsigned char *in, unsigned long inlen, dh_key *key)
LTC_ARGCHK(key != NULL);
/* init */
- if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
return err;
}
diff --git a/src/ltc/pk/dh/dh_set.c b/src/ltc/pk/dh/dh_set.c
index 1f094f20..e25db089 100644
--- a/src/ltc/pk/dh/dh_set.c
+++ b/src/ltc/pk/dh/dh_set.c
@@ -26,7 +26,7 @@ int dh_set_pg(const unsigned char *p, unsigned long plen,
LTC_ARGCHK(g != NULL);
LTC_ARGCHK(ltc_mp.name != NULL);
- if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -58,7 +58,7 @@ int dh_set_pg_groupsize(int groupsize, dh_key *key)
for (i = 0; (groupsize > ltc_dh_sets[i].size) && (ltc_dh_sets[i].size != 0); i++);
if (ltc_dh_sets[i].size == 0) return CRYPT_INVALID_KEYSIZE;
- if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
return err;
}
if ((err = mp_read_radix(key->base, ltc_dh_sets[i].base, 16)) != CRYPT_OK) { goto LBL_ERR; }
diff --git a/src/ltc/pk/dh/dh_set_pg_dhparam.c b/src/ltc/pk/dh/dh_set_pg_dhparam.c
index 972c6ac0..1f2fb3b9 100644
--- a/src/ltc/pk/dh/dh_set_pg_dhparam.c
+++ b/src/ltc/pk/dh/dh_set_pg_dhparam.c
@@ -24,7 +24,7 @@ int dh_set_pg_dhparam(const unsigned char *dhparam, unsigned long dhparamlen, dh
LTC_ARGCHK(dhparam != NULL);
LTC_ARGCHK(dhparamlen > 0);
- if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&key->x, &key->y, &key->base, &key->prime, LTC_NULL)) != CRYPT_OK) {
return err;
}
if ((err = der_decode_sequence_multi(dhparam, dhparamlen,
diff --git a/src/ltc/pk/dsa/dsa_encrypt_key.c b/src/ltc/pk/dsa/dsa_encrypt_key.c
index c2b7e9d7..2f460921 100644
--- a/src/ltc/pk/dsa/dsa_encrypt_key.c
+++ b/src/ltc/pk/dsa/dsa_encrypt_key.c
@@ -50,7 +50,7 @@ int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
}
/* make a random key and export the public copy */
- if ((err = mp_init_multi(&g_pub, &g_priv, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&g_pub, &g_priv, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -63,7 +63,7 @@ int dsa_encrypt_key(const unsigned char *in, unsigned long inlen,
if (skey != NULL) {
XFREE(skey);
}
- mp_clear_multi(g_pub, g_priv, NULL);
+ mp_clear_multi(g_pub, g_priv, LTC_NULL);
return CRYPT_MEM;
}
@@ -111,7 +111,7 @@ LBL_ERR:
XFREE(skey);
XFREE(expt);
- mp_clear_multi(g_pub, g_priv, NULL);
+ mp_clear_multi(g_pub, g_priv, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/dsa/dsa_export.c b/src/ltc/pk/dsa/dsa_export.c
index 8f22ab8a..3550cbec 100644
--- a/src/ltc/pk/dsa/dsa_export.c
+++ b/src/ltc/pk/dsa/dsa_export.c
@@ -75,7 +75,7 @@ int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_ke
LTC_SET_ASN1(int_list, 1, LTC_ASN1_INTEGER, key->q, 1UL);
LTC_SET_ASN1(int_list, 2, LTC_ASN1_INTEGER, key->g, 1UL);
- err = x509_encode_subject_public_key_info(out, outlen, PKA_DSA, tmp,
+ err = x509_encode_subject_public_key_info(out, outlen, LTC_OID_DSA, tmp,
tmplen, LTC_ASN1_SEQUENCE, int_list,
sizeof(int_list) / sizeof(int_list[0]));
diff --git a/src/ltc/pk/dsa/dsa_free.c b/src/ltc/pk/dsa/dsa_free.c
index dc54f57f..dbe86253 100644
--- a/src/ltc/pk/dsa/dsa_free.c
+++ b/src/ltc/pk/dsa/dsa_free.c
@@ -16,7 +16,7 @@
void dsa_free(dsa_key *key)
{
LTC_ARGCHKVD(key != NULL);
- mp_cleanup_multi(&key->y, &key->x, &key->q, &key->g, &key->p, NULL);
+ mp_cleanup_multi(&key->y, &key->x, &key->q, &key->g, &key->p, LTC_NULL);
key->type = key->qord = 0;
}
diff --git a/src/ltc/pk/dsa/dsa_generate_pqg.c b/src/ltc/pk/dsa/dsa_generate_pqg.c
index a2d54382..22f4852b 100644
--- a/src/ltc/pk/dsa/dsa_generate_pqg.c
+++ b/src/ltc/pk/dsa/dsa_generate_pqg.c
@@ -108,7 +108,7 @@ static int s_dsa_make_params(prng_state *prng, int wprng, int group_size, int mo
if ((wbuf = XMALLOC((n+1)*outbytes)) == NULL) { err = CRYPT_MEM; goto cleanup3; }
if ((sbuf = XMALLOC(seedbytes)) == NULL) { err = CRYPT_MEM; goto cleanup2; }
- err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, NULL);
+ err = mp_init_multi(&t2L1, &t2N1, &t2q, &t2seedlen, &U, &W, &X, &c, &h, &e, &seedinc, LTC_NULL);
if (err != CRYPT_OK) { goto cleanup1; }
if ((err = mp_2expt(t2L1, L-1)) != CRYPT_OK) { goto cleanup; }
@@ -187,7 +187,7 @@ static int s_dsa_make_params(prng_state *prng, int wprng, int group_size, int mo
err = CRYPT_OK;
cleanup:
- mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, NULL);
+ mp_clear_multi(t2L1, t2N1, t2q, t2seedlen, U, W, X, c, h, e, seedinc, LTC_NULL);
cleanup1:
XFREE(sbuf);
cleanup2:
@@ -213,7 +213,7 @@ int dsa_generate_pqg(prng_state *prng, int wprng, int group_size, int modulus_si
LTC_ARGCHK(ltc_mp.name != NULL);
/* init mp_ints */
- if ((err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL)) != CRYPT_OK) {
return err;
}
/* generate params */
diff --git a/src/ltc/pk/dsa/dsa_import.c b/src/ltc/pk/dsa/dsa_import.c
index a1d22818..b5660d39 100644
--- a/src/ltc/pk/dsa/dsa_import.c
+++ b/src/ltc/pk/dsa/dsa_import.c
@@ -28,7 +28,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
LTC_ARGCHK(ltc_mp.name != NULL);
/* init key */
- if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL) != CRYPT_OK) {
+ if (mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL) != CRYPT_OK) {
return CRYPT_MEM;
}
@@ -72,14 +72,14 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
}
}
/* get key type */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
- LTC_ASN1_INTEGER, 1UL, key->p,
- LTC_ASN1_INTEGER, 1UL, key->q,
- LTC_ASN1_INTEGER, 1UL, key->g,
- LTC_ASN1_INTEGER, 1UL, key->y,
- LTC_ASN1_INTEGER, 1UL, key->x,
- LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
+ if (der_decode_sequence_multi(in, inlen,
+ LTC_ASN1_SHORT_INTEGER, 1UL, &zero,
+ LTC_ASN1_INTEGER, 1UL, key->p,
+ LTC_ASN1_INTEGER, 1UL, key->q,
+ LTC_ASN1_INTEGER, 1UL, key->g,
+ LTC_ASN1_INTEGER, 1UL, key->y,
+ LTC_ASN1_INTEGER, 1UL, key->x,
+ LTC_ASN1_EOL, 0UL, NULL) == CRYPT_OK) {
key->type = PK_PRIVATE;
} else { /* public */
@@ -97,7 +97,7 @@ int dsa_import(const unsigned char *in, unsigned long inlen, dsa_key *key)
}
len = 3;
- err = x509_decode_subject_public_key_info(in, inlen, PKA_DSA,
+ err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_DSA,
tmpbuf, &tmpbuf_len,
LTC_ASN1_SEQUENCE, params, &len);
if (err != CRYPT_OK) {
diff --git a/src/ltc/pk/dsa/dsa_set.c b/src/ltc/pk/dsa/dsa_set.c
index 026f2806..82b60333 100644
--- a/src/ltc/pk/dsa/dsa_set.c
+++ b/src/ltc/pk/dsa/dsa_set.c
@@ -30,7 +30,7 @@ int dsa_set_pqg(const unsigned char *p, unsigned long plen,
LTC_ARGCHK(ltc_mp.name != NULL);
/* init key */
- err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
+ err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
if (err != CRYPT_OK) return err;
if ((err = mp_read_unsigned_bin(key->p, (unsigned char *)p , plen)) != CRYPT_OK) { goto LBL_ERR; }
diff --git a/src/ltc/pk/dsa/dsa_set_pqg_dsaparam.c b/src/ltc/pk/dsa/dsa_set_pqg_dsaparam.c
index 3ab92282..97c71f10 100644
--- a/src/ltc/pk/dsa/dsa_set_pqg_dsaparam.c
+++ b/src/ltc/pk/dsa/dsa_set_pqg_dsaparam.c
@@ -25,7 +25,7 @@ int dsa_set_pqg_dsaparam(const unsigned char *dsaparam, unsigned long dsaparamle
LTC_ARGCHK(ltc_mp.name != NULL);
/* init key */
- err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, NULL);
+ err = mp_init_multi(&key->p, &key->g, &key->q, &key->x, &key->y, LTC_NULL);
if (err != CRYPT_OK) return err;
if ((err = der_decode_sequence_multi(dsaparam, dsaparamlen,
diff --git a/src/ltc/pk/dsa/dsa_sign_hash.c b/src/ltc/pk/dsa/dsa_sign_hash.c
index c4ba0bc1..56baa803 100644
--- a/src/ltc/pk/dsa/dsa_sign_hash.c
+++ b/src/ltc/pk/dsa/dsa_sign_hash.c
@@ -51,7 +51,7 @@ int dsa_sign_hash_raw(const unsigned char *in, unsigned long inlen,
}
/* Init our temps */
- if ((err = mp_init_multi(&k, &kinv, &tmp, NULL)) != CRYPT_OK) { goto ERRBUF; }
+ if ((err = mp_init_multi(&k, &kinv, &tmp, LTC_NULL)) != CRYPT_OK) { goto ERRBUF; }
qbits = mp_count_bits(key->q);
retry:
@@ -89,7 +89,7 @@ retry:
err = CRYPT_OK;
error:
- mp_clear_multi(k, kinv, tmp, NULL);
+ mp_clear_multi(k, kinv, tmp, LTC_NULL);
ERRBUF:
#ifdef LTC_CLEAN_STACK
zeromem(buf, LTC_MDSA_MAX_GROUP);
@@ -121,7 +121,7 @@ int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(key != NULL);
- if (mp_init_multi(&r, &s, NULL) != CRYPT_OK) {
+ if (mp_init_multi(&r, &s, LTC_NULL) != CRYPT_OK) {
return CRYPT_MEM;
}
@@ -135,7 +135,7 @@ int dsa_sign_hash(const unsigned char *in, unsigned long inlen,
LTC_ASN1_EOL, 0UL, NULL);
error:
- mp_clear_multi(r, s, NULL);
+ mp_clear_multi(r, s, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/dsa/dsa_verify_hash.c b/src/ltc/pk/dsa/dsa_verify_hash.c
index e290ba16..500feda9 100644
--- a/src/ltc/pk/dsa/dsa_verify_hash.c
+++ b/src/ltc/pk/dsa/dsa_verify_hash.c
@@ -36,7 +36,7 @@ int dsa_verify_hash_raw( void *r, void *s,
*stat = 0;
/* init our variables */
- if ((err = mp_init_multi(&w, &v, &u1, &u2, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&w, &v, &u1, &u2, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -72,7 +72,7 @@ int dsa_verify_hash_raw( void *r, void *s,
err = CRYPT_OK;
error:
- mp_clear_multi(w, v, u1, u2, NULL);
+ mp_clear_multi(w, v, u1, u2, LTC_NULL);
return err;
}
@@ -98,7 +98,7 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
LTC_ARGCHK(stat != NULL);
*stat = 0; /* must be set before the first return */
- if ((err = mp_init_multi(&r, &s, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&r, &s, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -119,7 +119,7 @@ int dsa_verify_hash(const unsigned char *sig, unsigned long siglen,
err = dsa_verify_hash_raw(r, s, hash, hashlen, stat, key);
LBL_ERR:
- mp_clear_multi(r, s, NULL);
+ mp_clear_multi(r, s, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/dsa/dsa_verify_key.c b/src/ltc/pk/dsa/dsa_verify_key.c
index 4f4bdd17..50d566ae 100644
--- a/src/ltc/pk/dsa/dsa_verify_key.c
+++ b/src/ltc/pk/dsa/dsa_verify_key.c
@@ -62,7 +62,7 @@ int dsa_int_validate_pqg(const dsa_key *key, int *stat)
return CRYPT_OK;
}
- if ((err = mp_init_multi(&tmp1, &tmp2, NULL)) != CRYPT_OK) { return err; }
+ if ((err = mp_init_multi(&tmp1, &tmp2, LTC_NULL)) != CRYPT_OK) { return err; }
/* FIPS 186-4 chapter 4.1: q is a divisor of (p - 1) */
if ((err = mp_sub_d(key->p, 1, tmp1)) != CRYPT_OK) { goto error; }
@@ -84,7 +84,7 @@ int dsa_int_validate_pqg(const dsa_key *key, int *stat)
err = CRYPT_OK;
*stat = 1;
error:
- mp_clear_multi(tmp2, tmp1, NULL);
+ mp_clear_multi(tmp2, tmp1, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ec25519/ec25519_crypto_ctx.c b/src/ltc/pk/ec25519/ec25519_crypto_ctx.c
new file mode 100644
index 00000000..e1efb301
--- /dev/null
+++ b/src/ltc/pk/ec25519/ec25519_crypto_ctx.c
@@ -0,0 +1,41 @@
+/* LibTomCrypt, modular cryptographic library -- Tom St Denis */
+/* SPDX-License-Identifier: Unlicense */
+#include "tomcrypt_private.h"
+
+/**
+ @file ec25519_crypto_ctx.c
+ curve25519 crypto context helper
+*/
+
+#ifdef LTC_CURVE25519
+
+int ec25519_crypto_ctx(unsigned char *out, unsigned long *outlen, unsigned char flag, const unsigned char *ctx, unsigned long ctxlen)
+{
+ unsigned char *buf = out;
+
+ const char *prefix = "SigEd25519 no Ed25519 collisions";
+ const unsigned long prefix_len = XSTRLEN(prefix);
+ const unsigned char ctxlen8 = (unsigned char)ctxlen;
+
+ if (ctxlen > 255u) return CRYPT_INPUT_TOO_LONG;
+ if (*outlen < prefix_len + 2u + ctxlen) return CRYPT_BUFFER_OVERFLOW;
+
+ XMEMCPY(buf, prefix, prefix_len);
+ buf += prefix_len;
+ XMEMCPY(buf, &flag, 1);
+ buf++;
+ XMEMCPY(buf, &ctxlen8, 1);
+ buf++;
+
+ if (ctxlen > 0u) {
+ LTC_ARGCHK(ctx != NULL);
+ XMEMCPY(buf, ctx, ctxlen);
+ buf += ctxlen;
+ }
+
+ *outlen = buf-out;
+
+ return CRYPT_OK;
+}
+
+#endif
diff --git a/src/ltc/pk/ec25519/tweetnacl.c b/src/ltc/pk/ec25519/tweetnacl.c
index fc5aad72..9db0dcd8 100644
--- a/src/ltc/pk/ec25519/tweetnacl.c
+++ b/src/ltc/pk/ec25519/tweetnacl.c
@@ -221,18 +221,22 @@ int tweetnacl_crypto_scalarmult_base(u8 *q,const u8 *n)
return tweetnacl_crypto_scalarmult(q,n,nine);
}
-static int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
+static LTC_INLINE int tweetnacl_crypto_hash_ctx(u8 *out,const u8 *m,u64 n,const u8 *ctx,u32 cs)
{
- unsigned long len;
- int err, hash_idx;
+ unsigned long len = 64;
+ int hash_idx = find_hash("sha512");
if (n > ULONG_MAX) return CRYPT_OVERFLOW;
- hash_idx = find_hash("sha512");
- len = 64;
- if ((err = hash_memory(hash_idx, m, n, out, &len)) != CRYPT_OK) return err;
+ if(cs == 0)
+ return hash_memory(hash_idx, m, n, out, &len);
- return 0;
+ return hash_memory_multi(hash_idx, out, &len, ctx, cs, m, n, LTC_NULL);
+}
+
+static LTC_INLINE int tweetnacl_crypto_hash(u8 *out,const u8 *m,u64 n)
+{
+ return tweetnacl_crypto_hash_ctx(out, m, n, NULL, 0);
}
sv add(gf p[4],gf q[4])
@@ -376,7 +380,7 @@ sv reduce(u8 *r)
modL(r,x);
}
-int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk)
+int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,const u8 *pk, const u8 *ctx, u64 cs)
{
u8 d[64],h[64],r[64];
i64 i,j,x[64];
@@ -391,13 +395,13 @@ int tweetnacl_crypto_sign(u8 *sm,u64 *smlen,const u8 *m,u64 mlen,const u8 *sk,co
FOR(i,(i64)mlen) sm[64 + i] = m[i];
FOR(i,32) sm[32 + i] = d[32 + i];
- tweetnacl_crypto_hash(r, sm+32, mlen+32);
+ tweetnacl_crypto_hash_ctx(r, sm+32, mlen+32,ctx,cs);
reduce(r);
scalarbase(p,r);
pack(sm,p);
FOR(i,32) sm[i+32] = pk[i];
- tweetnacl_crypto_hash(h,sm,mlen + 64);
+ tweetnacl_crypto_hash_ctx(h,sm,mlen + 64,ctx,cs);
reduce(h);
FOR(i,64) x[i] = 0;
@@ -444,7 +448,7 @@ static int unpackneg(gf r[4],const u8 p[32])
return 0;
}
-int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *pk)
+int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen,const u8 *ctx,u64 cs,const u8 *pk)
{
u64 i;
u8 s[32],t[32],h[64];
@@ -460,7 +464,7 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen
XMEMMOVE(m,sm,smlen);
XMEMMOVE(s,m + 32,32);
XMEMMOVE(m + 32,pk,32);
- tweetnacl_crypto_hash(h,m,smlen);
+ tweetnacl_crypto_hash_ctx(h,m,smlen,ctx,cs);
reduce(h);
scalarmult(p,q,h);
@@ -480,3 +484,8 @@ int tweetnacl_crypto_sign_open(int *stat, u8 *m,u64 *mlen,const u8 *sm,u64 smlen
*mlen = smlen;
return CRYPT_OK;
}
+
+int tweetnacl_crypto_ph(u8 *out,const u8 *msg,u64 msglen)
+{
+ return tweetnacl_crypto_hash(out, msg, msglen);
+}
diff --git a/src/ltc/pk/ecc/ecc_export_openssl.c b/src/ltc/pk/ecc/ecc_export_openssl.c
index 97123d64..2e899968 100644
--- a/src/ltc/pk/ecc/ecc_export_openssl.c
+++ b/src/ltc/pk/ecc/ecc_export_openssl.c
@@ -34,41 +34,6 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons
if (key->type != PK_PRIVATE && flag_pri) return CRYPT_PK_TYPE_MISMATCH;
- prime = key->dp.prime;
- order = key->dp.order;
- b = key->dp.B;
- a = key->dp.A;
- gx = key->dp.base.x;
- gy = key->dp.base.y;
-
- /* curve param a */
- len_a = mp_unsigned_bin_size(a);
- if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
- if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) { goto error; }
- if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* handle case a == 0 */
-
- /* curve param b */
- len_b = mp_unsigned_bin_size(b);
- if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
- if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) { goto error; }
- if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* handle case b == 0 */
-
- /* base point - (un)compressed based on flag_com */
- len_g = sizeof(bin_g);
- err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp.size, flag_com);
- if (err != CRYPT_OK) { goto error; }
-
- /* public key - (un)compressed based on flag_com */
- len_xy = sizeof(bin_xy);
- err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp.size, flag_com);
- if (err != CRYPT_OK) { goto error; }
-
- /* co-factor */
- cofactor = key->dp.cofactor;
-
- /* we support only prime-field EC */
- if ((err = pk_get_oid(PKA_EC_PRIMEF, &OID)) != CRYPT_OK) { goto error; }
-
if (flag_oid) {
/* http://tools.ietf.org/html/rfc5912
ECParameters ::= CHOICE {
@@ -79,6 +44,34 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons
LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_OBJECT_IDENTIFIER, key->dp.oid, key->dp.oidlen);
}
else {
+ prime = key->dp.prime;
+ order = key->dp.order;
+ a = key->dp.A;
+ b = key->dp.B;
+ gx = key->dp.base.x;
+ gy = key->dp.base.y;
+ cofactor = key->dp.cofactor;
+
+ /* curve param a */
+ len_a = mp_unsigned_bin_size(a);
+ if (len_a > sizeof(bin_a)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
+ if ((err = mp_to_unsigned_bin(a, bin_a)) != CRYPT_OK) { goto error; }
+ if (len_a == 0) { len_a = 1; bin_a[0] = 0; } /* handle case a == 0 */
+
+ /* curve param b */
+ len_b = mp_unsigned_bin_size(b);
+ if (len_b > sizeof(bin_b)) { err = CRYPT_BUFFER_OVERFLOW; goto error; }
+ if ((err = mp_to_unsigned_bin(b, bin_b)) != CRYPT_OK) { goto error; }
+ if (len_b == 0) { len_b = 1; bin_b[0] = 0; } /* handle case b == 0 */
+
+ /* base point - (un)compressed based on flag_com */
+ len_g = sizeof(bin_g);
+ err = ltc_ecc_export_point(bin_g, &len_g, gx, gy, key->dp.size, flag_com);
+ if (err != CRYPT_OK) { goto error; }
+
+ /* we support only prime-field EC */
+ if ((err = pk_get_oid(LTC_OID_EC_PRIMEF, &OID)) != CRYPT_OK) { goto error; }
+
/* http://tools.ietf.org/html/rfc3279
ECParameters ::= SEQUENCE { # SEQUENCE
version INTEGER { ecpVer1(1) } (ecpVer1) # INTEGER :01
@@ -122,7 +115,15 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons
LTC_SET_ASN1(&ecparams, 0, LTC_ASN1_SEQUENCE, seq_ecparams, 6UL);
}
+ /* public key - (un)compressed based on flag_com */
+ len_xy = sizeof(bin_xy);
+ err = ltc_ecc_export_point(bin_xy, &len_xy, key->pubkey.x, key->pubkey.y, key->dp.size, flag_com);
+ if (err != CRYPT_OK) {
+ goto error;
+ }
+
if (flag_pri) {
+
/* http://tools.ietf.org/html/rfc5915
ECPrivateKey ::= SEQUENCE { # SEQUENCE
version INTEGER { ecPrivkeyVer1(1) } (ecPrivkeyVer1) # INTEGER :01
@@ -155,7 +156,7 @@ int ecc_export_openssl(unsigned char *out, unsigned long *outlen, int type, cons
subjectPublicKey BIT STRING # BIT STRING
}
*/
- err = x509_encode_subject_public_key_info( out, outlen, PKA_EC, bin_xy, len_xy,
+ err = x509_encode_subject_public_key_info( out, outlen, LTC_OID_EC, bin_xy, len_xy,
ecparams.type, ecparams.data, ecparams.size );
}
diff --git a/src/ltc/pk/ecc/ecc_import_openssl.c b/src/ltc/pk/ecc/ecc_import_openssl.c
index e3a6f619..325b0b05 100644
--- a/src/ltc/pk/ecc/ecc_import_openssl.c
+++ b/src/ltc/pk/ecc/ecc_import_openssl.c
@@ -49,7 +49,7 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
unsigned long cofactor = 0, ecver = 0, pkver = 0, tmpoid[16];
int err;
- if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -95,7 +95,7 @@ static int s_ecc_import_private_with_curve(const unsigned char *in, unsigned lon
err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key);
}
error:
- mp_clear_multi(prime, order, a, b, gx, gy, NULL);
+ mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ecc_import_pkcs8.c b/src/ltc/pk/ecc/ecc_import_pkcs8.c
index 0461db09..81ac6ed6 100644
--- a/src/ltc/pk/ecc/ecc_import_pkcs8.c
+++ b/src/ltc/pk/ecc/ecc_import_pkcs8.c
@@ -56,15 +56,15 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
LTC_ARGCHK(ltc_mp.name != NULL);
/* get EC alg oid */
- err = pk_get_oid(PKA_EC, &pka_ec_oid);
+ err = pk_get_oid(LTC_OID_EC, &pka_ec_oid);
if (err != CRYPT_OK) return err;
/* init key */
- err = mp_init_multi(&a, &b, &gx, &gy, NULL);
+ err = mp_init_multi(&a, &b, &gx, &gy, LTC_NULL);
if (err != CRYPT_OK) return err;
- if ((err = pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l)) == CRYPT_OK) {
+ if (pkcs8_decode_flexi(in, inlen, pwd, pwdlen, &l) == CRYPT_OK) {
/* Setup for basic structure */
n=0;
@@ -73,7 +73,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
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 (((err = s_der_flexi_sequence_cmp(l, flexi_should)) == CRYPT_OK) &&
+ if ((s_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;
@@ -154,7 +154,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
/* load private key value 'k' */
len = priv_key->size;
- if ((err = der_decode_sequence_flexi(priv_key->data, &len, &p)) == CRYPT_OK) {
+ if (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)) {
@@ -177,7 +177,7 @@ int ecc_import_pkcs8(const unsigned char *in, unsigned long inlen,
LBL_ECCFREE:
ecc_free(key);
LBL_DONE:
- mp_clear_multi(a, b, gx, gy, NULL);
+ mp_clear_multi(a, b, gx, gy, LTC_NULL);
if (l) der_free_sequence_flexi(l);
if (p) der_free_sequence_flexi(p);
return err;
diff --git a/src/ltc/pk/ecc/ecc_import_x509.c b/src/ltc/pk/ecc/ecc_import_x509.c
index 7d64c63f..e4ba5e3a 100644
--- a/src/ltc/pk/ecc/ecc_import_x509.c
+++ b/src/ltc/pk/ecc/ecc_import_x509.c
@@ -15,7 +15,7 @@ static int s_ecc_import_x509_with_oid(const unsigned char *in, unsigned long inl
len_xy = sizeof(bin_xy);
len_oid = 16;
- err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy,
+ err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy,
LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid);
if (err == CRYPT_OK) {
/* load curve parameters for given curve OID */
@@ -40,7 +40,7 @@ static int s_ecc_import_x509_with_curve(const unsigned char *in, unsigned long i
unsigned long cofactor = 0, ecver = 0, tmpoid[16];
int err;
- if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&prime, &order, &a, &b, &gx, &gy, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -63,7 +63,7 @@ static int s_ecc_import_x509_with_curve(const unsigned char *in, unsigned long i
/* try to load public key */
len_xy = sizeof(bin_xy);
len = 6;
- err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);
+ err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_EC, bin_xy, &len_xy, LTC_ASN1_SEQUENCE, seq_ecparams, &len);
if (err == CRYPT_OK) {
len_a = seq_curve[0].size;
@@ -79,7 +79,7 @@ static int s_ecc_import_x509_with_curve(const unsigned char *in, unsigned long i
err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key);
}
error:
- mp_clear_multi(prime, order, a, b, gx, gy, NULL);
+ mp_clear_multi(prime, order, a, b, gx, gy, LTC_NULL);
return err;
}
@@ -107,7 +107,7 @@ success:
int ecc_import_x509(const unsigned char *in, unsigned long inlen, ecc_key *key)
{
return x509_decode_public_key_from_certificate(in, inlen,
- PKA_EC,
+ LTC_OID_EC,
LTC_ASN1_EOL, NULL, NULL,
(public_key_decode_cb)ecc_import_subject_public_key_info, key);
}
diff --git a/src/ltc/pk/ecc/ecc_recover_key.c b/src/ltc/pk/ecc/ecc_recover_key.c
index ae932767..b6ae644b 100644
--- a/src/ltc/pk/ecc/ecc_recover_key.c
+++ b/src/ltc/pk/ecc/ecc_recover_key.c
@@ -46,7 +46,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen,
}
/* 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) {
+ if ((err = mp_init_multi(&r, &s, &v, &w, &t1, &t2, &u1, &u2, &v1, &v2, &e, &x, &y, &a_plus3, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -72,7 +72,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen,
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; }
+ LTC_ASN1_EOL, 0UL, LTC_NULL)) != CRYPT_OK) { goto error; }
}
else if (sigformat == LTC_ECCSIG_RFC7518) {
/* RFC7518 format - raw (r,s) */
@@ -120,7 +120,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen,
/* Check curve matches identifier string */
- if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
+ if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
if ((namelen != name2len) || (XSTRCMP(name, name2) != 0)) {
err = CRYPT_INVALID_ARG;
goto error;
@@ -214,7 +214,7 @@ int ecc_recover_key(const unsigned char *sig, unsigned long siglen,
/* 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_init_multi(&mu, &ma, LTC_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; }
}
@@ -252,7 +252,7 @@ error:
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);
+ mp_clear_multi(a_plus3, y, x, e, v2, v1, u2, u1, t2, t1, w, v, s, r, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ecc_sign_hash.c b/src/ltc/pk/ecc/ecc_sign_hash.c
index 69c72bd9..229ced19 100644
--- a/src/ltc/pk/ecc/ecc_sign_hash.c
+++ b/src/ltc/pk/ecc/ecc_sign_hash.c
@@ -46,7 +46,7 @@ int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen,
}
/* init the bignums */
- if ((err = mp_init_multi(&r, &s, &e, &b, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&r, &s, &e, &b, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -174,7 +174,7 @@ int ecc_sign_hash_ex(const unsigned char *in, unsigned long inlen,
error:
ecc_free(&pubkey);
errnokey:
- mp_clear_multi(r, s, e, b, NULL);
+ mp_clear_multi(r, s, e, b, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ecc_ssh_ecdsa_encode_name.c b/src/ltc/pk/ecc/ecc_ssh_ecdsa_encode_name.c
index 09c8d643..4b8d5542 100644
--- a/src/ltc/pk/ecc/ecc_ssh_ecdsa_encode_name.c
+++ b/src/ltc/pk/ecc/ecc_ssh_ecdsa_encode_name.c
@@ -19,7 +19,7 @@
*/
int ecc_ssh_ecdsa_encode_name(char *buffer, unsigned long *buflen, const ecc_key *key)
{
- char oidstr[64];
+ char oidstr[64] = {0};
unsigned long oidlen = sizeof(oidstr);
int err, size = 0;
diff --git a/src/ltc/pk/ecc/ecc_verify_hash.c b/src/ltc/pk/ecc/ecc_verify_hash.c
index 377b4d31..4480ff45 100644
--- a/src/ltc/pk/ecc/ecc_verify_hash.c
+++ b/src/ltc/pk/ecc/ecc_verify_hash.c
@@ -42,7 +42,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
*stat = 0;
/* allocate ints */
- if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &e, &a_plus3, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&r, &s, &v, &w, &u1, &u2, &e, &a_plus3, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -66,7 +66,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
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; }
+ LTC_ASN1_EOL, 0UL, LTC_NULL)) != CRYPT_OK) { goto error; }
}
else if (sigformat == LTC_ECCSIG_RFC7518) {
/* RFC7518 format - raw (r,s) */
@@ -106,7 +106,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
/* Check curve matches identifier string */
- if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
+ if ((err = ecc_ssh_ecdsa_encode_name(name2, &name2len, key)) != CRYPT_OK) { goto error; }
if ((namelen != name2len) || (XSTRCMP(name, name2) != 0)) {
err = CRYPT_INVALID_ARG;
goto error;
@@ -163,7 +163,7 @@ int ecc_verify_hash_ex(const unsigned char *sig, unsigned long siglen,
/* 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_init_multi(&mu, &ma, LTC_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; }
}
@@ -198,7 +198,7 @@ error:
if (mQ != NULL) ltc_ecc_del_point(mQ);
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);
+ mp_clear_multi(r, s, v, w, u1, u2, e, a_plus3, LTC_NULL);
if (mp != NULL) mp_montgomery_free(mp);
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_import_point.c b/src/ltc/pk/ecc/ltc_ecc_import_point.c
index 8ef31eaf..6250fca2 100644
--- a/src/ltc/pk/ecc/ltc_ecc_import_point.c
+++ b/src/ltc/pk/ecc/ltc_ecc_import_point.c
@@ -12,7 +12,7 @@ int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *pri
void *t1, *t2;
/* init key + temporary numbers */
- if (mp_init_multi(&t1, &t2, NULL) != CRYPT_OK) {
+ if (mp_init_multi(&t1, &t2, LTC_NULL) != CRYPT_OK) {
return CRYPT_MEM;
}
@@ -54,7 +54,7 @@ int ltc_ecc_import_point(const unsigned char *in, unsigned long inlen, void *pri
err = CRYPT_OK;
cleanup:
- mp_clear_multi(t1, t2, NULL);
+ mp_clear_multi(t1, t2, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point.c b/src/ltc/pk/ecc/ltc_ecc_is_point.c
index db10232c..56a9537d 100644
--- a/src/ltc/pk/ecc/ltc_ecc_is_point.c
+++ b/src/ltc/pk/ecc/ltc_ecc_is_point.c
@@ -21,7 +21,7 @@ int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y)
b = dp->B;
a = dp->A;
- if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) return err;
+ if ((err = mp_init_multi(&t1, &t2, LTC_NULL)) != CRYPT_OK) return err;
/* compute y^2 */
if ((err = mp_sqr(y, t1)) != CRYPT_OK) goto cleanup;
@@ -55,7 +55,7 @@ int ltc_ecc_is_point(const ltc_ecc_dp *dp, void *x, void *y)
}
cleanup:
- mp_clear_multi(t1, t2, NULL);
+ mp_clear_multi(t1, t2, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c
index 8a3e3857..2afc4d49 100644
--- a/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c
+++ b/src/ltc/pk/ecc/ltc_ecc_is_point_at_infinity.c
@@ -27,7 +27,7 @@ int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval)
}
/* initialize */
- if ((err = mp_init_multi(&x3, &y2, NULL)) != CRYPT_OK) goto done;
+ if ((err = mp_init_multi(&x3, &y2, LTC_NULL)) != CRYPT_OK) goto done;
/* compute y^2 */
if ((err = mp_mulmod(P->y, P->y, modulus, y2)) != CRYPT_OK) goto cleanup;
@@ -45,7 +45,7 @@ int ltc_ecc_is_point_at_infinity(const ecc_point *P, void *modulus, int *retval)
}
cleanup:
- mp_clear_multi(x3, y2, NULL);
+ mp_clear_multi(x3, y2, LTC_NULL);
done:
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_map.c b/src/ltc/pk/ecc/ltc_ecc_map.c
index ffe6f85d..163fb412 100644
--- a/src/ltc/pk/ecc/ltc_ecc_map.c
+++ b/src/ltc/pk/ecc/ltc_ecc_map.c
@@ -30,7 +30,7 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
return ltc_ecc_set_point_xyz(0, 0, 1, P);
}
- if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&t1, &t2, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -55,7 +55,7 @@ int ltc_ecc_map(ecc_point *P, void *modulus, void *mp)
err = CRYPT_OK;
done:
- mp_clear_multi(t1, t2, NULL);
+ mp_clear_multi(t1, t2, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_points.c b/src/ltc/pk/ecc/ltc_ecc_points.c
index 5700c0ed..b762db50 100644
--- a/src/ltc/pk/ecc/ltc_ecc_points.c
+++ b/src/ltc/pk/ecc/ltc_ecc_points.c
@@ -21,7 +21,7 @@ ecc_point *ltc_ecc_new_point(void)
if (p == NULL) {
return NULL;
}
- if (mp_init_multi(&p->x, &p->y, &p->z, NULL) != CRYPT_OK) {
+ if (mp_init_multi(&p->x, &p->y, &p->z, LTC_NULL) != CRYPT_OK) {
XFREE(p);
return NULL;
}
@@ -35,7 +35,7 @@ void ltc_ecc_del_point(ecc_point *p)
{
/* prevents free'ing null arguments */
if (p != NULL) {
- mp_clear_multi(p->x, p->y, p->z, NULL); /* note: p->z may be NULL but that's ok with this function anyways */
+ mp_clear_multi(p->x, p->y, p->z, LTC_NULL); /* note: p->z may be NULL but that's ok with this function anyways */
XFREE(p);
}
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c
index 71630338..448c2bb6 100644
--- a/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c
+++ b/src/ltc/pk/ecc/ltc_ecc_projective_add_point.c
@@ -31,7 +31,7 @@ int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_poi
LTC_ARGCHK(modulus != NULL);
LTC_ARGCHK(mp != NULL);
- if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&t1, &t2, &x, &y, &z, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -52,7 +52,7 @@ int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_poi
if ((mp_cmp(P->x, Q->x) == LTC_MP_EQ) && (mp_cmp(P->z, Q->z) == LTC_MP_EQ)) {
if (mp_cmp(P->y, Q->y) == LTC_MP_EQ) {
/* here P = Q >> Result = 2 * P (use doubling) */
- mp_clear_multi(t1, t2, x, y, z, NULL);
+ mp_clear_multi(t1, t2, x, y, z, LTC_NULL);
return ltc_ecc_projective_dbl_point(P, R, ma, modulus, mp);
}
if ((err = mp_sub(modulus, Q->y, t1)) != CRYPT_OK) { goto done; }
@@ -190,7 +190,7 @@ int ltc_ecc_projective_add_point(const ecc_point *P, const ecc_point *Q, ecc_poi
err = CRYPT_OK;
done:
- mp_clear_multi(t1, t2, x, y, z, NULL);
+ mp_clear_multi(t1, t2, x, y, z, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c
index 6e01939c..c99a2674 100644
--- a/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c
+++ b/src/ltc/pk/ecc/ltc_ecc_projective_dbl_point.c
@@ -47,7 +47,7 @@ int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, voi
LTC_ARGCHK(modulus != NULL);
LTC_ARGCHK(mp != NULL);
- if ((err = mp_init_multi(&t1, &t2, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&t1, &t2, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -176,7 +176,7 @@ int ltc_ecc_projective_dbl_point(const ecc_point *P, ecc_point *R, void *ma, voi
err = CRYPT_OK;
done:
- mp_clear_multi(t2, t1, NULL);
+ mp_clear_multi(t2, t1, LTC_NULL);
return err;
}
#endif
diff --git a/src/ltc/pk/ed25519/ed25519_export.c b/src/ltc/pk/ed25519/ed25519_export.c
index 36adfc9d..2b710e58 100644
--- a/src/ltc/pk/ed25519/ed25519_export.c
+++ b/src/ltc/pk/ed25519/ed25519_export.c
@@ -23,7 +23,7 @@ int ed25519_export( unsigned char *out, unsigned long *outlen,
{
LTC_ARGCHK(key != NULL);
- if (key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
+ if (key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE;
return ec25519_export(out, outlen, which, key);
}
diff --git a/src/ltc/pk/ed25519/ed25519_import.c b/src/ltc/pk/ed25519/ed25519_import.c
index 9684e6fa..f197d59d 100644
--- a/src/ltc/pk/ed25519/ed25519_import.c
+++ b/src/ltc/pk/ed25519/ed25519_import.c
@@ -25,9 +25,9 @@ int ed25519_import(const unsigned char *in, unsigned long inlen, curve25519_key
LTC_ARGCHK(key != NULL);
key_len = sizeof(key->pub);
- if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
+ if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_ED25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
key->type = PK_PUBLIC;
- key->algo = PKA_ED25519;
+ key->algo = LTC_OID_ED25519;
}
return err;
}
diff --git a/src/ltc/pk/ed25519/ed25519_import_pkcs8.c b/src/ltc/pk/ed25519/ed25519_import_pkcs8.c
index 3137c512..71f12de4 100644
--- a/src/ltc/pk/ed25519/ed25519_import_pkcs8.c
+++ b/src/ltc/pk/ed25519/ed25519_import_pkcs8.c
@@ -22,7 +22,7 @@ int ed25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
curve25519_key *key)
{
- return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_ED25519, tweetnacl_crypto_sk_to_pk, key);
+ return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, LTC_OID_ED25519, tweetnacl_crypto_sk_to_pk, key);
}
#endif
diff --git a/src/ltc/pk/ed25519/ed25519_import_raw.c b/src/ltc/pk/ed25519/ed25519_import_raw.c
index 0a11372b..19955d13 100644
--- a/src/ltc/pk/ed25519/ed25519_import_raw.c
+++ b/src/ltc/pk/ed25519/ed25519_import_raw.c
@@ -32,7 +32,7 @@ int ed25519_import_raw(const unsigned char *in, unsigned long inlen, int which,
} else {
return CRYPT_INVALID_ARG;
}
- key->algo = PKA_ED25519;
+ key->algo = LTC_OID_ED25519;
key->type = which;
return CRYPT_OK;
diff --git a/src/ltc/pk/ed25519/ed25519_import_x509.c b/src/ltc/pk/ed25519/ed25519_import_x509.c
index 451c4704..44978ac2 100644
--- a/src/ltc/pk/ed25519/ed25519_import_x509.c
+++ b/src/ltc/pk/ed25519/ed25519_import_x509.c
@@ -31,13 +31,13 @@ int ed25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519
LTC_ARGCHK(key != NULL);
if ((err = x509_decode_public_key_from_certificate(in, inlen,
- PKA_ED25519,
+ LTC_OID_ED25519,
LTC_ASN1_EOL, NULL, NULL,
(public_key_decode_cb)s_ed25519_decode, key)) != CRYPT_OK) {
return err;
}
key->type = PK_PUBLIC;
- key->algo = PKA_ED25519;
+ key->algo = LTC_OID_ED25519;
return err;
}
diff --git a/src/ltc/pk/ed25519/ed25519_make_key.c b/src/ltc/pk/ed25519/ed25519_make_key.c
index 5d81e5ac..7cec1959 100644
--- a/src/ltc/pk/ed25519/ed25519_make_key.c
+++ b/src/ltc/pk/ed25519/ed25519_make_key.c
@@ -28,7 +28,7 @@ int ed25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
}
key->type = PK_PRIVATE;
- key->algo = PKA_ED25519;
+ key->algo = LTC_OID_ED25519;
return err;
}
diff --git a/src/ltc/pk/ed25519/ed25519_sign.c b/src/ltc/pk/ed25519/ed25519_sign.c
index 86a4ea23..d5bf364e 100644
--- a/src/ltc/pk/ed25519/ed25519_sign.c
+++ b/src/ltc/pk/ed25519/ed25519_sign.c
@@ -9,17 +9,10 @@
#ifdef LTC_CURVE25519
-/**
- Create an Ed25519 signature.
- @param private_key The private Ed25519 key in the pair
- @param public_key The public Ed25519 key in the pair
- @param out [out] The destination of the shared data
- @param outlen [in/out] The max size and resulting size of the shared data.
- @return CRYPT_OK if successful
-*/
-int ed25519_sign(const unsigned char *msg, unsigned long msglen,
- unsigned char *sig, unsigned long *siglen,
- const curve25519_key *private_key)
+static int s_ed25519_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ const curve25519_key *private_key)
{
unsigned char *s;
unsigned long long smlen;
@@ -30,7 +23,7 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
LTC_ARGCHK(siglen != NULL);
LTC_ARGCHK(private_key != NULL);
- if (private_key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
+ if (private_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE;
if (private_key->type != PK_PRIVATE) return CRYPT_PK_INVALID_TYPE;
if (*siglen < 64uL) {
@@ -44,7 +37,8 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
err = tweetnacl_crypto_sign(s, &smlen,
msg, msglen,
- private_key->priv, private_key->pub);
+ private_key->priv, private_key->pub,
+ ctx, ctxlen);
XMEMCPY(sig, s, 64uL);
*siglen = 64uL;
@@ -57,4 +51,76 @@ int ed25519_sign(const unsigned char *msg, unsigned long msglen,
return err;
}
+/**
+ Create an Ed25519ctx signature.
+ @param msg The data to be signed
+ @param msglen [in] The size of the date to be signed
+ @param sig [out] The destination of the shared data
+ @param siglen [in/out] The max size and resulting size of the shared data.
+ @param ctx [in] The context is a constant null terminated string
+ @param private_key The private Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519ctx_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ const curve25519_key *private_key)
+{
+ int err;
+ unsigned char ctx_prefix[292];
+ unsigned long ctx_prefix_size = sizeof(ctx_prefix);
+
+ LTC_ARGCHK(ctx != NULL);
+
+ if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen)) != CRYPT_OK)
+ return err;
+
+ return s_ed25519_sign(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, private_key);
+}
+
+/**
+ Create an Ed25519ph signature.
+ @param msg The data to be signed
+ @param msglen [in] The size of the date to be signed
+ @param sig [out] The destination of the shared data
+ @param siglen [in/out] The max size and resulting size of the shared data.
+ @param ctx [in] The context is a constant null terminated string
+ @param private_key The private Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519ph_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ const curve25519_key *private_key)
+{
+ int err;
+ unsigned char msg_hash[64];
+ unsigned char ctx_prefix[292];
+ unsigned long ctx_prefix_size = sizeof(ctx_prefix);
+
+ if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK)
+ return err;
+
+ if ((err = tweetnacl_crypto_ph(msg_hash, msg, msglen)) != CRYPT_OK)
+ return err;
+
+ return s_ed25519_sign(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, private_key);
+}
+
+/**
+ Create an Ed25519 signature.
+ @param msg The data to be signed
+ @param msglen [in] The size of the date to be signed
+ @param sig [out] The destination of the shared data
+ @param siglen [in/out] The max size and resulting size of the shared data.
+ @param private_key The private Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519_sign(const unsigned char *msg, unsigned long msglen,
+ unsigned char *sig, unsigned long *siglen,
+ const curve25519_key *private_key)
+{
+ return s_ed25519_sign(msg, msglen, sig, siglen, NULL, 0, private_key);
+}
+
#endif
diff --git a/src/ltc/pk/ed25519/ed25519_verify.c b/src/ltc/pk/ed25519/ed25519_verify.c
index d2c30c2c..e7dcc307 100644
--- a/src/ltc/pk/ed25519/ed25519_verify.c
+++ b/src/ltc/pk/ed25519/ed25519_verify.c
@@ -9,18 +9,11 @@
#ifdef LTC_CURVE25519
-/**
- Verify an Ed25519 signature.
- @param private_key The private Ed25519 key in the pair
- @param public_key The public Ed25519 key in the pair
- @param out [out] The destination of the shared data
- @param outlen [in/out] The max size and resulting size of the shared data.
- @param stat [out] The result of the signature verification, 1==valid, 0==invalid
- @return CRYPT_OK if successful
-*/
-int ed25519_verify(const unsigned char *msg, unsigned long msglen,
- const unsigned char *sig, unsigned long siglen,
- int *stat, const curve25519_key *public_key)
+static int s_ed25519_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ int *stat,
+ const curve25519_key *public_key)
{
unsigned char* m;
unsigned long long mlen;
@@ -34,7 +27,7 @@ int ed25519_verify(const unsigned char *msg, unsigned long msglen,
*stat = 0;
if (siglen != 64uL) return CRYPT_INVALID_ARG;
- if (public_key->algo != PKA_ED25519) return CRYPT_PK_INVALID_TYPE;
+ if (public_key->algo != LTC_OID_ED25519) return CRYPT_PK_INVALID_TYPE;
mlen = msglen + siglen;
if ((mlen < msglen) || (mlen < siglen)) return CRYPT_OVERFLOW;
@@ -48,14 +41,94 @@ int ed25519_verify(const unsigned char *msg, unsigned long msglen,
err = tweetnacl_crypto_sign_open(stat,
m, &mlen,
m, mlen,
+ ctx, ctxlen,
public_key->pub);
#ifdef LTC_CLEAN_STACK
- zeromem(m, mlen);
+ zeromem(m, msglen + siglen);
#endif
XFREE(m);
return err;
}
+/**
+ Verify an Ed25519ctx signature.
+ @param msg [in] The data to be verified
+ @param msglen [in] The size of the data to be verified
+ @param sig [in] The signature to be verified
+ @param siglen [in] The size of the signature to be verified
+ @param ctx [in] The context
+ @param ctxlen [in] The size of the context
+ @param stat [out] The result of the signature verification, 1==valid, 0==invalid
+ @param public_key [in] The public Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519ctx_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ int *stat,
+ const curve25519_key *public_key)
+{
+ unsigned char ctx_prefix[292];
+ unsigned long ctx_prefix_size = sizeof(ctx_prefix);
+
+ LTC_ARGCHK(ctx != NULL);
+
+ if (ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 0, ctx, ctxlen) != CRYPT_OK)
+ return CRYPT_INVALID_ARG;
+
+ return s_ed25519_verify(msg, msglen, sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
+}
+
+/**
+ Verify an Ed25519ph signature.
+ @param msg [in] The data to be verified
+ @param msglen [in] The size of the data to be verified
+ @param sig [in] The signature to be verified
+ @param siglen [in] The size of the signature to be verified
+ @param ctx [in] The context
+ @param ctxlen [in] The size of the context
+ @param stat [out] The result of the signature verification, 1==valid, 0==invalid
+ @param public_key [in] The public Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519ph_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ const unsigned char *ctx, unsigned long ctxlen,
+ int *stat,
+ const curve25519_key *public_key)
+{
+ int err;
+ unsigned char msg_hash[64];
+ unsigned char ctx_prefix[292];
+ unsigned long ctx_prefix_size = sizeof(ctx_prefix);
+
+ if ((err = ec25519_crypto_ctx(ctx_prefix, &ctx_prefix_size, 1, ctx, ctxlen)) != CRYPT_OK)
+ return err;
+
+ if ((err = tweetnacl_crypto_ph(msg_hash, msg, msglen)) != CRYPT_OK)
+ return err;
+
+ return s_ed25519_verify(msg_hash, sizeof(msg_hash), sig, siglen, ctx_prefix, ctx_prefix_size, stat, public_key);
+}
+
+/**
+ Verify an Ed25519 signature.
+ @param msg [in] The data to be verified
+ @param msglen [in] The size of the data to be verified
+ @param sig [in] The signature to be verified
+ @param siglen [in] The size of the signature to be verified
+ @param stat [out] The result of the signature verification, 1==valid, 0==invalid
+ @param public_key [in] The public Ed25519 key in the pair
+ @return CRYPT_OK if successful
+*/
+int ed25519_verify(const unsigned char *msg, unsigned long msglen,
+ const unsigned char *sig, unsigned long siglen,
+ int *stat,
+ const curve25519_key *public_key)
+{
+ return s_ed25519_verify(msg, msglen, sig, siglen, NULL, 0, stat, public_key);
+}
+
#endif
diff --git a/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c b/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c
index 7a8d6d1b..171df053 100644
--- a/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c
+++ b/src/ltc/pk/pkcs1/pkcs_1_oaep_encode.c
@@ -33,7 +33,7 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
unsigned long hLen, x, y, modulus_len;
int err;
- LTC_ARGCHK(msg != NULL);
+ LTC_ARGCHK((msglen == 0) || (msg != NULL));
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
@@ -95,9 +95,11 @@ int pkcs_1_oaep_encode(const unsigned char *msg, unsigned long msglen,
/* 0x01 byte */
DB[x++] = 0x01;
- /* message (length = msglen) */
- XMEMCPY(DB+x, msg, msglen);
- x += msglen;
+ if (msglen != 0) {
+ /* message (length = msglen) */
+ XMEMCPY(DB+x, msg, msglen);
+ x += msglen;
+ }
/* now choose a random seed */
if (prng_descriptor[prng_idx].read(seed, hLen, prng) != hLen) {
diff --git a/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c b/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c
index c07d81f8..e9880607 100644
--- a/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c
+++ b/src/ltc/pk/pkcs1/pkcs_1_v1_5_decode.c
@@ -58,7 +58,7 @@ int pkcs_1_v1_5_decode(const unsigned char *msg,
}
ps_len = i++ - 2;
- if (i >= modulus_len) {
+ if (i > modulus_len) {
/* There was no octet with hexadecimal value 0x00 to separate ps from m.
*/
result = CRYPT_INVALID_PACKET;
diff --git a/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c b/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c
index bb3436bf..a21df4bf 100644
--- a/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c
+++ b/src/ltc/pk/pkcs1/pkcs_1_v1_5_encode.c
@@ -35,6 +35,10 @@ int pkcs_1_v1_5_encode(const unsigned char *msg,
unsigned char *ps;
int result;
+ LTC_ARGCHK((msglen == 0) || (msg != NULL));
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
+
/* valid block_type? */
if ((block_type != LTC_PKCS_1_EMSA) &&
(block_type != LTC_PKCS_1_EME)) {
@@ -88,7 +92,9 @@ int pkcs_1_v1_5_encode(const unsigned char *msg,
out[0] = 0x00;
out[1] = (unsigned char)block_type; /* block_type 1 or 2 */
out[2 + ps_len] = 0x00;
- XMEMCPY(&out[2 + ps_len + 1], msg, msglen);
+ if (msglen != 0) {
+ XMEMCPY(&out[2 + ps_len + 1], msg, msglen);
+ }
*outlen = modulus_len;
result = CRYPT_OK;
diff --git a/src/ltc/pk/rsa/rsa_decrypt_key.c b/src/ltc/pk/rsa/rsa_decrypt_key.c
index 34a11f91..8c6ca3d8 100644
--- a/src/ltc/pk/rsa/rsa_decrypt_key.c
+++ b/src/ltc/pk/rsa/rsa_decrypt_key.c
@@ -33,6 +33,7 @@ int rsa_decrypt_key_ex(const unsigned char *in, unsigned long inlen
int err;
unsigned char *tmp;
+ LTC_ARGCHK(in != NULL);
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(key != NULL);
diff --git a/src/ltc/pk/rsa/rsa_encrypt_key.c b/src/ltc/pk/rsa/rsa_encrypt_key.c
index 66942608..e0f91e19 100644
--- a/src/ltc/pk/rsa/rsa_encrypt_key.c
+++ b/src/ltc/pk/rsa/rsa_encrypt_key.c
@@ -34,7 +34,7 @@ int rsa_encrypt_key_ex(const unsigned char *in, unsigned long inlen,
unsigned long modulus_bitlen, modulus_bytelen, x;
int err;
- LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK((inlen == 0) || (in != NULL));
LTC_ARGCHK(out != NULL);
LTC_ARGCHK(outlen != NULL);
LTC_ARGCHK(key != NULL);
diff --git a/src/ltc/pk/rsa/rsa_export.c b/src/ltc/pk/rsa/rsa_export.c
index ac8fed22..225224d0 100644
--- a/src/ltc/pk/rsa/rsa_export.c
+++ b/src/ltc/pk/rsa/rsa_export.c
@@ -78,7 +78,7 @@ int rsa_export(unsigned char *out, unsigned long *outlen, int type, const rsa_ke
}
err = x509_encode_subject_public_key_info(out, outlen,
- PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0);
+ LTC_OID_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0);
finish:
if (tmp != out) XFREE(tmp);
diff --git a/src/ltc/pk/rsa/rsa_import.c b/src/ltc/pk/rsa/rsa_import.c
index 5efb125e..1240a77e 100644
--- a/src/ltc/pk/rsa/rsa_import.c
+++ b/src/ltc/pk/rsa/rsa_import.c
@@ -9,8 +9,74 @@
#ifdef LTC_MRSA
+
+/**
+ Import an RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only]
+
+ The `key` passed into this function has to be already initialized and will
+ NOT be free'd on error!
+
+ @param in The packet to import from
+ @param inlen It's length (octets)
+ @param key [out] Destination for newly imported key
+ @return CRYPT_OK if successful
+*/
+int rsa_import_pkcs1(const unsigned char *in, unsigned long inlen, rsa_key *key)
+{
+ int err;
+ unsigned long version = -1;
+
+ err = der_decode_sequence_multi(in, inlen, LTC_ASN1_SHORT_INTEGER, 1UL, &version,
+ LTC_ASN1_EOL, 0UL, NULL);
+
+ if (err == CRYPT_OVERFLOW) {
+ /* the version would fit into an LTC_ASN1_SHORT_INTEGER
+ * so we try to decode as a public key
+ */
+ if ((err = der_decode_sequence_multi(in, inlen,
+ LTC_ASN1_INTEGER, 1UL, key->N,
+ LTC_ASN1_INTEGER, 1UL, key->e,
+ LTC_ASN1_EOL, 0UL, NULL)) == CRYPT_OK) {
+ key->type = PK_PUBLIC;
+ }
+ goto LBL_OUT;
+ } else if (err != CRYPT_INPUT_TOO_LONG) {
+ /* couldn't decode the version, so error out */
+ goto LBL_OUT;
+ }
+
+ if (version == 0) {
+ /* it's a private key */
+ if ((err = der_decode_sequence_multi(in, inlen,
+ LTC_ASN1_SHORT_INTEGER, 1UL, &version,
+ LTC_ASN1_INTEGER, 1UL, key->N,
+ LTC_ASN1_INTEGER, 1UL, key->e,
+ LTC_ASN1_INTEGER, 1UL, key->d,
+ LTC_ASN1_INTEGER, 1UL, key->p,
+ LTC_ASN1_INTEGER, 1UL, key->q,
+ LTC_ASN1_INTEGER, 1UL, key->dP,
+ LTC_ASN1_INTEGER, 1UL, key->dQ,
+ LTC_ASN1_INTEGER, 1UL, key->qP,
+ LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
+ goto LBL_OUT;
+ }
+ key->type = PK_PRIVATE;
+ } else if (version == 1) {
+ /* we don't support multi-prime RSA */
+ err = CRYPT_PK_INVALID_TYPE;
+ goto LBL_OUT;
+ }
+ err = CRYPT_OK;
+LBL_OUT:
+ return err;
+}
+
/**
- Import an RSAPublicKey or RSAPrivateKey [two-prime only, only support >= 1024-bit keys, defined in PKCS #1 v2.1]
+ Import multiple formats of RSA public and private keys.
+
+ RSAPublicKey or RSAPrivateKey as defined in PKCS #1 v2.1 [two-prime only]
+ SubjectPublicKeyInfo formatted public keys
+
@param in The packet to import from
@param inlen It's length (octets)
@param key [out] Destination for newly imported key
@@ -19,7 +85,6 @@
int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
{
int err;
- void *zero;
unsigned char *tmpbuf=NULL;
unsigned long tmpbuf_len, len;
@@ -42,7 +107,7 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
len = 0;
err = x509_decode_subject_public_key_info(in, inlen,
- PKA_RSA, tmpbuf, &tmpbuf_len,
+ LTC_OID_RSA, tmpbuf, &tmpbuf_len,
LTC_ASN1_NULL, NULL, &len);
if (err == CRYPT_OK) { /* SubjectPublicKeyInfo format */
@@ -60,50 +125,9 @@ int rsa_import(const unsigned char *in, unsigned long inlen, rsa_key *key)
}
/* not SSL public key, try to match against PKCS #1 standards */
- err = der_decode_sequence_multi(in, inlen, LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_EOL, 0UL, NULL);
-
- if (err != CRYPT_OK && err != CRYPT_INPUT_TOO_LONG) {
- goto LBL_ERR;
- }
-
- if (mp_cmp_d(key->N, 0) == LTC_MP_EQ) {
- if ((err = mp_init(&zero)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- /* it's a private key */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_INTEGER, 1UL, zero,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_INTEGER, 1UL, key->d,
- LTC_ASN1_INTEGER, 1UL, key->p,
- LTC_ASN1_INTEGER, 1UL, key->q,
- LTC_ASN1_INTEGER, 1UL, key->dP,
- LTC_ASN1_INTEGER, 1UL, key->dQ,
- LTC_ASN1_INTEGER, 1UL, key->qP,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- mp_clear(zero);
- goto LBL_ERR;
- }
- mp_clear(zero);
- key->type = PK_PRIVATE;
- } else if (mp_cmp_d(key->N, 1) == LTC_MP_EQ) {
- /* we don't support multi-prime RSA */
- err = CRYPT_PK_INVALID_TYPE;
- goto LBL_ERR;
- } else {
- /* it's a public key and we lack e */
- if ((err = der_decode_sequence_multi(in, inlen,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_EOL, 0UL, NULL)) != CRYPT_OK) {
- goto LBL_ERR;
- }
- key->type = PK_PUBLIC;
+ if ((err = rsa_import_pkcs1(in, inlen, key)) == CRYPT_OK) {
+ goto LBL_FREE;
}
- err = CRYPT_OK;
- goto LBL_FREE;
LBL_ERR:
rsa_free(key);
diff --git a/src/ltc/pk/rsa/rsa_import_pkcs8.c b/src/ltc/pk/rsa/rsa_import_pkcs8.c
index 5d0bb6d2..9e02585c 100644
--- a/src/ltc/pk/rsa/rsa_import_pkcs8.c
+++ b/src/ltc/pk/rsa/rsa_import_pkcs8.c
@@ -46,10 +46,9 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
rsa_key *key)
{
int err;
- void *zero, *iter;
unsigned char *buf1 = NULL, *buf2 = NULL;
unsigned long buf1len, buf2len;
- unsigned long oid[16];
+ unsigned long oid[16], version;
const char *rsaoid;
ltc_asn1_list alg_seq[2], top_seq[3];
ltc_asn1_list *l = NULL;
@@ -61,7 +60,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
LTC_ARGCHK(ltc_mp.name != NULL);
/* get RSA alg oid */
- err = pk_get_oid(PKA_RSA, &rsaoid);
+ err = pk_get_oid(LTC_OID_RSA, &rsaoid);
if (err != CRYPT_OK) { goto LBL_NOFREE; }
/* alloc buffers */
@@ -72,9 +71,8 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
buf2 = XMALLOC(buf2len);
if (buf2 == NULL) { err = CRYPT_MEM; goto LBL_FREE1; }
- if ((err = mp_init_multi(&zero, &iter, NULL)) != CRYPT_OK) { goto LBL_FREE2; }
/* init key */
- if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE3; }
+ if ((err = rsa_init(key)) != CRYPT_OK) { goto LBL_FREE2; }
/* try to decode encrypted priv key */
if ((err = pkcs8_decode_flexi(in, inlen, passwd, passwdlen, &l)) != CRYPT_OK) {
@@ -86,7 +84,7 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
/* try to decode unencrypted priv key */
LTC_SET_ASN1(alg_seq, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid, 16UL);
LTC_SET_ASN1(alg_seq, 1, LTC_ASN1_NULL, NULL, 0UL);
- LTC_SET_ASN1(top_seq, 0, LTC_ASN1_INTEGER, zero, 1UL);
+ LTC_SET_ASN1(top_seq, 0, LTC_ASN1_SHORT_INTEGER, &version, 1UL);
LTC_SET_ASN1(top_seq, 1, LTC_ASN1_SEQUENCE, alg_seq, 2UL);
LTC_SET_ASN1(top_seq, 2, LTC_ASN1_OCTET_STRING, buf1, buf1len);
err=der_decode_sequence(decrypted, decryptedlen, top_seq, 3UL);
@@ -97,28 +95,17 @@ int rsa_import_pkcs8(const unsigned char *in, unsigned long inlen,
goto LBL_ERR;
}
- err = der_decode_sequence_multi(buf1, top_seq[2].size,
- LTC_ASN1_INTEGER, 1UL, zero,
- LTC_ASN1_INTEGER, 1UL, key->N,
- LTC_ASN1_INTEGER, 1UL, key->e,
- LTC_ASN1_INTEGER, 1UL, key->d,
- LTC_ASN1_INTEGER, 1UL, key->p,
- LTC_ASN1_INTEGER, 1UL, key->q,
- LTC_ASN1_INTEGER, 1UL, key->dP,
- LTC_ASN1_INTEGER, 1UL, key->dQ,
- LTC_ASN1_INTEGER, 1UL, key->qP,
- LTC_ASN1_EOL, 0UL, NULL);
- if (err != CRYPT_OK) { goto LBL_ERR; }
+ if ((err = rsa_import_pkcs1(buf1, top_seq[2].size, key)) != CRYPT_OK) {
+ goto LBL_ERR;
+ }
key->type = PK_PRIVATE;
err = CRYPT_OK;
- goto LBL_FREE3;
+ goto LBL_FREE2;
LBL_ERR:
rsa_free(key);
-LBL_FREE3:
- mp_clear_multi(iter, zero, NULL);
- if (l) der_free_sequence_flexi(l);
LBL_FREE2:
+ if (l) der_free_sequence_flexi(l);
XFREE(buf2);
LBL_FREE1:
XFREE(buf1);
diff --git a/src/ltc/pk/rsa/rsa_import_x509.c b/src/ltc/pk/rsa/rsa_import_x509.c
index a66a2672..e921aae0 100644
--- a/src/ltc/pk/rsa/rsa_import_x509.c
+++ b/src/ltc/pk/rsa/rsa_import_x509.c
@@ -39,7 +39,7 @@ int rsa_import_x509(const unsigned char *in, unsigned long inlen, rsa_key *key)
}
if ((err = x509_decode_public_key_from_certificate(in, inlen,
- PKA_RSA, LTC_ASN1_NULL,
+ LTC_OID_RSA, LTC_ASN1_NULL,
NULL, NULL,
(public_key_decode_cb)s_rsa_decode, key)) != CRYPT_OK) {
rsa_free(key);
diff --git a/src/ltc/pk/rsa/rsa_key.c b/src/ltc/pk/rsa/rsa_key.c
index 48a1d8fd..2d0712f2 100644
--- a/src/ltc/pk/rsa/rsa_key.c
+++ b/src/ltc/pk/rsa/rsa_key.c
@@ -87,7 +87,7 @@ void rsa_shrink_key(rsa_key *key)
int rsa_init(rsa_key *key)
{
LTC_ARGCHK(key != NULL);
- return mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, NULL);
+ return mp_init_multi(&key->e, &key->d, &key->N, &key->dQ, &key->dP, &key->qP, &key->p, &key->q, LTC_NULL);
}
/**
@@ -97,7 +97,7 @@ int rsa_init(rsa_key *key)
void rsa_free(rsa_key *key)
{
LTC_ARGCHKVD(key != NULL);
- mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, NULL);
+ mp_cleanup_multi(&key->q, &key->p, &key->qP, &key->dP, &key->dQ, &key->N, &key->d, &key->e, LTC_NULL);
}
#endif
diff --git a/src/ltc/pk/rsa/rsa_make_key.c b/src/ltc/pk/rsa/rsa_make_key.c
index e0402afd..6bfc0419 100644
--- a/src/ltc/pk/rsa/rsa_make_key.c
+++ b/src/ltc/pk/rsa/rsa_make_key.c
@@ -22,7 +22,7 @@ static int s_rsa_make_key(prng_state *prng, int wprng, int size, void *e, rsa_ke
return err;
}
- if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, NULL)) != CRYPT_OK) {
+ if ((err = mp_init_multi(&p, &q, &tmp1, &tmp2, LTC_NULL)) != CRYPT_OK) {
return err;
}
@@ -76,7 +76,7 @@ static int s_rsa_make_key(prng_state *prng, int wprng, int size, void *e, rsa_ke
errkey:
rsa_free(key);
cleanup:
- mp_clear_multi(tmp2, tmp1, q, p, NULL);
+ mp_clear_multi(tmp2, tmp1, q, p, LTC_NULL);
return err;
}
diff --git a/src/ltc/pk/rsa/rsa_verify_hash.c b/src/ltc/pk/rsa/rsa_verify_hash.c
index ca4cdf9c..d946a202 100644
--- a/src/ltc/pk/rsa/rsa_verify_hash.c
+++ b/src/ltc/pk/rsa/rsa_verify_hash.c
@@ -136,7 +136,7 @@ int rsa_verify_hash_ex(const unsigned char *sig, unsigned long sigle
LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 2);
LTC_SET_ASN1(siginfo, 1, LTC_ASN1_OCTET_STRING, tmpbuf, siglen);
- if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) {
+ if (der_decode_sequence_strict(out, outlen, siginfo, 2) != CRYPT_OK) {
/* fallback to Legacy:missing NULL */
LTC_SET_ASN1(siginfo, 0, LTC_ASN1_SEQUENCE, digestinfo, 1);
if ((err = der_decode_sequence_strict(out, outlen, siginfo, 2)) != CRYPT_OK) {
diff --git a/src/ltc/pk/x25519/x25519_export.c b/src/ltc/pk/x25519/x25519_export.c
index c828512b..0687c135 100644
--- a/src/ltc/pk/x25519/x25519_export.c
+++ b/src/ltc/pk/x25519/x25519_export.c
@@ -23,7 +23,7 @@ int x25519_export( unsigned char *out, unsigned long *outlen,
{
LTC_ARGCHK(key != NULL);
- if (key->algo != PKA_X25519) return CRYPT_PK_INVALID_TYPE;
+ if (key->algo != LTC_OID_X25519) return CRYPT_PK_INVALID_TYPE;
return ec25519_export(out, outlen, which, key);
}
diff --git a/src/ltc/pk/x25519/x25519_import.c b/src/ltc/pk/x25519/x25519_import.c
index ddbbd54b..247885f9 100644
--- a/src/ltc/pk/x25519/x25519_import.c
+++ b/src/ltc/pk/x25519/x25519_import.c
@@ -25,9 +25,9 @@ int x25519_import(const unsigned char *in, unsigned long inlen, curve25519_key *
LTC_ARGCHK(key != NULL);
key_len = sizeof(key->pub);
- if ((err = x509_decode_subject_public_key_info(in, inlen, PKA_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
+ if ((err = x509_decode_subject_public_key_info(in, inlen, LTC_OID_X25519, key->pub, &key_len, LTC_ASN1_EOL, NULL, 0uL)) == CRYPT_OK) {
key->type = PK_PUBLIC;
- key->algo = PKA_X25519;
+ key->algo = LTC_OID_X25519;
}
return err;
}
diff --git a/src/ltc/pk/x25519/x25519_import_pkcs8.c b/src/ltc/pk/x25519/x25519_import_pkcs8.c
index 878df8cd..8b577c31 100644
--- a/src/ltc/pk/x25519/x25519_import_pkcs8.c
+++ b/src/ltc/pk/x25519/x25519_import_pkcs8.c
@@ -22,7 +22,7 @@ int x25519_import_pkcs8(const unsigned char *in, unsigned long inlen,
const void *pwd, unsigned long pwdlen,
curve25519_key *key)
{
- return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, PKA_X25519, tweetnacl_crypto_scalarmult_base, key);
+ return ec25519_import_pkcs8(in, inlen, pwd, pwdlen, LTC_OID_X25519, tweetnacl_crypto_scalarmult_base, key);
}
#endif
diff --git a/src/ltc/pk/x25519/x25519_import_raw.c b/src/ltc/pk/x25519/x25519_import_raw.c
index d118e341..e86e8c6a 100644
--- a/src/ltc/pk/x25519/x25519_import_raw.c
+++ b/src/ltc/pk/x25519/x25519_import_raw.c
@@ -32,7 +32,7 @@ int x25519_import_raw(const unsigned char *in, unsigned long inlen, int which, c
} else {
return CRYPT_INVALID_ARG;
}
- key->algo = PKA_X25519;
+ key->algo = LTC_OID_X25519;
key->type = which;
return CRYPT_OK;
diff --git a/src/ltc/pk/x25519/x25519_import_x509.c b/src/ltc/pk/x25519/x25519_import_x509.c
index 18e0b67d..043b6ad9 100644
--- a/src/ltc/pk/x25519/x25519_import_x509.c
+++ b/src/ltc/pk/x25519/x25519_import_x509.c
@@ -31,13 +31,13 @@ int x25519_import_x509(const unsigned char *in, unsigned long inlen, curve25519_
LTC_ARGCHK(key != NULL);
if ((err = x509_decode_public_key_from_certificate(in, inlen,
- PKA_X25519,
+ LTC_OID_X25519,
LTC_ASN1_EOL, NULL, NULL,
(public_key_decode_cb)s_x25519_decode, key)) != CRYPT_OK) {
return err;
}
key->type = PK_PUBLIC;
- key->algo = PKA_X25519;
+ key->algo = LTC_OID_X25519;
return err;
}
diff --git a/src/ltc/pk/x25519/x25519_make_key.c b/src/ltc/pk/x25519/x25519_make_key.c
index 610eb96f..40276fe9 100644
--- a/src/ltc/pk/x25519/x25519_make_key.c
+++ b/src/ltc/pk/x25519/x25519_make_key.c
@@ -34,7 +34,7 @@ int x25519_make_key(prng_state *prng, int wprng, curve25519_key *key)
tweetnacl_crypto_scalarmult_base(key->pub, key->priv);
key->type = PK_PRIVATE;
- key->algo = PKA_X25519;
+ key->algo = LTC_OID_X25519;
return err;
}