libtomcrypt update
Karel Miko
5 years ago
55 | 55 | ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \ |
56 | 56 | ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \ |
57 | 57 | ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/padding/padding_depad.o \ |
58 | ltc/misc/padding/padding_pad.o ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o \ | |
59 | ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ | |
60 | ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o ltc/modes/cfb/cfb_decrypt.o \ | |
61 | ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o \ | |
62 | ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o \ | |
63 | ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o \ | |
64 | ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o ltc/modes/ecb/ecb_start.o ltc/modes/ofb/ofb_decrypt.o \ | |
65 | ltc/modes/ofb/ofb_done.o ltc/modes/ofb/ofb_encrypt.o ltc/modes/ofb/ofb_getiv.o ltc/modes/ofb/ofb_setiv.o \ | |
66 | ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o ltc/pk/asn1/der/bit/der_decode_raw_bit_string.o \ | |
67 | ltc/pk/asn1/der/bit/der_encode_bit_string.o ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o \ | |
68 | ltc/pk/asn1/der/bit/der_length_bit_string.o ltc/pk/asn1/der/boolean/der_decode_boolean.o \ | |
69 | ltc/pk/asn1/der/boolean/der_encode_boolean.o ltc/pk/asn1/der/boolean/der_length_boolean.o \ | |
70 | ltc/pk/asn1/der/choice/der_decode_choice.o ltc/pk/asn1/der/custom_type/der_decode_custom_type.o \ | |
71 | ltc/pk/asn1/der/custom_type/der_encode_custom_type.o ltc/pk/asn1/der/custom_type/der_length_custom_type.o \ | |
72 | ltc/pk/asn1/der/general/der_asn1_maps.o ltc/pk/asn1/der/general/der_decode_asn1_identifier.o \ | |
73 | ltc/pk/asn1/der/general/der_decode_asn1_length.o ltc/pk/asn1/der/general/der_encode_asn1_identifier.o \ | |
74 | ltc/pk/asn1/der/general/der_encode_asn1_length.o ltc/pk/asn1/der/general/der_length_asn1_identifier.o \ | |
75 | ltc/pk/asn1/der/general/der_length_asn1_length.o ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o \ | |
76 | ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o \ | |
77 | ltc/pk/asn1/der/ia5/der_decode_ia5_string.o ltc/pk/asn1/der/ia5/der_encode_ia5_string.o \ | |
78 | ltc/pk/asn1/der/ia5/der_length_ia5_string.o ltc/pk/asn1/der/integer/der_decode_integer.o \ | |
79 | ltc/pk/asn1/der/integer/der_encode_integer.o ltc/pk/asn1/der/integer/der_length_integer.o \ | |
80 | ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.o \ | |
81 | ltc/pk/asn1/der/object_identifier/der_length_object_identifier.o ltc/pk/asn1/der/octet/der_decode_octet_string.o \ | |
82 | ltc/pk/asn1/der/octet/der_encode_octet_string.o ltc/pk/asn1/der/octet/der_length_octet_string.o \ | |
83 | ltc/pk/asn1/der/printable_string/der_decode_printable_string.o ltc/pk/asn1/der/printable_string/der_encode_printable_string.o \ | |
84 | ltc/pk/asn1/der/printable_string/der_length_printable_string.o ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o \ | |
85 | ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o \ | |
86 | ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o \ | |
87 | ltc/pk/asn1/der/sequence/der_length_sequence.o ltc/pk/asn1/der/sequence/der_sequence_free.o \ | |
88 | ltc/pk/asn1/der/sequence/der_sequence_shrink.o ltc/pk/asn1/der/set/der_encode_set.o \ | |
89 | ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ | |
58 | ltc/misc/padding/padding_pad.o ltc/misc/pkcs12/pkcs12_kdf.o ltc/misc/pkcs12/pkcs12_utf8_to_utf16.o \ | |
59 | ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o \ | |
60 | ltc/modes/cbc/cbc_encrypt.o ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o \ | |
61 | ltc/modes/cfb/cfb_decrypt.o ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o \ | |
62 | ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o \ | |
63 | ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o ltc/modes/ctr/ctr_getiv.o ltc/modes/ctr/ctr_setiv.o \ | |
64 | ltc/modes/ctr/ctr_start.o ltc/modes/ecb/ecb_decrypt.o ltc/modes/ecb/ecb_done.o ltc/modes/ecb/ecb_encrypt.o \ | |
65 | ltc/modes/ecb/ecb_start.o ltc/modes/ofb/ofb_decrypt.o ltc/modes/ofb/ofb_done.o ltc/modes/ofb/ofb_encrypt.o \ | |
66 | ltc/modes/ofb/ofb_getiv.o ltc/modes/ofb/ofb_setiv.o ltc/modes/ofb/ofb_start.o ltc/pk/asn1/der/bit/der_decode_bit_string.o \ | |
67 | ltc/pk/asn1/der/bit/der_decode_raw_bit_string.o ltc/pk/asn1/der/bit/der_encode_bit_string.o \ | |
68 | ltc/pk/asn1/der/bit/der_encode_raw_bit_string.o ltc/pk/asn1/der/bit/der_length_bit_string.o \ | |
69 | ltc/pk/asn1/der/boolean/der_decode_boolean.o ltc/pk/asn1/der/boolean/der_encode_boolean.o \ | |
70 | ltc/pk/asn1/der/boolean/der_length_boolean.o ltc/pk/asn1/der/choice/der_decode_choice.o \ | |
71 | ltc/pk/asn1/der/custom_type/der_decode_custom_type.o ltc/pk/asn1/der/custom_type/der_encode_custom_type.o \ | |
72 | ltc/pk/asn1/der/custom_type/der_length_custom_type.o ltc/pk/asn1/der/general/der_asn1_maps.o \ | |
73 | ltc/pk/asn1/der/general/der_decode_asn1_identifier.o ltc/pk/asn1/der/general/der_decode_asn1_length.o \ | |
74 | ltc/pk/asn1/der/general/der_encode_asn1_identifier.o ltc/pk/asn1/der/general/der_encode_asn1_length.o \ | |
75 | ltc/pk/asn1/der/general/der_length_asn1_identifier.o ltc/pk/asn1/der/general/der_length_asn1_length.o \ | |
76 | ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.o ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.o \ | |
77 | ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.o ltc/pk/asn1/der/ia5/der_decode_ia5_string.o \ | |
78 | ltc/pk/asn1/der/ia5/der_encode_ia5_string.o ltc/pk/asn1/der/ia5/der_length_ia5_string.o \ | |
79 | ltc/pk/asn1/der/integer/der_decode_integer.o ltc/pk/asn1/der/integer/der_encode_integer.o \ | |
80 | ltc/pk/asn1/der/integer/der_length_integer.o ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.o \ | |
81 | ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.o ltc/pk/asn1/der/object_identifier/der_length_object_identifier.o \ | |
82 | ltc/pk/asn1/der/octet/der_decode_octet_string.o ltc/pk/asn1/der/octet/der_encode_octet_string.o \ | |
83 | ltc/pk/asn1/der/octet/der_length_octet_string.o ltc/pk/asn1/der/printable_string/der_decode_printable_string.o \ | |
84 | ltc/pk/asn1/der/printable_string/der_encode_printable_string.o ltc/pk/asn1/der/printable_string/der_length_printable_string.o \ | |
85 | ltc/pk/asn1/der/sequence/der_decode_sequence_ex.o ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.o \ | |
86 | ltc/pk/asn1/der/sequence/der_decode_sequence_multi.o ltc/pk/asn1/der/sequence/der_encode_sequence_ex.o \ | |
87 | ltc/pk/asn1/der/sequence/der_encode_sequence_multi.o ltc/pk/asn1/der/sequence/der_length_sequence.o \ | |
88 | ltc/pk/asn1/der/sequence/der_sequence_free.o ltc/pk/asn1/der/sequence/der_sequence_shrink.o \ | |
89 | ltc/pk/asn1/der/set/der_encode_set.o ltc/pk/asn1/der/set/der_encode_setof.o ltc/pk/asn1/der/short_integer/der_decode_short_integer.o \ | |
90 | 90 | ltc/pk/asn1/der/short_integer/der_encode_short_integer.o ltc/pk/asn1/der/short_integer/der_length_short_integer.o \ |
91 | 91 | ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.o ltc/pk/asn1/der/teletex_string/der_length_teletex_string.o \ |
92 | 92 | ltc/pk/asn1/der/utctime/der_decode_utctime.o ltc/pk/asn1/der/utctime/der_encode_utctime.o \ |
101 | 101 | ltc/pk/dsa/dsa_set_pqg_dsaparam.o ltc/pk/dsa/dsa_shared_secret.o ltc/pk/dsa/dsa_sign_hash.o \ |
102 | 102 | ltc/pk/dsa/dsa_verify_hash.o ltc/pk/dsa/dsa_verify_key.o ltc/pk/ecc/ecc.o ltc/pk/ecc/ecc_ansi_x963_export.o \ |
103 | 103 | ltc/pk/ecc/ecc_ansi_x963_import.o ltc/pk/ecc/ecc_decrypt_key.o ltc/pk/ecc/ecc_encrypt_key.o \ |
104 | ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_free.o ltc/pk/ecc/ecc_get_curve.o \ | |
105 | 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 \ | |
106 | ltc/pk/ecc/ecc_import_openssl.o ltc/pk/ecc/ecc_import_pkcs8.o ltc/pk/ecc/ecc_import_x509.o \ | |
107 | ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_set_dp.o ltc/pk/ecc/ecc_set_dp_internal.o \ | |
108 | ltc/pk/ecc/ecc_set_key.o ltc/pk/ecc/ecc_shared_secret.o ltc/pk/ecc/ecc_sign_hash.o \ | |
109 | ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ltc_ecc_export_point.o \ | |
104 | ltc/pk/ecc/ecc_export.o ltc/pk/ecc/ecc_export_openssl.o ltc/pk/ecc/ecc_find_curve.o \ | |
105 | 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 \ | |
106 | ltc/pk/ecc/ecc_import.o ltc/pk/ecc/ecc_import_openssl.o ltc/pk/ecc/ecc_import_pkcs8.o \ | |
107 | ltc/pk/ecc/ecc_import_x509.o ltc/pk/ecc/ecc_make_key.o ltc/pk/ecc/ecc_set_curve.o \ | |
108 | ltc/pk/ecc/ecc_set_curve_internal.o ltc/pk/ecc/ecc_set_key.o ltc/pk/ecc/ecc_shared_secret.o \ | |
109 | ltc/pk/ecc/ecc_sign_hash.o ltc/pk/ecc/ecc_sizes.o ltc/pk/ecc/ecc_verify_hash.o ltc/pk/ecc/ltc_ecc_export_point.o \ | |
110 | 110 | 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 \ |
111 | 111 | ltc/pk/ecc/ltc_ecc_map.o ltc/pk/ecc/ltc_ecc_mul2add.o ltc/pk/ecc/ltc_ecc_mulmod.o \ |
112 | 112 | ltc/pk/ecc/ltc_ecc_mulmod_timing.o ltc/pk/ecc/ltc_ecc_points.o ltc/pk/ecc/ltc_ecc_projective_add_point.o \ |
59 | 59 | ltc/misc/crypt/crypt_register_hash.obj ltc/misc/crypt/crypt_register_prng.obj ltc/misc/crypt/crypt_sizes.obj \ |
60 | 60 | ltc/misc/crypt/crypt_unregister_cipher.obj ltc/misc/crypt/crypt_unregister_hash.obj \ |
61 | 61 | ltc/misc/crypt/crypt_unregister_prng.obj ltc/misc/hkdf/hkdf.obj ltc/misc/padding/padding_depad.obj \ |
62 | ltc/misc/padding/padding_pad.obj ltc/misc/pkcs5/pkcs_5_1.obj ltc/misc/pkcs5/pkcs_5_2.obj \ | |
63 | ltc/modes/cbc/cbc_decrypt.obj ltc/modes/cbc/cbc_done.obj ltc/modes/cbc/cbc_encrypt.obj \ | |
64 | ltc/modes/cbc/cbc_getiv.obj ltc/modes/cbc/cbc_setiv.obj ltc/modes/cbc/cbc_start.obj \ | |
65 | ltc/modes/cfb/cfb_decrypt.obj ltc/modes/cfb/cfb_done.obj ltc/modes/cfb/cfb_encrypt.obj \ | |
66 | ltc/modes/cfb/cfb_getiv.obj ltc/modes/cfb/cfb_setiv.obj ltc/modes/cfb/cfb_start.obj \ | |
67 | ltc/modes/ctr/ctr_decrypt.obj ltc/modes/ctr/ctr_done.obj ltc/modes/ctr/ctr_encrypt.obj \ | |
68 | ltc/modes/ctr/ctr_getiv.obj ltc/modes/ctr/ctr_setiv.obj ltc/modes/ctr/ctr_start.obj \ | |
69 | ltc/modes/ecb/ecb_decrypt.obj ltc/modes/ecb/ecb_done.obj ltc/modes/ecb/ecb_encrypt.obj \ | |
70 | ltc/modes/ecb/ecb_start.obj ltc/modes/ofb/ofb_decrypt.obj ltc/modes/ofb/ofb_done.obj \ | |
71 | ltc/modes/ofb/ofb_encrypt.obj ltc/modes/ofb/ofb_getiv.obj ltc/modes/ofb/ofb_setiv.obj \ | |
72 | ltc/modes/ofb/ofb_start.obj ltc/pk/asn1/der/bit/der_decode_bit_string.obj ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj \ | |
62 | ltc/misc/padding/padding_pad.obj ltc/misc/pkcs12/pkcs12_kdf.obj ltc/misc/pkcs12/pkcs12_utf8_to_utf16.obj \ | |
63 | ltc/misc/pkcs5/pkcs_5_1.obj ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj \ | |
64 | ltc/modes/cbc/cbc_done.obj ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj \ | |
65 | ltc/modes/cbc/cbc_setiv.obj ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj \ | |
66 | ltc/modes/cfb/cfb_done.obj ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj \ | |
67 | ltc/modes/cfb/cfb_setiv.obj ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj \ | |
68 | ltc/modes/ctr/ctr_done.obj ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj \ | |
69 | ltc/modes/ctr/ctr_setiv.obj ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj \ | |
70 | ltc/modes/ecb/ecb_done.obj ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj \ | |
71 | ltc/modes/ofb/ofb_decrypt.obj ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj \ | |
72 | ltc/modes/ofb/ofb_getiv.obj ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj \ | |
73 | ltc/pk/asn1/der/bit/der_decode_bit_string.obj ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj \ | |
73 | 74 | ltc/pk/asn1/der/bit/der_encode_bit_string.obj ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj \ |
74 | 75 | ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ |
75 | 76 | ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ |
108 | 109 | ltc/pk/dsa/dsa_shared_secret.obj ltc/pk/dsa/dsa_sign_hash.obj ltc/pk/dsa/dsa_verify_hash.obj \ |
109 | 110 | ltc/pk/dsa/dsa_verify_key.obj ltc/pk/ecc/ecc.obj ltc/pk/ecc/ecc_ansi_x963_export.obj \ |
110 | 111 | ltc/pk/ecc/ecc_ansi_x963_import.obj ltc/pk/ecc/ecc_decrypt_key.obj ltc/pk/ecc/ecc_encrypt_key.obj \ |
111 | ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_free.obj \ | |
112 | ltc/pk/ecc/ecc_get_curve.obj ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_oid_str.obj \ | |
112 | ltc/pk/ecc/ecc_export.obj ltc/pk/ecc/ecc_export_openssl.obj ltc/pk/ecc/ecc_find_curve.obj \ | |
113 | ltc/pk/ecc/ecc_free.obj ltc/pk/ecc/ecc_get_key.obj ltc/pk/ecc/ecc_get_oid_str.obj \ | |
113 | 114 | ltc/pk/ecc/ecc_get_size.obj ltc/pk/ecc/ecc_import.obj ltc/pk/ecc/ecc_import_openssl.obj \ |
114 | 115 | ltc/pk/ecc/ecc_import_pkcs8.obj ltc/pk/ecc/ecc_import_x509.obj ltc/pk/ecc/ecc_make_key.obj \ |
115 | ltc/pk/ecc/ecc_set_dp.obj ltc/pk/ecc/ecc_set_dp_internal.obj ltc/pk/ecc/ecc_set_key.obj \ | |
116 | ltc/pk/ecc/ecc_set_curve.obj ltc/pk/ecc/ecc_set_curve_internal.obj ltc/pk/ecc/ecc_set_key.obj \ | |
116 | 117 | ltc/pk/ecc/ecc_shared_secret.obj ltc/pk/ecc/ecc_sign_hash.obj ltc/pk/ecc/ecc_sizes.obj \ |
117 | 118 | ltc/pk/ecc/ecc_verify_hash.obj ltc/pk/ecc/ltc_ecc_export_point.obj ltc/pk/ecc/ltc_ecc_import_point.obj \ |
118 | 119 | 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 \ |
722 | 722 | { |
723 | 723 | LTC_ARGCHK(keysize != NULL); |
724 | 724 | |
725 | if (*keysize < 16) | |
725 | if (*keysize < 16) { | |
726 | 726 | return CRYPT_INVALID_KEYSIZE; |
727 | } | |
727 | 728 | if (*keysize < 24) { |
728 | 729 | *keysize = 16; |
729 | 730 | return CRYPT_OK; |
730 | } else if (*keysize < 32) { | |
731 | } | |
732 | if (*keysize < 32) { | |
731 | 733 | *keysize = 24; |
732 | 734 | return CRYPT_OK; |
733 | } else { | |
734 | *keysize = 32; | |
735 | return CRYPT_OK; | |
736 | 735 | } |
736 | *keysize = 32; | |
737 | return CRYPT_OK; | |
737 | 738 | } |
738 | 739 | |
739 | 740 | #endif |
579 | 579 | |
580 | 580 | if (*keysize < 8) { |
581 | 581 | return CRYPT_INVALID_KEYSIZE; |
582 | } else if (*keysize > 56) { | |
582 | } | |
583 | if (*keysize > 56) { | |
583 | 584 | *keysize = 56; |
584 | 585 | } |
585 | 586 | return CRYPT_OK; |
706 | 706 | LTC_ARGCHK(keysize != NULL); |
707 | 707 | if (*keysize < 5) { |
708 | 708 | return CRYPT_INVALID_KEYSIZE; |
709 | } else if (*keysize > 16) { | |
709 | } | |
710 | if (*keysize > 16) { | |
710 | 711 | *keysize = 16; |
711 | 712 | } |
712 | 713 | return CRYPT_OK; |
2067 | 2067 | int des3_keysize(int *keysize) |
2068 | 2068 | { |
2069 | 2069 | LTC_ARGCHK(keysize != NULL); |
2070 | if (*keysize < 16) | |
2070 | if (*keysize < 16) { | |
2071 | 2071 | return CRYPT_INVALID_KEYSIZE; |
2072 | } | |
2072 | 2073 | if (*keysize < 24) { |
2073 | 2074 | *keysize = 16; |
2074 | 2075 | return CRYPT_OK; |
242 | 242 | if (*keysize >= 16) { |
243 | 243 | *keysize = 16; |
244 | 244 | return CRYPT_OK; |
245 | } else { | |
246 | return CRYPT_INVALID_KEYSIZE; | |
247 | 245 | } |
246 | return CRYPT_INVALID_KEYSIZE; | |
248 | 247 | } |
249 | 248 | |
250 | 249 | int kasumi_test(void) |
842 | 842 | if (*keysize >= 16) { |
843 | 843 | *keysize = 16; |
844 | 844 | return CRYPT_OK; |
845 | } else { | |
846 | return CRYPT_INVALID_KEYSIZE; | |
847 | 845 | } |
846 | return CRYPT_INVALID_KEYSIZE; | |
848 | 847 | } |
849 | 848 | |
850 | 849 | #endif |
313 | 313 | LTC_ARGCHK(keysize != NULL); |
314 | 314 | if (*keysize < 16) { |
315 | 315 | return CRYPT_INVALID_KEYSIZE; |
316 | } else { | |
317 | *keysize = 16; | |
318 | return CRYPT_OK; | |
319 | } | |
316 | } | |
317 | *keysize = 16; | |
318 | return CRYPT_OK; | |
320 | 319 | } |
321 | 320 | |
322 | 321 | #endif |
400 | 400 | LTC_ARGCHK(keysize != NULL); |
401 | 401 | if (*keysize < 1) { |
402 | 402 | return CRYPT_INVALID_KEYSIZE; |
403 | } else if (*keysize > 128) { | |
403 | } | |
404 | if (*keysize > 128) { | |
404 | 405 | *keysize = 128; |
405 | 406 | } |
406 | 407 | return CRYPT_OK; |
307 | 307 | LTC_ARGCHK(keysize != NULL); |
308 | 308 | if (*keysize < 8) { |
309 | 309 | return CRYPT_INVALID_KEYSIZE; |
310 | } else if (*keysize > 128) { | |
310 | } | |
311 | if (*keysize > 128) { | |
311 | 312 | *keysize = 128; |
312 | 313 | } |
313 | 314 | return CRYPT_OK; |
317 | 317 | LTC_ARGCHK(keysize != NULL); |
318 | 318 | if (*keysize < 8) { |
319 | 319 | return CRYPT_INVALID_KEYSIZE; |
320 | } else if (*keysize > 128) { | |
320 | } | |
321 | if (*keysize > 128) { | |
321 | 322 | *keysize = 128; |
322 | 323 | } |
323 | 324 | return CRYPT_OK; |
112 | 112 | unsigned char ka[LTC_SAFER_BLOCK_LEN + 1]; |
113 | 113 | unsigned char kb[LTC_SAFER_BLOCK_LEN + 1]; |
114 | 114 | |
115 | if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds) | |
115 | if (LTC_SAFER_MAX_NOF_ROUNDS < nof_rounds) { | |
116 | 116 | nof_rounds = LTC_SAFER_MAX_NOF_ROUNDS; |
117 | } | |
117 | 118 | *key++ = (unsigned char)nof_rounds; |
118 | 119 | ka[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; |
119 | 120 | kb[LTC_SAFER_BLOCK_LEN] = (unsigned char)0; |
175 | 176 | } |
176 | 177 | #endif |
177 | 178 | |
178 | int safer_k64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
179 | int safer_k64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | |
179 | 180 | { |
180 | 181 | LTC_ARGCHK(key != NULL); |
181 | 182 | LTC_ARGCHK(skey != NULL); |
182 | 183 | |
183 | if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
184 | if (num_rounds != 0 && (num_rounds < 6 || num_rounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
184 | 185 | return CRYPT_INVALID_ROUNDS; |
185 | 186 | } |
186 | 187 | |
188 | 189 | return CRYPT_INVALID_KEYSIZE; |
189 | 190 | } |
190 | 191 | |
191 | Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
192 | return CRYPT_OK; | |
193 | } | |
194 | ||
195 | int safer_sk64_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
192 | Safer_Expand_Userkey(key, key, (unsigned int)(num_rounds != 0 ?num_rounds:LTC_SAFER_K64_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
193 | return CRYPT_OK; | |
194 | } | |
195 | ||
196 | int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | |
196 | 197 | { |
197 | 198 | LTC_ARGCHK(key != NULL); |
198 | 199 | LTC_ARGCHK(skey != NULL); |
199 | 200 | |
200 | if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
201 | if (num_rounds != 0 && (num_rounds < 6 || num_rounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
201 | 202 | return CRYPT_INVALID_ROUNDS; |
202 | 203 | } |
203 | 204 | |
205 | 206 | return CRYPT_INVALID_KEYSIZE; |
206 | 207 | } |
207 | 208 | |
208 | Safer_Expand_Userkey(key, key, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
209 | return CRYPT_OK; | |
210 | } | |
211 | ||
212 | int safer_k128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
209 | Safer_Expand_Userkey(key, key, (unsigned int)(num_rounds != 0 ?num_rounds:LTC_SAFER_SK64_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
210 | return CRYPT_OK; | |
211 | } | |
212 | ||
213 | int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | |
213 | 214 | { |
214 | 215 | LTC_ARGCHK(key != NULL); |
215 | 216 | LTC_ARGCHK(skey != NULL); |
216 | 217 | |
217 | if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
218 | if (num_rounds != 0 && (num_rounds < 6 || num_rounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
218 | 219 | return CRYPT_INVALID_ROUNDS; |
219 | 220 | } |
220 | 221 | |
222 | 223 | return CRYPT_INVALID_KEYSIZE; |
223 | 224 | } |
224 | 225 | |
225 | Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0 ?numrounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
226 | return CRYPT_OK; | |
227 | } | |
228 | ||
229 | int safer_sk128_setup(const unsigned char *key, int keylen, int numrounds, symmetric_key *skey) | |
226 | Safer_Expand_Userkey(key, key+8, (unsigned int)(num_rounds != 0 ?num_rounds:LTC_SAFER_K128_DEFAULT_NOF_ROUNDS), 0, skey->safer.key); | |
227 | return CRYPT_OK; | |
228 | } | |
229 | ||
230 | int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey) | |
230 | 231 | { |
231 | 232 | LTC_ARGCHK(key != NULL); |
232 | 233 | LTC_ARGCHK(skey != NULL); |
233 | 234 | |
234 | if (numrounds != 0 && (numrounds < 6 || numrounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
235 | if (num_rounds != 0 && (num_rounds < 6 || num_rounds > LTC_SAFER_MAX_NOF_ROUNDS)) { | |
235 | 236 | return CRYPT_INVALID_ROUNDS; |
236 | 237 | } |
237 | 238 | |
239 | 240 | return CRYPT_INVALID_KEYSIZE; |
240 | 241 | } |
241 | 242 | |
242 | Safer_Expand_Userkey(key, key+8, (unsigned int)(numrounds != 0?numrounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
243 | return CRYPT_OK; | |
244 | } | |
245 | ||
246 | #ifdef LTC_CLEAN_STACK | |
247 | static int _safer_ecb_encrypt(const unsigned char *block_in, | |
248 | unsigned char *block_out, | |
243 | Safer_Expand_Userkey(key, key+8, (unsigned int)(num_rounds != 0?num_rounds:LTC_SAFER_SK128_DEFAULT_NOF_ROUNDS), 1, skey->safer.key); | |
244 | return CRYPT_OK; | |
245 | } | |
246 | ||
247 | #ifdef LTC_CLEAN_STACK | |
248 | static int _safer_ecb_encrypt(const unsigned char *pt, | |
249 | unsigned char *ct, | |
249 | 250 | const symmetric_key *skey) |
250 | 251 | #else |
251 | int safer_ecb_encrypt(const unsigned char *block_in, | |
252 | unsigned char *block_out, | |
252 | int safer_ecb_encrypt(const unsigned char *pt, | |
253 | unsigned char *ct, | |
253 | 254 | const symmetric_key *skey) |
254 | 255 | #endif |
255 | 256 | { unsigned char a, b, c, d, e, f, g, h, t; |
256 | 257 | unsigned int round; |
257 | 258 | const unsigned char *key; |
258 | 259 | |
259 | LTC_ARGCHK(block_in != NULL); | |
260 | LTC_ARGCHK(block_out != NULL); | |
260 | LTC_ARGCHK(pt != NULL); | |
261 | LTC_ARGCHK(ct != NULL); | |
261 | 262 | LTC_ARGCHK(skey != NULL); |
262 | 263 | |
263 | 264 | key = skey->safer.key; |
264 | a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; | |
265 | e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; | |
265 | a = pt[0]; b = pt[1]; c = pt[2]; d = pt[3]; | |
266 | e = pt[4]; f = pt[5]; g = pt[6]; h = pt[7]; | |
266 | 267 | if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; |
267 | 268 | while(round-- > 0) |
268 | 269 | { |
279 | 280 | } |
280 | 281 | a ^= *++key; b += *++key; c += *++key; d ^= *++key; |
281 | 282 | e ^= *++key; f += *++key; g += *++key; h ^= *++key; |
282 | block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; | |
283 | block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | |
284 | block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | |
285 | block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | |
283 | ct[0] = a & 0xFF; ct[1] = b & 0xFF; | |
284 | ct[2] = c & 0xFF; ct[3] = d & 0xFF; | |
285 | ct[4] = e & 0xFF; ct[5] = f & 0xFF; | |
286 | ct[6] = g & 0xFF; ct[7] = h & 0xFF; | |
286 | 287 | return CRYPT_OK; |
287 | 288 | } |
288 | 289 | |
289 | 290 | #ifdef LTC_CLEAN_STACK |
290 | int safer_ecb_encrypt(const unsigned char *block_in, | |
291 | unsigned char *block_out, | |
292 | const symmetric_key *skey) | |
293 | { | |
294 | int err = _safer_ecb_encrypt(block_in, block_out, skey); | |
291 | int safer_ecb_encrypt(const unsigned char *pt, | |
292 | unsigned char *ct, | |
293 | const symmetric_key *skey) | |
294 | { | |
295 | int err = _safer_ecb_encrypt(pt, ct, skey); | |
295 | 296 | burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); |
296 | 297 | return err; |
297 | 298 | } |
298 | 299 | #endif |
299 | 300 | |
300 | 301 | #ifdef LTC_CLEAN_STACK |
301 | static int _safer_ecb_decrypt(const unsigned char *block_in, | |
302 | unsigned char *block_out, | |
302 | static int _safer_ecb_decrypt(const unsigned char *ct, | |
303 | unsigned char *pt, | |
303 | 304 | const symmetric_key *skey) |
304 | 305 | #else |
305 | int safer_ecb_decrypt(const unsigned char *block_in, | |
306 | unsigned char *block_out, | |
306 | int safer_ecb_decrypt(const unsigned char *ct, | |
307 | unsigned char *pt, | |
307 | 308 | const symmetric_key *skey) |
308 | 309 | #endif |
309 | 310 | { unsigned char a, b, c, d, e, f, g, h, t; |
310 | 311 | unsigned int round; |
311 | 312 | const unsigned char *key; |
312 | 313 | |
313 | LTC_ARGCHK(block_in != NULL); | |
314 | LTC_ARGCHK(block_out != NULL); | |
314 | LTC_ARGCHK(ct != NULL); | |
315 | LTC_ARGCHK(pt != NULL); | |
315 | 316 | LTC_ARGCHK(skey != NULL); |
316 | 317 | |
317 | 318 | key = skey->safer.key; |
318 | a = block_in[0]; b = block_in[1]; c = block_in[2]; d = block_in[3]; | |
319 | e = block_in[4]; f = block_in[5]; g = block_in[6]; h = block_in[7]; | |
319 | a = ct[0]; b = ct[1]; c = ct[2]; d = ct[3]; | |
320 | e = ct[4]; f = ct[5]; g = ct[6]; h = ct[7]; | |
320 | 321 | if (LTC_SAFER_MAX_NOF_ROUNDS < (round = *key)) round = LTC_SAFER_MAX_NOF_ROUNDS; |
321 | 322 | key += LTC_SAFER_BLOCK_LEN * (1 + 2 * round); |
322 | 323 | h ^= *key; g -= *--key; f -= *--key; e ^= *--key; |
334 | 335 | d = LOG(d) ^ *--key; c = EXP(c) - *--key; |
335 | 336 | b = EXP(b) - *--key; a = LOG(a) ^ *--key; |
336 | 337 | } |
337 | block_out[0] = a & 0xFF; block_out[1] = b & 0xFF; | |
338 | block_out[2] = c & 0xFF; block_out[3] = d & 0xFF; | |
339 | block_out[4] = e & 0xFF; block_out[5] = f & 0xFF; | |
340 | block_out[6] = g & 0xFF; block_out[7] = h & 0xFF; | |
338 | pt[0] = a & 0xFF; pt[1] = b & 0xFF; | |
339 | pt[2] = c & 0xFF; pt[3] = d & 0xFF; | |
340 | pt[4] = e & 0xFF; pt[5] = f & 0xFF; | |
341 | pt[6] = g & 0xFF; pt[7] = h & 0xFF; | |
341 | 342 | return CRYPT_OK; |
342 | 343 | } |
343 | 344 | |
344 | 345 | #ifdef LTC_CLEAN_STACK |
345 | int safer_ecb_decrypt(const unsigned char *block_in, | |
346 | unsigned char *block_out, | |
347 | const symmetric_key *skey) | |
348 | { | |
349 | int err = _safer_ecb_decrypt(block_in, block_out, skey); | |
346 | int safer_ecb_decrypt(const unsigned char *ct, | |
347 | unsigned char *pt, | |
348 | const symmetric_key *skey) | |
349 | { | |
350 | int err = _safer_ecb_decrypt(ct, pt, skey); | |
350 | 351 | burn_stack(sizeof(unsigned char) * 9 + sizeof(unsigned int) + sizeof(unsigned char *)); |
351 | 352 | return err; |
352 | 353 | } |
357 | 358 | LTC_ARGCHK(keysize != NULL); |
358 | 359 | if (*keysize < 8) { |
359 | 360 | return CRYPT_INVALID_KEYSIZE; |
360 | } else { | |
361 | *keysize = 8; | |
362 | return CRYPT_OK; | |
363 | } | |
361 | } | |
362 | *keysize = 8; | |
363 | return CRYPT_OK; | |
364 | 364 | } |
365 | 365 | |
366 | 366 | int safer_128_keysize(int *keysize) |
368 | 368 | LTC_ARGCHK(keysize != NULL); |
369 | 369 | if (*keysize < 16) { |
370 | 370 | return CRYPT_INVALID_KEYSIZE; |
371 | } else { | |
372 | *keysize = 16; | |
373 | return CRYPT_OK; | |
374 | } | |
371 | } | |
372 | *keysize = 16; | |
373 | return CRYPT_OK; | |
375 | 374 | } |
376 | 375 | |
377 | 376 | int safer_k64_test(void) |
546 | 546 | { |
547 | 547 | LTC_ARGCHK(keysize != NULL); |
548 | 548 | |
549 | if (*keysize < 16) | |
549 | if (*keysize < 16) { | |
550 | 550 | return CRYPT_INVALID_KEYSIZE; |
551 | } | |
551 | 552 | if (*keysize < 24) { |
552 | 553 | *keysize = 16; |
553 | 554 | } else if (*keysize < 32) { |
329 | 329 | LTC_ARGCHK(keysize != NULL); |
330 | 330 | if (*keysize < 10) { |
331 | 331 | return CRYPT_INVALID_KEYSIZE; |
332 | } else if (*keysize > 10) { | |
332 | } | |
333 | if (*keysize > 10) { | |
333 | 334 | *keysize = 10; |
334 | 335 | } |
335 | 336 | return CRYPT_OK; |
688 | 688 | int twofish_keysize(int *keysize) |
689 | 689 | { |
690 | 690 | LTC_ARGCHK(keysize); |
691 | if (*keysize < 16) | |
691 | if (*keysize < 16) { | |
692 | 692 | return CRYPT_INVALID_KEYSIZE; |
693 | } | |
693 | 694 | if (*keysize < 24) { |
694 | 695 | *keysize = 16; |
695 | 696 | return CRYPT_OK; |
696 | } else if (*keysize < 32) { | |
697 | } | |
698 | if (*keysize < 32) { | |
697 | 699 | *keysize = 24; |
698 | 700 | return CRYPT_OK; |
699 | } else { | |
700 | *keysize = 32; | |
701 | return CRYPT_OK; | |
702 | } | |
703 | } | |
704 | ||
705 | #endif | |
706 | ||
707 | ||
701 | } | |
702 | *keysize = 32; | |
703 | return CRYPT_OK; | |
704 | } | |
705 | ||
706 | #endif | |
708 | 707 | |
709 | 708 | |
710 | 709 | /* ref: $Format:%D$ */ |
65 | 65 | /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ |
66 | 66 | ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len); |
67 | 67 | for(x=last_block_len; x<ocb->block_len; x++) { |
68 | if (x == last_block_len) | |
68 | if (x == last_block_len) { | |
69 | 69 | ocb->checksum[x] ^= 0x80; |
70 | else | |
70 | } else { | |
71 | 71 | ocb->checksum[x] ^= 0x00; |
72 | } | |
72 | 73 | } |
73 | 74 | |
74 | 75 | /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */ |
67 | 67 | /* Checksum_* = Checksum_m xor (P_* || 1 || zeros(127-bitlen(P_*))) */ |
68 | 68 | ocb3_int_xor_blocks(ocb->checksum, ocb->checksum, pt+full_blocks_len, last_block_len); |
69 | 69 | for(x=last_block_len; x<ocb->block_len; x++) { |
70 | if (x == last_block_len) | |
70 | if (x == last_block_len) { | |
71 | 71 | ocb->checksum[x] ^= 0x80; |
72 | else | |
72 | } else { | |
73 | 73 | ocb->checksum[x] ^= 0x00; |
74 | } | |
74 | 75 | } |
75 | 76 | |
76 | 77 | /* Tag = ENCIPHER(K, Checksum_* xor Offset_* xor L_$) xor HASH(K,A) */ |
81 | 82 | if ((err = cipher_descriptor[ocb->cipher].ecb_encrypt(ocb->tag_part, ocb->tag_part, &ocb->key)) != CRYPT_OK) { |
82 | 83 | goto LBL_ERR; |
83 | 84 | } |
84 | } | |
85 | else { | |
85 | } else { | |
86 | 86 | /* Tag = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) xor HASH(K,A) */ |
87 | 87 | /* at this point we calculate only: Tag_part = ENCIPHER(K, Checksum_m xor Offset_m xor L_$) */ |
88 | 88 | for(x=0; x<ocb->block_len; x++) { |
159 | 159 | |
160 | 160 | static void blake2b_set_lastblock(hash_state *md) |
161 | 161 | { |
162 | if (md->blake2b.last_node) | |
162 | if (md->blake2b.last_node) { | |
163 | 163 | blake2b_set_lastnode(md); |
164 | ||
164 | } | |
165 | 165 | md->blake2b.f[0] = CONST64(0xffffffffffffffff); |
166 | 166 | } |
167 | 167 | |
176 | 176 | unsigned long i; |
177 | 177 | XMEMSET(&md->blake2b, 0, sizeof(md->blake2b)); |
178 | 178 | |
179 | for (i = 0; i < 8; ++i) | |
179 | for (i = 0; i < 8; ++i) { | |
180 | 180 | md->blake2b.h[i] = blake2b_IV[i]; |
181 | } | |
181 | 182 | } |
182 | 183 | |
183 | 184 | /* init xors IV with input parameter block */ |
218 | 219 | |
219 | 220 | LTC_ARGCHK(md != NULL); |
220 | 221 | |
221 | if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) | |
222 | if ((!outlen) || (outlen > BLAKE2B_OUTBYTES)) { | |
222 | 223 | return CRYPT_INVALID_ARG; |
223 | ||
224 | if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES)) | |
224 | } | |
225 | if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2B_KEYBYTES)) { | |
225 | 226 | return CRYPT_INVALID_ARG; |
227 | } | |
226 | 228 | |
227 | 229 | XMEMSET(P, 0, sizeof(P)); |
228 | 230 | |
415 | 417 | |
416 | 418 | /* if(md->blakebs.outlen != outlen) return CRYPT_INVALID_ARG; */ |
417 | 419 | |
418 | if (blake2b_is_lastblock(md)) | |
420 | if (blake2b_is_lastblock(md)) { | |
419 | 421 | return CRYPT_ERROR; |
422 | } | |
420 | 423 | |
421 | 424 | blake2b_increment_counter(md, md->blake2b.curlen); |
422 | 425 | blake2b_set_lastblock(md); |
423 | 426 | XMEMSET(md->blake2b.buf + md->blake2b.curlen, 0, BLAKE2B_BLOCKBYTES - md->blake2b.curlen); /* Padding */ |
424 | 427 | blake2b_compress(md, md->blake2b.buf); |
425 | 428 | |
426 | for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ | |
429 | for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ | |
427 | 430 | STORE64L(md->blake2b.h[i], buffer + i * 8); |
431 | } | |
428 | 432 | |
429 | 433 | XMEMCPY(out, buffer, md->blake2b.outlen); |
430 | 434 | zeromem(md, sizeof(hash_state)); |
151 | 151 | |
152 | 152 | static void blake2s_set_lastblock(hash_state *md) |
153 | 153 | { |
154 | if (md->blake2s.last_node) | |
154 | if (md->blake2s.last_node) { | |
155 | 155 | blake2s_set_lastnode(md); |
156 | ||
156 | } | |
157 | 157 | md->blake2s.f[0] = 0xffffffffUL; |
158 | 158 | } |
159 | 159 | |
168 | 168 | int i; |
169 | 169 | XMEMSET(&md->blake2s, 0, sizeof(struct blake2s_state)); |
170 | 170 | |
171 | for (i = 0; i < 8; ++i) | |
171 | for (i = 0; i < 8; ++i) { | |
172 | 172 | md->blake2s.h[i] = blake2s_IV[i]; |
173 | } | |
173 | 174 | |
174 | 175 | return CRYPT_OK; |
175 | 176 | } |
212 | 213 | |
213 | 214 | LTC_ARGCHK(md != NULL); |
214 | 215 | |
215 | if ((!outlen) || (outlen > BLAKE2S_OUTBYTES)) | |
216 | if ((!outlen) || (outlen > BLAKE2S_OUTBYTES)) { | |
216 | 217 | return CRYPT_INVALID_ARG; |
217 | ||
218 | if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES)) | |
218 | } | |
219 | if ((key && !keylen) || (keylen && !key) || (keylen > BLAKE2S_KEYBYTES)) { | |
219 | 220 | return CRYPT_INVALID_ARG; |
221 | } | |
220 | 222 | |
221 | 223 | XMEMSET(P, 0, sizeof(P)); |
222 | 224 | |
307 | 309 | LOAD32L(m[i], buf + i * sizeof(m[i])); |
308 | 310 | } |
309 | 311 | |
310 | for (i = 0; i < 8; ++i) | |
312 | for (i = 0; i < 8; ++i) { | |
311 | 313 | v[i] = md->blake2s.h[i]; |
314 | } | |
312 | 315 | |
313 | 316 | v[8] = blake2s_IV[0]; |
314 | 317 | v[9] = blake2s_IV[1]; |
330 | 333 | ROUND(8); |
331 | 334 | ROUND(9); |
332 | 335 | |
333 | for (i = 0; i < 8; ++i) | |
336 | for (i = 0; i < 8; ++i) { | |
334 | 337 | md->blake2s.h[i] = md->blake2s.h[i] ^ v[i] ^ v[i + 8]; |
335 | ||
338 | } | |
336 | 339 | return CRYPT_OK; |
337 | 340 | } |
338 | 341 | #undef G |
403 | 406 | |
404 | 407 | /* if(md->blake2s.outlen != outlen) return CRYPT_INVALID_ARG; */ |
405 | 408 | |
406 | if (blake2s_is_lastblock(md)) | |
409 | if (blake2s_is_lastblock(md)) { | |
407 | 410 | return CRYPT_ERROR; |
408 | ||
411 | } | |
409 | 412 | blake2s_increment_counter(md, md->blake2s.curlen); |
410 | 413 | blake2s_set_lastblock(md); |
411 | 414 | XMEMSET(md->blake2s.buf + md->blake2s.curlen, 0, BLAKE2S_BLOCKBYTES - md->blake2s.curlen); /* Padding */ |
412 | 415 | blake2s_compress(md, md->blake2s.buf); |
413 | 416 | |
414 | for (i = 0; i < 8; ++i) /* Output full hash to temp buffer */ | |
417 | for (i = 0; i < 8; ++i) { /* Output full hash to temp buffer */ | |
415 | 418 | STORE32L(md->blake2s.h[i], buffer + i * 4); |
419 | } | |
416 | 420 | |
417 | 421 | XMEMCPY(out, buffer, md->blake2s.outlen); |
418 | 422 | zeromem(md, sizeof(hash_state)); |
159 | 159 | @param len The length of the data (octets) |
160 | 160 | @return CRYPT_OK if successful |
161 | 161 | */ |
162 | static int _chc_process(hash_state * md, const unsigned char *buf, unsigned long len); | |
162 | static int _chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); | |
163 | 163 | static HASH_PROCESS(_chc_process, chc_compress, chc, (unsigned long)cipher_blocksize) |
164 | 164 | |
165 | 165 | /** |
166 | 166 | |
167 | 167 | for(round = 0; round < SHA3_KECCAK_ROUNDS; round++) { |
168 | 168 | /* Theta */ |
169 | for(i = 0; i < 5; i++) | |
169 | for(i = 0; i < 5; i++) { | |
170 | 170 | bc[i] = s[i] ^ s[i + 5] ^ s[i + 10] ^ s[i + 15] ^ s[i + 20]; |
171 | ||
171 | } | |
172 | 172 | for(i = 0; i < 5; i++) { |
173 | 173 | t = bc[(i + 4) % 5] ^ ROL64(bc[(i + 1) % 5], 1); |
174 | for(j = 0; j < 25; j += 5) | |
174 | for(j = 0; j < 25; j += 5) { | |
175 | 175 | s[j + i] ^= t; |
176 | } | |
176 | 177 | } |
177 | 178 | /* Rho Pi */ |
178 | 179 | t = s[1]; |
184 | 185 | } |
185 | 186 | /* Chi */ |
186 | 187 | for(j = 0; j < 25; j += 5) { |
187 | for(i = 0; i < 5; i++) | |
188 | for(i = 0; i < 5; i++) { | |
188 | 189 | bc[i] = s[j + i]; |
189 | for(i = 0; i < 5; i++) | |
190 | } | |
191 | for(i = 0; i < 5; i++) { | |
190 | 192 | s[j + i] ^= (~bc[(i + 1) % 5]) & bc[(i + 2) % 5]; |
193 | } | |
191 | 194 | } |
192 | 195 | /* Iota */ |
193 | 196 | s[0] ^= keccakf_rndc[round]; |
312 | 315 | } |
313 | 316 | |
314 | 317 | #ifdef LTC_SHA3 |
315 | int sha3_done(hash_state *md, unsigned char *hash) | |
316 | { | |
317 | return _done(md, hash, CONST64(0x06)); | |
318 | int sha3_done(hash_state *md, unsigned char *out) | |
319 | { | |
320 | return _done(md, out, CONST64(0x06)); | |
318 | 321 | } |
319 | 322 | #endif |
320 | 323 | |
321 | 324 | #ifdef LTC_KECCAK |
322 | int keccak_done(hash_state *md, unsigned char *hash) | |
323 | { | |
324 | return _done(md, hash, CONST64(0x01)); | |
325 | int keccak_done(hash_state *md, unsigned char *out) | |
326 | { | |
327 | return _done(md, out, CONST64(0x01)); | |
325 | 328 | } |
326 | 329 | #endif |
327 | 330 |
26 | 26 | |
27 | 27 | /* version */ |
28 | 28 | #define CRYPT 0x0118 |
29 | #define SCRYPT "1.18.1-develop" | |
29 | #define SCRYPT "1.18.2-develop" | |
30 | 30 | |
31 | 31 | /* max size of either a cipher/hash block or symmetric key [largest of the two] */ |
32 | 32 | #define MAXBLOCKSIZE 144 |
33 | 33 | |
34 | #ifndef TAB_SIZE | |
34 | 35 | /* descriptor table size */ |
35 | 36 | #define TAB_SIZE 34 |
37 | #endif | |
36 | 38 | |
37 | 39 | /* error codes [will be expanded in future releases] */ |
38 | 40 | enum { |
672 | 672 | int safer_sk64_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); |
673 | 673 | int safer_k128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); |
674 | 674 | int safer_sk128_setup(const unsigned char *key, int keylen, int num_rounds, symmetric_key *skey); |
675 | int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *key); | |
676 | int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *key); | |
675 | int safer_ecb_encrypt(const unsigned char *pt, unsigned char *ct, const symmetric_key *skey); | |
676 | int safer_ecb_decrypt(const unsigned char *ct, unsigned char *pt, const symmetric_key *skey); | |
677 | 677 | int safer_k64_test(void); |
678 | 678 | int safer_sk64_test(void); |
679 | 679 | int safer_sk128_test(void); |
1056 | 1056 | |
1057 | 1057 | int sosemanuk_setup(sosemanuk_state *ss, const unsigned char *key, unsigned long keylen); |
1058 | 1058 | int sosemanuk_setiv(sosemanuk_state *ss, const unsigned char *iv, unsigned long ivlen); |
1059 | int sosemanuk_crypt(sosemanuk_state *ss, const unsigned char *in, unsigned long datalen, unsigned char *out); | |
1059 | int sosemanuk_crypt(sosemanuk_state *ss, const unsigned char *in, unsigned long inlen, unsigned char *out); | |
1060 | 1060 | int sosemanuk_keystream(sosemanuk_state *ss, unsigned char *out, unsigned long outlen); |
1061 | 1061 | int sosemanuk_done(sosemanuk_state *ss); |
1062 | 1062 | int sosemanuk_test(void); |
416 | 416 | #define LTC_DH1536 |
417 | 417 | #define LTC_DH2048 |
418 | 418 | |
419 | #ifndef TFM_DESC | |
419 | #if defined(LTM_DESC) || defined(GMP_DESC) | |
420 | 420 | /* tfm has a problem in fp_isprime for larger key sizes */ |
421 | 421 | #define LTC_DH3072 |
422 | 422 | #define LTC_DH4096 |
462 | 462 | |
463 | 463 | #define LTC_PKCS_1 |
464 | 464 | #define LTC_PKCS_5 |
465 | #define LTC_PKCS_12 | |
465 | 466 | |
466 | 467 | /* Include ASN.1 DER (required by DSA/RSA) */ |
467 | 468 | #define LTC_DER |
249 | 249 | int chc_register(int cipher); |
250 | 250 | int chc_init(hash_state * md); |
251 | 251 | int chc_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
252 | int chc_done(hash_state * md, unsigned char *hash); | |
252 | int chc_done(hash_state * md, unsigned char *out); | |
253 | 253 | int chc_test(void); |
254 | 254 | extern const struct ltc_hash_descriptor chc_desc; |
255 | 255 | #endif |
257 | 257 | #ifdef LTC_WHIRLPOOL |
258 | 258 | int whirlpool_init(hash_state * md); |
259 | 259 | int whirlpool_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
260 | int whirlpool_done(hash_state * md, unsigned char *hash); | |
260 | int whirlpool_done(hash_state * md, unsigned char *out); | |
261 | 261 | int whirlpool_test(void); |
262 | 262 | extern const struct ltc_hash_descriptor whirlpool_desc; |
263 | 263 | #endif |
281 | 281 | extern const struct ltc_hash_descriptor sha3_256_desc; |
282 | 282 | int sha3_224_test(void); |
283 | 283 | extern const struct ltc_hash_descriptor sha3_224_desc; |
284 | int sha3_done(hash_state *md, unsigned char *hash); | |
284 | int sha3_done(hash_state *md, unsigned char *out); | |
285 | 285 | /* SHAKE128 + SHAKE256 */ |
286 | 286 | int sha3_shake_init(hash_state *md, int num); |
287 | 287 | #define sha3_shake_process(a,b,c) sha3_process(a,b,c) |
304 | 304 | int keccak_256_test(void); |
305 | 305 | extern const struct ltc_hash_descriptor keccak_224_desc; |
306 | 306 | int keccak_224_test(void); |
307 | int keccak_done(hash_state *md, unsigned char *hash); | |
307 | int keccak_done(hash_state *md, unsigned char *out); | |
308 | 308 | #endif |
309 | 309 | |
310 | 310 | #ifdef LTC_SHA512 |
311 | 311 | int sha512_init(hash_state * md); |
312 | 312 | int sha512_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
313 | int sha512_done(hash_state * md, unsigned char *hash); | |
313 | int sha512_done(hash_state * md, unsigned char *out); | |
314 | 314 | int sha512_test(void); |
315 | 315 | extern const struct ltc_hash_descriptor sha512_desc; |
316 | 316 | #endif |
321 | 321 | #endif |
322 | 322 | int sha384_init(hash_state * md); |
323 | 323 | #define sha384_process sha512_process |
324 | int sha384_done(hash_state * md, unsigned char *hash); | |
324 | int sha384_done(hash_state * md, unsigned char *out); | |
325 | 325 | int sha384_test(void); |
326 | 326 | extern const struct ltc_hash_descriptor sha384_desc; |
327 | 327 | #endif |
332 | 332 | #endif |
333 | 333 | int sha512_256_init(hash_state * md); |
334 | 334 | #define sha512_256_process sha512_process |
335 | int sha512_256_done(hash_state * md, unsigned char *hash); | |
335 | int sha512_256_done(hash_state * md, unsigned char *out); | |
336 | 336 | int sha512_256_test(void); |
337 | 337 | extern const struct ltc_hash_descriptor sha512_256_desc; |
338 | 338 | #endif |
343 | 343 | #endif |
344 | 344 | int sha512_224_init(hash_state * md); |
345 | 345 | #define sha512_224_process sha512_process |
346 | int sha512_224_done(hash_state * md, unsigned char *hash); | |
346 | int sha512_224_done(hash_state * md, unsigned char *out); | |
347 | 347 | int sha512_224_test(void); |
348 | 348 | extern const struct ltc_hash_descriptor sha512_224_desc; |
349 | 349 | #endif |
351 | 351 | #ifdef LTC_SHA256 |
352 | 352 | int sha256_init(hash_state * md); |
353 | 353 | int sha256_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
354 | int sha256_done(hash_state * md, unsigned char *hash); | |
354 | int sha256_done(hash_state * md, unsigned char *out); | |
355 | 355 | int sha256_test(void); |
356 | 356 | extern const struct ltc_hash_descriptor sha256_desc; |
357 | 357 | |
361 | 361 | #endif |
362 | 362 | int sha224_init(hash_state * md); |
363 | 363 | #define sha224_process sha256_process |
364 | int sha224_done(hash_state * md, unsigned char *hash); | |
364 | int sha224_done(hash_state * md, unsigned char *out); | |
365 | 365 | int sha224_test(void); |
366 | 366 | extern const struct ltc_hash_descriptor sha224_desc; |
367 | 367 | #endif |
370 | 370 | #ifdef LTC_SHA1 |
371 | 371 | int sha1_init(hash_state * md); |
372 | 372 | int sha1_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
373 | int sha1_done(hash_state * md, unsigned char *hash); | |
373 | int sha1_done(hash_state * md, unsigned char *out); | |
374 | 374 | int sha1_test(void); |
375 | 375 | extern const struct ltc_hash_descriptor sha1_desc; |
376 | 376 | #endif |
394 | 394 | |
395 | 395 | int blake2s_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); |
396 | 396 | int blake2s_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
397 | int blake2s_done(hash_state * md, unsigned char *hash); | |
397 | int blake2s_done(hash_state * md, unsigned char *out); | |
398 | 398 | #endif |
399 | 399 | |
400 | 400 | #ifdef LTC_BLAKE2B |
416 | 416 | |
417 | 417 | int blake2b_init(hash_state * md, unsigned long outlen, const unsigned char *key, unsigned long keylen); |
418 | 418 | int blake2b_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
419 | int blake2b_done(hash_state * md, unsigned char *hash); | |
419 | int blake2b_done(hash_state * md, unsigned char *out); | |
420 | 420 | #endif |
421 | 421 | |
422 | 422 | #ifdef LTC_MD5 |
423 | 423 | int md5_init(hash_state * md); |
424 | 424 | int md5_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
425 | int md5_done(hash_state * md, unsigned char *hash); | |
425 | int md5_done(hash_state * md, unsigned char *out); | |
426 | 426 | int md5_test(void); |
427 | 427 | extern const struct ltc_hash_descriptor md5_desc; |
428 | 428 | #endif |
430 | 430 | #ifdef LTC_MD4 |
431 | 431 | int md4_init(hash_state * md); |
432 | 432 | int md4_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
433 | int md4_done(hash_state * md, unsigned char *hash); | |
433 | int md4_done(hash_state * md, unsigned char *out); | |
434 | 434 | int md4_test(void); |
435 | 435 | extern const struct ltc_hash_descriptor md4_desc; |
436 | 436 | #endif |
438 | 438 | #ifdef LTC_MD2 |
439 | 439 | int md2_init(hash_state * md); |
440 | 440 | int md2_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
441 | int md2_done(hash_state * md, unsigned char *hash); | |
441 | int md2_done(hash_state * md, unsigned char *out); | |
442 | 442 | int md2_test(void); |
443 | 443 | extern const struct ltc_hash_descriptor md2_desc; |
444 | 444 | #endif |
446 | 446 | #ifdef LTC_TIGER |
447 | 447 | int tiger_init(hash_state * md); |
448 | 448 | int tiger_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
449 | int tiger_done(hash_state * md, unsigned char *hash); | |
449 | int tiger_done(hash_state * md, unsigned char *out); | |
450 | 450 | int tiger_test(void); |
451 | 451 | extern const struct ltc_hash_descriptor tiger_desc; |
452 | 452 | #endif |
454 | 454 | #ifdef LTC_RIPEMD128 |
455 | 455 | int rmd128_init(hash_state * md); |
456 | 456 | int rmd128_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
457 | int rmd128_done(hash_state * md, unsigned char *hash); | |
457 | int rmd128_done(hash_state * md, unsigned char *out); | |
458 | 458 | int rmd128_test(void); |
459 | 459 | extern const struct ltc_hash_descriptor rmd128_desc; |
460 | 460 | #endif |
462 | 462 | #ifdef LTC_RIPEMD160 |
463 | 463 | int rmd160_init(hash_state * md); |
464 | 464 | int rmd160_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
465 | int rmd160_done(hash_state * md, unsigned char *hash); | |
465 | int rmd160_done(hash_state * md, unsigned char *out); | |
466 | 466 | int rmd160_test(void); |
467 | 467 | extern const struct ltc_hash_descriptor rmd160_desc; |
468 | 468 | #endif |
470 | 470 | #ifdef LTC_RIPEMD256 |
471 | 471 | int rmd256_init(hash_state * md); |
472 | 472 | int rmd256_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
473 | int rmd256_done(hash_state * md, unsigned char *hash); | |
473 | int rmd256_done(hash_state * md, unsigned char *out); | |
474 | 474 | int rmd256_test(void); |
475 | 475 | extern const struct ltc_hash_descriptor rmd256_desc; |
476 | 476 | #endif |
478 | 478 | #ifdef LTC_RIPEMD320 |
479 | 479 | int rmd320_init(hash_state * md); |
480 | 480 | int rmd320_process(hash_state * md, const unsigned char *in, unsigned long inlen); |
481 | int rmd320_done(hash_state * md, unsigned char *hash); | |
481 | int rmd320_done(hash_state * md, unsigned char *out); | |
482 | 482 | int rmd320_test(void); |
483 | 483 | extern const struct ltc_hash_descriptor rmd320_desc; |
484 | 484 | #endif |
28 | 28 | const unsigned char *in, unsigned long inlen, ...); |
29 | 29 | int hmac_file(int hash, const char *fname, const unsigned char *key, |
30 | 30 | unsigned long keylen, |
31 | unsigned char *dst, unsigned long *dstlen); | |
31 | unsigned char *out, unsigned long *outlen); | |
32 | 32 | #endif |
33 | 33 | |
34 | 34 | #ifdef LTC_OMAC |
83 | 83 | |
84 | 84 | int pmac_memory(int cipher, |
85 | 85 | const unsigned char *key, unsigned long keylen, |
86 | const unsigned char *msg, unsigned long msglen, | |
86 | const unsigned char *in, unsigned long inlen, | |
87 | 87 | unsigned char *out, unsigned long *outlen); |
88 | 88 | |
89 | 89 | int pmac_memory_multi(int cipher, |
229 | 229 | const unsigned char *in, unsigned long inlen, ...); |
230 | 230 | int f9_file(int cipher, |
231 | 231 | const unsigned char *key, unsigned long keylen, |
232 | const char *filename, | |
232 | const char *fname, | |
233 | 233 | unsigned char *out, unsigned long *outlen); |
234 | 234 | int f9_test(void); |
235 | 235 | |
418 | 418 | } ccm_state; |
419 | 419 | |
420 | 420 | int ccm_init(ccm_state *ccm, int cipher, |
421 | const unsigned char *key, int keylen, int ptlen, int taglen, int aad_len); | |
421 | const unsigned char *key, int keylen, int ptlen, int taglen, int aadlen); | |
422 | 422 | |
423 | 423 | int ccm_reset(ccm_state *ccm); |
424 | 424 |
8 | 8 | |
9 | 9 | /* ---- LTC_BASE64 Routines ---- */ |
10 | 10 | #ifdef LTC_BASE64 |
11 | int base64_encode(const unsigned char *in, unsigned long len, | |
11 | int base64_encode(const unsigned char *in, unsigned long inlen, | |
12 | 12 | char *out, unsigned long *outlen); |
13 | 13 | |
14 | int base64_decode(const char *in, unsigned long len, | |
14 | int base64_decode(const char *in, unsigned long inlen, | |
15 | 15 | unsigned char *out, unsigned long *outlen); |
16 | int base64_strict_decode(const char *in, unsigned long len, | |
16 | int base64_strict_decode(const char *in, unsigned long inlen, | |
17 | 17 | unsigned char *out, unsigned long *outlen); |
18 | 18 | int base64_sane_decode(const char *in, unsigned long inlen, |
19 | 19 | unsigned char *out, unsigned long *outlen); |
20 | 20 | #endif |
21 | 21 | |
22 | 22 | #ifdef LTC_BASE64_URL |
23 | int base64url_encode(const unsigned char *in, unsigned long len, | |
23 | int base64url_encode(const unsigned char *in, unsigned long inlen, | |
24 | 24 | char *out, unsigned long *outlen); |
25 | 25 | int base64url_strict_encode(const unsigned char *in, unsigned long inlen, |
26 | 26 | char *out, unsigned long *outlen); |
27 | 27 | |
28 | int base64url_decode(const char *in, unsigned long len, | |
28 | int base64url_decode(const char *in, unsigned long inlen, | |
29 | 29 | unsigned char *out, unsigned long *outlen); |
30 | int base64url_strict_decode(const char *in, unsigned long len, | |
30 | int base64url_strict_decode(const char *in, unsigned long inlen, | |
31 | 31 | unsigned char *out, unsigned long *outlen); |
32 | 32 | int base64url_sane_decode(const char *in, unsigned long inlen, |
33 | 33 | unsigned char *out, unsigned long *outlen); |
83 | 83 | |
84 | 84 | /* ---- MEM routines ---- */ |
85 | 85 | int mem_neq(const void *a, const void *b, size_t len); |
86 | void zeromem(volatile void *dst, size_t len); | |
86 | void zeromem(volatile void *out, size_t outlen); | |
87 | 87 | void burn_stack(unsigned long len); |
88 | 88 | |
89 | 89 | const char *error_to_string(int err); |
250 | 250 | void ecc_sizes(int *low, int *high); |
251 | 251 | int ecc_get_size(const ecc_key *key); |
252 | 252 | |
253 | int ecc_get_curve(const char* name_or_oid, const ltc_ecc_curve** cu); | |
254 | int ecc_set_dp(const ltc_ecc_curve *cu, ecc_key *key); | |
253 | int ecc_find_curve(const char* name_or_oid, const ltc_ecc_curve** cu); | |
254 | int ecc_set_curve(const ltc_ecc_curve *cu, ecc_key *key); | |
255 | 255 | int ecc_generate_key(prng_state *prng, int wprng, ecc_key *key); |
256 | 256 | int ecc_set_key(const unsigned char *in, unsigned long inlen, int type, ecc_key *key); |
257 | 257 | int ecc_get_key(unsigned char *out, unsigned long *outlen, int type, const ecc_key *key); |
572 | 572 | /* INTEGER */ |
573 | 573 | int der_encode_integer(void *num, unsigned char *out, unsigned long *outlen); |
574 | 574 | int der_decode_integer(const unsigned char *in, unsigned long inlen, void *num); |
575 | int der_length_integer(void *num, unsigned long *len); | |
575 | int der_length_integer(void *num, unsigned long *outlen); | |
576 | 576 | |
577 | 577 | /* INTEGER -- handy for 0..2^32-1 values */ |
578 | 578 | int der_decode_short_integer(const unsigned char *in, unsigned long inlen, unsigned long *num); |
102 | 102 | int pkcs_5_test (void); |
103 | 103 | #endif /* LTC_PKCS_5 */ |
104 | 104 | |
105 | ||
105 | 106 | /* ref: $Format:%D$ */ |
106 | 107 | /* git commit: $Format:%H$ */ |
107 | 108 | /* commit time: $Format:%ai$ */ |
191 | 191 | |
192 | 192 | /* ---- ECC Routines ---- */ |
193 | 193 | #ifdef LTC_MECC |
194 | int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); | |
195 | int ecc_copy_dp(const ecc_key *srckey, ecc_key *key); | |
196 | int ecc_set_dp_by_size(int size, ecc_key *key); | |
194 | int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key); | |
195 | int ecc_copy_curve(const ecc_key *srckey, ecc_key *key); | |
196 | int ecc_set_curve_by_size(int size, ecc_key *key); | |
197 | 197 | int ecc_import_subject_public_key_info(const unsigned char *in, unsigned long inlen, ecc_key *key); |
198 | 198 | |
199 | 199 | /* low level functions */ |
274 | 274 | int der_length_asn1_identifier(const ltc_asn1_list *id, unsigned long *idlen); |
275 | 275 | |
276 | 276 | int der_encode_asn1_length(unsigned long len, unsigned char* out, unsigned long* outlen); |
277 | int der_decode_asn1_length(const unsigned char* len, unsigned long* lenlen, unsigned long* outlen); | |
277 | int der_decode_asn1_length(const unsigned char *in, unsigned long *inlen, unsigned long *outlen); | |
278 | 278 | int der_length_asn1_length(unsigned long len, unsigned long *outlen); |
279 | 279 | |
280 | 280 | int der_length_sequence_ex(const ltc_asn1_list *list, unsigned long inlen, |
303 | 303 | ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); |
304 | 304 | |
305 | 305 | #endif /* LTC_DER */ |
306 | ||
307 | /* tomcrypt_pkcs.h */ | |
308 | ||
309 | #ifdef LTC_PKCS_12 | |
310 | ||
311 | int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen, | |
312 | unsigned char *out, unsigned long *outlen); | |
313 | ||
314 | int pkcs12_kdf( int hash_id, | |
315 | const unsigned char *pw, unsigned long pwlen, | |
316 | const unsigned char *salt, unsigned long saltlen, | |
317 | unsigned int iterations, unsigned char purpose, | |
318 | unsigned char *out, unsigned long outlen); | |
319 | ||
320 | #endif /* LTC_PKCS_12 */ | |
306 | 321 | |
307 | 322 | /* tomcrypt_prng.h */ |
308 | 323 |
14 | 14 | |
15 | 15 | #ifdef LTC_PMAC |
16 | 16 | |
17 | int pmac_done(pmac_state *state, unsigned char *out, unsigned long *outlen) | |
17 | int pmac_done(pmac_state *pmac, unsigned char *out, unsigned long *outlen) | |
18 | 18 | { |
19 | 19 | int err, x; |
20 | 20 | |
21 | LTC_ARGCHK(state != NULL); | |
22 | LTC_ARGCHK(out != NULL); | |
23 | if ((err = cipher_is_valid(state->cipher_idx)) != CRYPT_OK) { | |
21 | LTC_ARGCHK(pmac != NULL); | |
22 | LTC_ARGCHK(out != NULL); | |
23 | if ((err = cipher_is_valid(pmac->cipher_idx)) != CRYPT_OK) { | |
24 | 24 | return err; |
25 | 25 | } |
26 | 26 | |
27 | if ((state->buflen > (int)sizeof(state->block)) || (state->buflen < 0) || | |
28 | (state->block_len > (int)sizeof(state->block)) || (state->buflen > state->block_len)) { | |
27 | if ((pmac->buflen > (int)sizeof(pmac->block)) || (pmac->buflen < 0) || | |
28 | (pmac->block_len > (int)sizeof(pmac->block)) || (pmac->buflen > pmac->block_len)) { | |
29 | 29 | return CRYPT_INVALID_ARG; |
30 | 30 | } |
31 | 31 | |
32 | 32 | |
33 | 33 | /* handle padding. If multiple xor in L/x */ |
34 | 34 | |
35 | if (state->buflen == state->block_len) { | |
35 | if (pmac->buflen == pmac->block_len) { | |
36 | 36 | /* xor Lr against the checksum */ |
37 | for (x = 0; x < state->block_len; x++) { | |
38 | state->checksum[x] ^= state->block[x] ^ state->Lr[x]; | |
37 | for (x = 0; x < pmac->block_len; x++) { | |
38 | pmac->checksum[x] ^= pmac->block[x] ^ pmac->Lr[x]; | |
39 | 39 | } |
40 | 40 | } else { |
41 | 41 | /* otherwise xor message bytes then the 0x80 byte */ |
42 | for (x = 0; x < state->buflen; x++) { | |
43 | state->checksum[x] ^= state->block[x]; | |
42 | for (x = 0; x < pmac->buflen; x++) { | |
43 | pmac->checksum[x] ^= pmac->block[x]; | |
44 | 44 | } |
45 | state->checksum[x] ^= 0x80; | |
45 | pmac->checksum[x] ^= 0x80; | |
46 | 46 | } |
47 | 47 | |
48 | 48 | /* encrypt it */ |
49 | if ((err = cipher_descriptor[state->cipher_idx].ecb_encrypt(state->checksum, state->checksum, &state->key)) != CRYPT_OK) { | |
49 | if ((err = cipher_descriptor[pmac->cipher_idx].ecb_encrypt(pmac->checksum, pmac->checksum, &pmac->key)) != CRYPT_OK) { | |
50 | 50 | return err; |
51 | 51 | } |
52 | cipher_descriptor[state->cipher_idx].done(&state->key); | |
52 | cipher_descriptor[pmac->cipher_idx].done(&pmac->key); | |
53 | 53 | |
54 | 54 | /* store it */ |
55 | for (x = 0; x < state->block_len && x < (int)*outlen; x++) { | |
56 | out[x] = state->checksum[x]; | |
55 | for (x = 0; x < pmac->block_len && x < (int)*outlen; x++) { | |
56 | out[x] = pmac->checksum[x]; | |
57 | 57 | } |
58 | 58 | *outlen = x; |
59 | 59 | |
60 | 60 | #ifdef LTC_CLEAN_STACK |
61 | zeromem(state, sizeof(*state)); | |
61 | zeromem(pmac, sizeof(*pmac)); | |
62 | 62 | #endif |
63 | 63 | return CRYPT_OK; |
64 | 64 | } |
40 | 40 | length--; |
41 | 41 | } while (length % 8 != 0); |
42 | 42 | |
43 | if (s1 >= _adler32_base) | |
43 | if (s1 >= _adler32_base) { | |
44 | 44 | s1 -= _adler32_base; |
45 | } | |
45 | 46 | s2 %= _adler32_base; |
46 | 47 | } |
47 | 48 | |
66 | 67 | length -= 8; |
67 | 68 | input += 8; |
68 | 69 | |
69 | if (s1 >= _adler32_base) | |
70 | if (s1 >= _adler32_base) { | |
70 | 71 | s1 -= _adler32_base; |
72 | } | |
71 | 73 | s2 %= _adler32_base; |
72 | 74 | } |
73 | 75 |
51 | 51 | x--; |
52 | 52 | *outlen = x; /* returning the length without terminating NUL */ |
53 | 53 | |
54 | if (options == 0) alphabet = alphabets[0]; | |
55 | else alphabet = alphabets[1]; | |
54 | if (options == 0) { | |
55 | alphabet = alphabets[0]; | |
56 | } else { | |
57 | alphabet = alphabets[1]; | |
58 | } | |
56 | 59 | |
57 | 60 | for (i = 0; i < x; i += 2) { |
58 | 61 | out[i] = alphabet[(in[i/2] >> 4) & 0x0f]; |
103 | 103 | continue; |
104 | 104 | } |
105 | 105 | if (c == 253) { |
106 | if (mode == strict) | |
106 | if (mode == strict) { | |
107 | 107 | return CRYPT_INVALID_PACKET; |
108 | else | |
109 | continue; /* allow to ignore white-spaces (relaxed+insane) */ | |
108 | } | |
109 | continue; /* allow to ignore white-spaces (relaxed+insane) */ | |
110 | 110 | } |
111 | 111 | if (c == 255) { |
112 | if (mode == insane) | |
112 | if (mode == insane) { | |
113 | 113 | continue; /* allow to ignore invalid garbage (insane) */ |
114 | else | |
115 | return CRYPT_INVALID_PACKET; | |
114 | } | |
115 | return CRYPT_INVALID_PACKET; | |
116 | 116 | } |
117 | 117 | if ((g > 0) && (mode != insane)) { |
118 | 118 | /* we only allow '=' to be at the end (strict+relaxed) */ |
20 | 20 | { |
21 | 21 | unsigned char buf[32]; |
22 | 22 | zeromem(buf, sizeof(buf)); |
23 | if (len > (unsigned long)sizeof(buf)) | |
23 | if (len > (unsigned long)sizeof(buf)) { | |
24 | 24 | burn_stack(len - sizeof(buf)); |
25 | } | |
25 | 26 | } |
26 | 27 | |
27 | 28 |
62 | 62 | int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which) |
63 | 63 | { |
64 | 64 | int res = 0; |
65 | if(is_len != should_len) | |
65 | if(is_len != should_len) { | |
66 | 66 | res = is_len > should_len ? -1 : 1; |
67 | else | |
67 | } else { | |
68 | 68 | res = XMEMCMP(is, should, is_len); |
69 | ||
69 | } | |
70 | 70 | #if defined(LTC_TEST) && defined(LTC_TEST_DBG) |
71 | 71 | if (res != 0) { |
72 | 72 | fprintf(stderr, "Testvector #%i of %s failed:\n", which, what); |
152 | 152 | LTC_ARGCHKVD(input != NULL); |
153 | 153 | crc = ctx->crc; |
154 | 154 | |
155 | while (length--) | |
155 | while (length--) { | |
156 | 156 | crc = crc32_m_tab[CRC32_INDEX(crc) ^ *input++] ^ CRC32_SHIFTED(crc); |
157 | } | |
157 | 158 | |
158 | 159 | ctx->crc = crc; |
159 | 160 | } |
435 | 435 | #if defined(LTC_PKCS_5) |
436 | 436 | " PKCS#5 " |
437 | 437 | #endif |
438 | #if defined(LTC_PKCS_12) | |
439 | " PKCS#12 " | |
440 | #endif | |
438 | 441 | #if defined(LTC_PADDING) |
439 | 442 | " PADDING " |
440 | 443 | #endif |
264 | 264 | /* calculate amount of memory required for the list */ |
265 | 265 | for (i=0; i<count; i++) { |
266 | 266 | number_len = snprintf(NULL, 0, "%s,%d\n", _crypt_constants[i].name, _crypt_constants[i].value); |
267 | if (number_len < 0) | |
267 | if (number_len < 0) { | |
268 | 268 | return -1; |
269 | } | |
269 | 270 | total_len += number_len; |
270 | 271 | } |
271 | 272 |
325 | 325 | /* calculate amount of memory required for the list */ |
326 | 326 | for (i=0; i<count; i++) { |
327 | 327 | number_len = snprintf(NULL, 0, "%s,%u\n", _crypt_sizes[i].name, _crypt_sizes[i].size); |
328 | if (number_len < 0) | |
328 | if (number_len < 0) { | |
329 | 329 | return -1; |
330 | } | |
330 | 331 | total_len += number_len; |
331 | 332 | /* this last +1 is for newlines (and ending NULL) */ |
332 | 333 | } |
67 | 67 | { |
68 | 68 | if (err < 0 || err >= (int)(sizeof(err_2_str)/sizeof(err_2_str[0]))) { |
69 | 69 | return "Invalid error code."; |
70 | } else { | |
71 | return err_2_str[err]; | |
72 | 70 | } |
71 | return err_2_str[err]; | |
73 | 72 | } |
74 | 73 | |
75 | 74 |
29 | 29 | valid results for HKDF. */ |
30 | 30 | if (salt == NULL || saltlen == 0) { |
31 | 31 | return hmac_memory(hash_idx, (const unsigned char *)"", 1, in, inlen, out, outlen); |
32 | } else { | |
33 | return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen); | |
34 | 32 | } |
33 | return hmac_memory(hash_idx, salt, saltlen, in, inlen, out, outlen); | |
35 | 34 | } |
36 | 35 | |
37 | 36 | int hkdf_expand(int hash_idx, const unsigned char *info, unsigned long infolen, |
54 | 53 | hashsize = hash_descriptor[hash_idx].hashsize; |
55 | 54 | |
56 | 55 | /* RFC5869 parameter restrictions */ |
57 | if (inlen < hashsize || outlen > hashsize * 255) | |
56 | if (inlen < hashsize || outlen > hashsize * 255) { | |
58 | 57 | return CRYPT_INVALID_ARG; |
59 | if (info == NULL && infolen != 0) | |
58 | } | |
59 | if (info == NULL && infolen != 0) { | |
60 | 60 | return CRYPT_INVALID_ARG; |
61 | } | |
61 | 62 | LTC_ARGCHK(out != NULL); |
62 | 63 | |
63 | 64 | Tlen = hashsize + infolen + 1; |
86 | 87 | } |
87 | 88 | outoff += Noutlen; |
88 | 89 | |
89 | if (outoff >= outlen) /* loop exit condition */ | |
90 | if (outoff >= outlen) { /* loop exit condition */ | |
90 | 91 | break; |
92 | } | |
91 | 93 | |
92 | 94 | /* All subsequent HMAC data T(N) DOES include the previous hash value */ |
93 | 95 | XMEMCPY(T, out + hashsize * (N-1), hashsize); |
98 | 98 | type = mode & LTC_PAD_MASK; |
99 | 99 | |
100 | 100 | if (*padded_length < l) { |
101 | if (type != LTC_PAD_ISO_10126) *padded_length = l; | |
102 | else *padded_length = length + 256; | |
101 | if (type != LTC_PAD_ISO_10126) { | |
102 | *padded_length = l; | |
103 | } else { | |
104 | *padded_length = length + 256; | |
105 | } | |
103 | 106 | return CRYPT_BUFFER_OVERFLOW; |
104 | 107 | } |
105 | 108 |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_PKCS_12 | |
12 | ||
13 | int pkcs12_kdf( int hash_id, | |
14 | const unsigned char *pw, unsigned long pwlen, | |
15 | const unsigned char *salt, unsigned long saltlen, | |
16 | unsigned int iterations, unsigned char purpose, | |
17 | unsigned char *out, unsigned long outlen) | |
18 | { | |
19 | unsigned long u = hash_descriptor[hash_id].hashsize; | |
20 | unsigned long v = hash_descriptor[hash_id].blocksize; | |
21 | unsigned long c = (outlen + u - 1) / u; | |
22 | unsigned long Slen = ((saltlen + v - 1) / v) * v; | |
23 | unsigned long Plen = ((pwlen + v - 1) / v) * v; | |
24 | unsigned long k = (Plen + Slen) / v; | |
25 | unsigned long Alen, keylen = 0; | |
26 | unsigned int tmp, i, j, n; | |
27 | unsigned char ch; | |
28 | unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE]; | |
29 | unsigned char *I = NULL, *key = NULL; | |
30 | int err = CRYPT_ERROR; | |
31 | ||
32 | LTC_ARGCHK(pw != NULL); | |
33 | LTC_ARGCHK(salt != NULL); | |
34 | LTC_ARGCHK(out != NULL); | |
35 | ||
36 | key = XMALLOC(u * c); | |
37 | I = XMALLOC(Plen + Slen); | |
38 | if (key == NULL || I == NULL) goto DONE; | |
39 | zeromem(key, u * c); | |
40 | ||
41 | for (i = 0; i < v; i++) D[i] = purpose; /* D - diversifier */ | |
42 | for (i = 0; i < Slen; i++) I[i] = salt[i % saltlen]; | |
43 | for (i = 0; i < Plen; i++) I[Slen + i] = pw[i % pwlen]; /* I = Salt || Pass */ | |
44 | ||
45 | for (i = 0; i < c; i++) { | |
46 | Alen = sizeof(A); | |
47 | err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */ | |
48 | if (err != CRYPT_OK) goto DONE; | |
49 | for (j = 1; j < iterations; j++) { | |
50 | err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */ | |
51 | if (err != CRYPT_OK) goto DONE; | |
52 | } | |
53 | /* fill buffer B with A */ | |
54 | for (j = 0; j < v; j++) B[j] = A[j % Alen]; | |
55 | /* B += 1 */ | |
56 | for (j = v; j > 0; j--) { | |
57 | if (++B[j - 1] != 0) break; | |
58 | } | |
59 | /* I_n += B */ | |
60 | for (n = 0; n < k; n++) { | |
61 | ch = 0; | |
62 | for (j = v; j > 0; j--) { | |
63 | tmp = I[n * v + j - 1] + B[j - 1] + ch; | |
64 | ch = (unsigned char)((tmp >> 8) & 0xFF); | |
65 | I[n * v + j - 1] = (unsigned char)(tmp & 0xFF); | |
66 | } | |
67 | } | |
68 | /* store derived key block */ | |
69 | XMEMCPY(&key[keylen], A, Alen); | |
70 | keylen += Alen; | |
71 | } | |
72 | ||
73 | XMEMCPY(out, key, outlen); | |
74 | err = CRYPT_OK; | |
75 | DONE: | |
76 | if (I) { | |
77 | zeromem(I, Plen + Slen); | |
78 | XFREE(I); | |
79 | } | |
80 | if (key) { | |
81 | zeromem(key, u * c); | |
82 | XFREE(key); | |
83 | } | |
84 | return err; | |
85 | } | |
86 | ||
87 | #endif | |
88 | ||
89 | /* ref: $Format:%D$ */ | |
90 | /* git commit: $Format:%H$ */ | |
91 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_PKCS_12 | |
12 | ||
13 | int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen, | |
14 | unsigned char *out, unsigned long *outlen) { | |
15 | unsigned long len = 0; | |
16 | const unsigned char* in_end = in + inlen; | |
17 | const ulong32 offset[6] = { | |
18 | 0x00000000UL, 0x00003080UL, 0x000E2080UL, | |
19 | 0x03C82080UL, 0xFA082080UL, 0x82082080UL | |
20 | }; | |
21 | int err = CRYPT_ERROR; | |
22 | ||
23 | LTC_ARGCHK(in != NULL); | |
24 | LTC_ARGCHK(out != NULL); | |
25 | LTC_ARGCHK(outlen != NULL); | |
26 | ||
27 | while (in < in_end) { | |
28 | ulong32 ch = 0; | |
29 | unsigned short extra = 0; /* 0 */ | |
30 | if (*in >= 192) extra++; /* 1 */ | |
31 | if (*in >= 224) extra++; /* 2 */ | |
32 | if (*in >= 240) extra++; /* 3 */ | |
33 | if (*in >= 248) extra++; /* 4 */ | |
34 | if (*in >= 252) extra++; /* 5 */ | |
35 | if (in + extra >= in_end) goto ERROR; | |
36 | switch (extra) { | |
37 | case 5: ch += *in++; ch <<= 6; | |
38 | /* FALLTHROUGH */ | |
39 | case 4: ch += *in++; ch <<= 6; | |
40 | /* FALLTHROUGH */ | |
41 | case 3: ch += *in++; ch <<= 6; | |
42 | /* FALLTHROUGH */ | |
43 | case 2: ch += *in++; ch <<= 6; | |
44 | /* FALLTHROUGH */ | |
45 | case 1: ch += *in++; ch <<= 6; | |
46 | /* FALLTHROUGH */ | |
47 | case 0: ch += *in++; | |
48 | } | |
49 | ch -= offset[extra]; | |
50 | if (ch > 0xFFFF) goto ERROR; | |
51 | if (*outlen >= len + 2) { | |
52 | out[len] = (unsigned short)((ch >> 8) & 0xFF); | |
53 | out[len + 1] = (unsigned char)(ch & 0xFF); | |
54 | } | |
55 | len += 2; | |
56 | } | |
57 | ||
58 | err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK; | |
59 | *outlen = len; | |
60 | ERROR: | |
61 | return err; | |
62 | } | |
63 | ||
64 | #endif | |
65 | ||
66 | /* ref: $Format:%D$ */ | |
67 | /* git commit: $Format:%H$ */ | |
68 | /* commit time: $Format:%ai$ */ |
108 | 108 | the output buffer (and how many bytes we have to copy) */ |
109 | 109 | outidx = block*hash_descriptor[hash_idx].hashsize; |
110 | 110 | nb = hash_descriptor[hash_idx].hashsize; |
111 | if(outidx+nb > *outlen) | |
111 | if(outidx+nb > *outlen) { | |
112 | 112 | nb = *outlen - outidx; |
113 | if(nb > 0) | |
113 | } | |
114 | if(nb > 0) { | |
114 | 115 | XMEMCPY(out+outidx, buf, nb); |
116 | } | |
115 | 117 | |
116 | 118 | block++; |
117 | if (!openssl_compat) | |
119 | if (!openssl_compat) { | |
118 | 120 | break; |
121 | } | |
119 | 122 | } |
120 | 123 | /* In strict mode, we always return the hashsize, in compat we filled it |
121 | 124 | as much as was requested, so we leave it alone. */ |
122 | if(!openssl_compat) | |
125 | if(!openssl_compat) { | |
123 | 126 | *outlen = hash_descriptor[hash_idx].hashsize; |
127 | } | |
124 | 128 | |
125 | 129 | err = CRYPT_OK; |
126 | 130 | LBL_ERR: |
57 | 57 | |
58 | 58 | if (cipher_descriptor[cbc->cipher].accel_cbc_decrypt != NULL) { |
59 | 59 | return cipher_descriptor[cbc->cipher].accel_cbc_decrypt(ct, pt, len / cbc->blocklen, cbc->IV, &cbc->key); |
60 | } else { | |
61 | while (len) { | |
62 | /* decrypt */ | |
63 | if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { | |
64 | return err; | |
65 | } | |
60 | } | |
61 | while (len) { | |
62 | /* decrypt */ | |
63 | if ((err = cipher_descriptor[cbc->cipher].ecb_decrypt(ct, tmp, &cbc->key)) != CRYPT_OK) { | |
64 | return err; | |
65 | } | |
66 | 66 | |
67 | /* xor IV against plaintext */ | |
68 | #if defined(LTC_FAST) | |
69 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
70 | tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x)); | |
71 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); | |
72 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy; | |
73 | } | |
74 | #else | |
75 | for (x = 0; x < cbc->blocklen; x++) { | |
76 | tmpy = tmp[x] ^ cbc->IV[x]; | |
77 | cbc->IV[x] = ct[x]; | |
78 | pt[x] = tmpy; | |
79 | } | |
80 | #endif | |
67 | /* xor IV against plaintext */ | |
68 | #if defined(LTC_FAST) | |
69 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
70 | tmpy = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^ *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)tmp + x)); | |
71 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); | |
72 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)) = tmpy; | |
73 | } | |
74 | #else | |
75 | for (x = 0; x < cbc->blocklen; x++) { | |
76 | tmpy = tmp[x] ^ cbc->IV[x]; | |
77 | cbc->IV[x] = ct[x]; | |
78 | pt[x] = tmpy; | |
79 | } | |
80 | #endif | |
81 | 81 | |
82 | ct += cbc->blocklen; | |
83 | pt += cbc->blocklen; | |
84 | len -= cbc->blocklen; | |
85 | } | |
82 | ct += cbc->blocklen; | |
83 | pt += cbc->blocklen; | |
84 | len -= cbc->blocklen; | |
86 | 85 | } |
87 | 86 | return CRYPT_OK; |
88 | 87 | } |
51 | 51 | |
52 | 52 | if (cipher_descriptor[cbc->cipher].accel_cbc_encrypt != NULL) { |
53 | 53 | return cipher_descriptor[cbc->cipher].accel_cbc_encrypt(pt, ct, len / cbc->blocklen, cbc->IV, &cbc->key); |
54 | } else { | |
55 | while (len) { | |
56 | /* xor IV against plaintext */ | |
57 | #if defined(LTC_FAST) | |
58 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
59 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)); | |
60 | } | |
61 | #else | |
62 | for (x = 0; x < cbc->blocklen; x++) { | |
63 | cbc->IV[x] ^= pt[x]; | |
64 | } | |
65 | #endif | |
54 | } | |
55 | while (len) { | |
56 | /* xor IV against plaintext */ | |
57 | #if defined(LTC_FAST) | |
58 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
59 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) ^= *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)pt + x)); | |
60 | } | |
61 | #else | |
62 | for (x = 0; x < cbc->blocklen; x++) { | |
63 | cbc->IV[x] ^= pt[x]; | |
64 | } | |
65 | #endif | |
66 | 66 | |
67 | /* encrypt */ | |
68 | if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { | |
69 | return err; | |
70 | } | |
67 | /* encrypt */ | |
68 | if ((err = cipher_descriptor[cbc->cipher].ecb_encrypt(cbc->IV, ct, &cbc->key)) != CRYPT_OK) { | |
69 | return err; | |
70 | } | |
71 | 71 | |
72 | /* store IV [ciphertext] for a future block */ | |
73 | #if defined(LTC_FAST) | |
74 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
75 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); | |
76 | } | |
77 | #else | |
78 | for (x = 0; x < cbc->blocklen; x++) { | |
79 | cbc->IV[x] = ct[x]; | |
80 | } | |
81 | #endif | |
72 | /* store IV [ciphertext] for a future block */ | |
73 | #if defined(LTC_FAST) | |
74 | for (x = 0; x < cbc->blocklen; x += sizeof(LTC_FAST_TYPE)) { | |
75 | *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)cbc->IV + x)) = *(LTC_FAST_TYPE_PTR_CAST((unsigned char *)ct + x)); | |
76 | } | |
77 | #else | |
78 | for (x = 0; x < cbc->blocklen; x++) { | |
79 | cbc->IV[x] = ct[x]; | |
80 | } | |
81 | #endif | |
82 | 82 | |
83 | ct += cbc->blocklen; | |
84 | pt += cbc->blocklen; | |
85 | len -= cbc->blocklen; | |
86 | } | |
83 | ct += cbc->blocklen; | |
84 | pt += cbc->blocklen; | |
85 | len -= cbc->blocklen; | |
87 | 86 | } |
88 | 87 | return CRYPT_OK; |
89 | 88 | } |
42 | 42 | /* copy data */ |
43 | 43 | cfb->cipher = cipher; |
44 | 44 | cfb->blocklen = cipher_descriptor[cipher].block_length; |
45 | for (x = 0; x < cfb->blocklen; x++) | |
45 | for (x = 0; x < cfb->blocklen; x++) { | |
46 | 46 | cfb->IV[x] = IV[x]; |
47 | } | |
47 | 48 | |
48 | 49 | /* init the cipher */ |
49 | 50 | if ((err = cipher_descriptor[cipher].setup(key, keylen, num_rounds, &cfb->key)) != CRYPT_OK) { |
38 | 38 | /* check for accel */ |
39 | 39 | if (cipher_descriptor[ecb->cipher].accel_ecb_decrypt != NULL) { |
40 | 40 | return cipher_descriptor[ecb->cipher].accel_ecb_decrypt(ct, pt, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); |
41 | } else { | |
42 | while (len) { | |
43 | if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { | |
44 | return err; | |
45 | } | |
46 | pt += cipher_descriptor[ecb->cipher].block_length; | |
47 | ct += cipher_descriptor[ecb->cipher].block_length; | |
48 | len -= cipher_descriptor[ecb->cipher].block_length; | |
41 | } | |
42 | while (len) { | |
43 | if ((err = cipher_descriptor[ecb->cipher].ecb_decrypt(ct, pt, &ecb->key)) != CRYPT_OK) { | |
44 | return err; | |
49 | 45 | } |
46 | pt += cipher_descriptor[ecb->cipher].block_length; | |
47 | ct += cipher_descriptor[ecb->cipher].block_length; | |
48 | len -= cipher_descriptor[ecb->cipher].block_length; | |
50 | 49 | } |
51 | 50 | return CRYPT_OK; |
52 | 51 | } |
38 | 38 | /* check for accel */ |
39 | 39 | if (cipher_descriptor[ecb->cipher].accel_ecb_encrypt != NULL) { |
40 | 40 | return cipher_descriptor[ecb->cipher].accel_ecb_encrypt(pt, ct, len / cipher_descriptor[ecb->cipher].block_length, &ecb->key); |
41 | } else { | |
42 | while (len) { | |
43 | if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { | |
44 | return err; | |
45 | } | |
46 | pt += cipher_descriptor[ecb->cipher].block_length; | |
47 | ct += cipher_descriptor[ecb->cipher].block_length; | |
48 | len -= cipher_descriptor[ecb->cipher].block_length; | |
41 | } | |
42 | while (len) { | |
43 | if ((err = cipher_descriptor[ecb->cipher].ecb_encrypt(pt, ct, &ecb->key)) != CRYPT_OK) { | |
44 | return err; | |
49 | 45 | } |
46 | pt += cipher_descriptor[ecb->cipher].block_length; | |
47 | ct += cipher_descriptor[ecb->cipher].block_length; | |
48 | len -= cipher_descriptor[ecb->cipher].block_length; | |
50 | 49 | } |
51 | 50 | return CRYPT_OK; |
52 | 51 | } |
40 | 40 | real_len &= 0x7F; |
41 | 41 | if (real_len == 0) { |
42 | 42 | return CRYPT_PK_ASN1_ERROR; |
43 | } else if (real_len > sizeof(decoded_len)) { | |
43 | } | |
44 | if (real_len > sizeof(decoded_len)) { | |
44 | 45 | return CRYPT_OVERFLOW; |
45 | } else if (real_len > (*inlen - 1)) { | |
46 | } | |
47 | if (real_len > (*inlen - 1)) { | |
46 | 48 | return CRYPT_BUFFER_OVERFLOW; |
47 | 49 | } |
48 | 50 | decoded_len = 0; |
40 | 40 | } |
41 | 41 | *outlen = 1; |
42 | 42 | return CRYPT_OK; |
43 | } else { | |
44 | if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) { | |
45 | return CRYPT_INVALID_ARG; | |
46 | } | |
47 | if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { | |
48 | return CRYPT_INVALID_ARG; | |
49 | } | |
50 | if (id->tag > (ULONG_MAX >> (8 + 7))) { | |
51 | return CRYPT_INVALID_ARG; | |
52 | } | |
43 | } | |
44 | if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) { | |
45 | return CRYPT_INVALID_ARG; | |
46 | } | |
47 | if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { | |
48 | return CRYPT_INVALID_ARG; | |
49 | } | |
50 | if (id->tag > (ULONG_MAX >> (8 + 7))) { | |
51 | return CRYPT_INVALID_ARG; | |
53 | 52 | } |
54 | 53 | |
55 | 54 | if (out != NULL) { |
111 | 111 | /* now is it Z or . */ |
112 | 112 | if (buf[x] == 'Z') { |
113 | 113 | return CRYPT_OK; |
114 | } else if (buf[x] == '.') { | |
114 | } | |
115 | if (buf[x] == '.') { | |
115 | 116 | x++; |
116 | 117 | while (buf[x] >= '0' && buf[x] <= '9') { |
117 | 118 | unsigned fs = out->fs; |
126 | 127 | /* now is it Z, +, - */ |
127 | 128 | if (buf[x] == 'Z') { |
128 | 129 | return CRYPT_OK; |
129 | } else if (buf[x] == '+' || buf[x] == '-') { | |
130 | } | |
131 | if (buf[x] == '+' || buf[x] == '-') { | |
130 | 132 | out->off_dir = (buf[x++] == '+') ? 0 : 1; |
131 | 133 | DECODE_V(out->off_hh, 24); |
132 | 134 | DECODE_V(out->off_mm, 60); |
133 | 135 | return CRYPT_OK; |
134 | } else { | |
135 | return CRYPT_INVALID_PACKET; | |
136 | 136 | } |
137 | return CRYPT_INVALID_PACKET; | |
137 | 138 | } |
138 | 139 | |
139 | 140 | #endif |
32 | 32 | if (r == 0) { |
33 | 33 | /* their order in the original list now determines the position */ |
34 | 34 | return A->used - B->used; |
35 | } else { | |
36 | return r; | |
37 | 35 | } |
36 | return r; | |
38 | 37 | } |
39 | 38 | |
40 | 39 | /* |
94 | 94 | /* now is it Z, +, - or 0-9 */ |
95 | 95 | if (buf[x] == 'Z') { |
96 | 96 | return CRYPT_OK; |
97 | } else if (buf[x] == '+' || buf[x] == '-') { | |
97 | } | |
98 | if (buf[x] == '+' || buf[x] == '-') { | |
98 | 99 | out->off_dir = (buf[x++] == '+') ? 0 : 1; |
99 | 100 | DECODE_V(out->off_hh, 24); |
100 | 101 | DECODE_V(out->off_mm, 60); |
107 | 108 | /* now is it Z, +, - */ |
108 | 109 | if (buf[x] == 'Z') { |
109 | 110 | return CRYPT_OK; |
110 | } else if (buf[x] == '+' || buf[x] == '-') { | |
111 | } | |
112 | if (buf[x] == '+' || buf[x] == '-') { | |
111 | 113 | out->off_dir = (buf[x++] == '+') ? 0 : 1; |
112 | 114 | DECODE_V(out->off_hh, 24); |
113 | 115 | DECODE_V(out->off_mm, 60); |
114 | 116 | return CRYPT_OK; |
115 | } else { | |
116 | return CRYPT_INVALID_PACKET; | |
117 | 117 | } |
118 | return CRYPT_INVALID_PACKET; | |
118 | 119 | } |
119 | 120 | |
120 | 121 | #endif |
22 | 22 | { |
23 | 23 | if (c <= 0x7F) { |
24 | 24 | return 1; |
25 | } else if (c <= 0x7FF) { | |
25 | } | |
26 | if (c <= 0x7FF) { | |
26 | 27 | return 2; |
28 | } | |
27 | 29 | #if LTC_WCHAR_MAX == 0xFFFF |
28 | } else { | |
30 | return 3; | |
31 | #else | |
32 | if (c <= 0xFFFF) { | |
29 | 33 | return 3; |
30 | 34 | } |
31 | #else | |
32 | } else if (c <= 0xFFFF) { | |
33 | return 3; | |
34 | } else { | |
35 | return 4; | |
36 | } | |
35 | return 4; | |
37 | 36 | #endif |
38 | 37 | } |
39 | 38 |
18 | 18 | if (groupsize <= 0) { |
19 | 19 | return 0; |
20 | 20 | } |
21 | else if (groupsize <= 192) { | |
21 | if (groupsize <= 192) { | |
22 | 22 | return 30; /* 1536-bit => key size 240-bit */ |
23 | 23 | } |
24 | else if (groupsize <= 256) { | |
24 | if (groupsize <= 256) { | |
25 | 25 | return 40; /* 2048-bit => key size 320-bit */ |
26 | 26 | } |
27 | else if (groupsize <= 384) { | |
27 | if (groupsize <= 384) { | |
28 | 28 | return 52; /* 3072-bit => key size 416-bit */ |
29 | 29 | } |
30 | else if (groupsize <= 512) { | |
30 | if (groupsize <= 512) { | |
31 | 31 | return 60; /* 4096-bit => key size 480-bit */ |
32 | 32 | } |
33 | else if (groupsize <= 768) { | |
33 | if (groupsize <= 768) { | |
34 | 34 | return 67; /* 6144-bit => key size 536-bit */ |
35 | 35 | } |
36 | else if (groupsize <= 1024) { | |
36 | if (groupsize <= 1024) { | |
37 | 37 | return 77; /* 8192-bit => key size 616-bit */ |
38 | 38 | } |
39 | else { | |
40 | return 0; | |
41 | } | |
39 | return 0; | |
42 | 40 | } |
43 | 41 | |
44 | 42 | int dh_generate_key(prng_state *prng, int wprng, dh_key *key) |
25 | 25 | int dsa_export(unsigned char *out, unsigned long *outlen, int type, const dsa_key *key) |
26 | 26 | { |
27 | 27 | unsigned long zero=0; |
28 | unsigned char flags[1]; | |
28 | 29 | int err, std; |
29 | 30 | |
30 | 31 | LTC_ARGCHK(out != NULL); |
34 | 35 | std = type & PK_STD; |
35 | 36 | type &= ~PK_STD; |
36 | 37 | |
37 | /* can we store the static header? */ | |
38 | 38 | if (type == PK_PRIVATE && key->type != PK_PRIVATE) { |
39 | 39 | return CRYPT_PK_TYPE_MISMATCH; |
40 | } | |
41 | ||
42 | if (type != PK_PUBLIC && type != PK_PRIVATE) { | |
43 | return CRYPT_INVALID_ARG; | |
44 | 40 | } |
45 | 41 | |
46 | 42 | if (type == PK_PRIVATE) { |
54 | 50 | LTC_ASN1_INTEGER, 1UL, key->x, |
55 | 51 | LTC_ASN1_EOL, 0UL, NULL); |
56 | 52 | } |
57 | else { | |
58 | unsigned char flags[1]; | |
59 | flags[0] = 1; | |
60 | return der_encode_sequence_multi(out, outlen, | |
53 | flags[0] = 1; | |
54 | return der_encode_sequence_multi(out, outlen, | |
61 | 55 | LTC_ASN1_BIT_STRING, 1UL, flags, |
62 | 56 | LTC_ASN1_INTEGER, 1UL, key->g, |
63 | 57 | LTC_ASN1_INTEGER, 1UL, key->p, |
65 | 59 | LTC_ASN1_INTEGER, 1UL, key->y, |
66 | 60 | LTC_ASN1_INTEGER, 1UL, key->x, |
67 | 61 | LTC_ASN1_EOL, 0UL, NULL); |
68 | } | |
69 | } else { | |
62 | } | |
63 | ||
64 | if (type == PK_PUBLIC) { | |
70 | 65 | if (std) { |
71 | 66 | unsigned long tmplen = (unsigned long)(mp_count_bits(key->y) / 8) + 8; |
72 | 67 | unsigned char* tmp = XMALLOC(tmplen); |
93 | 88 | XFREE(tmp); |
94 | 89 | return err; |
95 | 90 | } |
96 | else { | |
97 | unsigned char flags[1]; | |
98 | flags[0] = 0; | |
99 | return der_encode_sequence_multi(out, outlen, | |
91 | flags[0] = 0; | |
92 | return der_encode_sequence_multi(out, outlen, | |
100 | 93 | LTC_ASN1_BIT_STRING, 1UL, flags, |
101 | 94 | LTC_ASN1_INTEGER, 1UL, key->g, |
102 | 95 | LTC_ASN1_INTEGER, 1UL, key->p, |
103 | 96 | LTC_ASN1_INTEGER, 1UL, key->q, |
104 | 97 | LTC_ASN1_INTEGER, 1UL, key->y, |
105 | 98 | LTC_ASN1_EOL, 0UL, NULL); |
106 | } | |
107 | 99 | } |
100 | ||
101 | return CRYPT_INVALID_ARG; | |
108 | 102 | } |
109 | 103 | |
110 | 104 | #endif |
40 | 40 | /* initialize key->dp */ |
41 | 41 | if (cu == NULL) { |
42 | 42 | /* this case works only for uncompressed public keys */ |
43 | if ((err = ecc_set_dp_by_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } | |
43 | if ((err = ecc_set_curve_by_size((inlen-1)>>1, key)) != CRYPT_OK) { return err; } | |
44 | 44 | } |
45 | 45 | else { |
46 | 46 | /* this one works for both compressed / uncompressed pubkeys */ |
47 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } | |
47 | if ((err = ecc_set_curve(cu, key)) != CRYPT_OK) { return err; } | |
48 | 48 | } |
49 | 49 | |
50 | 50 | /* load public key */ |
84 | 84 | } |
85 | 85 | |
86 | 86 | /* import ECC key from packet */ |
87 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } | |
87 | if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } | |
88 | 88 | if ((err = ecc_set_key(decode[1].data, decode[1].size, PK_PUBLIC, &pubkey)) != CRYPT_OK) { goto LBL_ERR; } |
89 | 89 | |
90 | 90 | /* make shared key */ |
51 | 51 | } |
52 | 52 | |
53 | 53 | /* make a random key and export the public copy */ |
54 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { return err; } | |
54 | if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { return err; } | |
55 | 55 | if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { return err; } |
56 | 56 | |
57 | 57 | pub_expt = XMALLOC(ECC_BUF_SIZE); |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | static const struct { | |
14 | const char *OID; | |
15 | const char *names[6]; | |
16 | } _curve_names[] = { | |
17 | #ifdef LTC_ECC_SECP112R1 | |
18 | { | |
19 | "1.3.132.0.6", { "SECP112R1", "ECC-112", NULL } | |
20 | }, | |
21 | #endif | |
22 | #ifdef LTC_ECC_SECP112R2 | |
23 | { | |
24 | "1.3.132.0.7", { "SECP112R2", NULL } | |
25 | }, | |
26 | #endif | |
27 | #ifdef LTC_ECC_SECP128R1 | |
28 | { | |
29 | "1.3.132.0.28", { "SECP128R1", "ECC-128", NULL } | |
30 | }, | |
31 | #endif | |
32 | #ifdef LTC_ECC_SECP128R2 | |
33 | { | |
34 | "1.3.132.0.29", { "SECP128R2", NULL } | |
35 | }, | |
36 | #endif | |
37 | #ifdef LTC_ECC_SECP160R1 | |
38 | { | |
39 | "1.3.132.0.8", { "SECP160R1", "ECC-160", NULL } | |
40 | }, | |
41 | #endif | |
42 | #ifdef LTC_ECC_SECP160R2 | |
43 | { | |
44 | "1.3.132.0.30", { "SECP160R2", NULL } | |
45 | }, | |
46 | #endif | |
47 | #ifdef LTC_ECC_SECP160K1 | |
48 | { | |
49 | "1.3.132.0.9", { "SECP160K1", NULL } | |
50 | }, | |
51 | #endif | |
52 | #ifdef LTC_ECC_SECP192R1 | |
53 | { | |
54 | "1.2.840.10045.3.1.1", { "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", NULL } | |
55 | }, | |
56 | #endif | |
57 | #ifdef LTC_ECC_PRIME192V2 | |
58 | { | |
59 | "1.2.840.10045.3.1.2", { "PRIME192V2", NULL } | |
60 | }, | |
61 | #endif | |
62 | #ifdef LTC_ECC_PRIME192V3 | |
63 | { | |
64 | "1.2.840.10045.3.1.3", { "PRIME192V3", NULL } | |
65 | }, | |
66 | #endif | |
67 | #ifdef LTC_ECC_SECP192K1 | |
68 | { | |
69 | "1.3.132.0.31", { "SECP192K1", NULL } | |
70 | }, | |
71 | #endif | |
72 | #ifdef LTC_ECC_SECP224R1 | |
73 | { | |
74 | "1.3.132.0.33", { "SECP224R1", "NISTP224", "ECC-224", "P-224", NULL } | |
75 | }, | |
76 | #endif | |
77 | #ifdef LTC_ECC_SECP224K1 | |
78 | { | |
79 | "1.3.132.0.32", { "SECP224K1", NULL } | |
80 | }, | |
81 | #endif | |
82 | #ifdef LTC_ECC_SECP256R1 | |
83 | { | |
84 | "1.2.840.10045.3.1.7", { "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", NULL } | |
85 | }, | |
86 | #endif | |
87 | #ifdef LTC_ECC_SECP256K1 | |
88 | { | |
89 | "1.3.132.0.10", { "SECP256K1", NULL } | |
90 | }, | |
91 | #endif | |
92 | #ifdef LTC_ECC_SECP384R1 | |
93 | { | |
94 | "1.3.132.0.34", { "SECP384R1", "NISTP384", "ECC-384", "P-384", NULL } | |
95 | }, | |
96 | #endif | |
97 | #ifdef LTC_ECC_SECP521R1 | |
98 | { | |
99 | "1.3.132.0.35", { "SECP521R1", "NISTP521", "ECC-521", "P-521", NULL } | |
100 | }, | |
101 | #endif | |
102 | #ifdef LTC_ECC_PRIME239V1 | |
103 | { | |
104 | "1.2.840.10045.3.1.4", { "PRIME239V1", NULL } | |
105 | }, | |
106 | #endif | |
107 | #ifdef LTC_ECC_PRIME239V2 | |
108 | { | |
109 | "1.2.840.10045.3.1.5", { "PRIME239V2", NULL } | |
110 | }, | |
111 | #endif | |
112 | #ifdef LTC_ECC_PRIME239V3 | |
113 | { | |
114 | "1.2.840.10045.3.1.6", { "PRIME239V3", NULL } | |
115 | }, | |
116 | #endif | |
117 | #ifdef LTC_ECC_BRAINPOOLP160R1 | |
118 | { | |
119 | "1.3.36.3.3.2.8.1.1.1", { "BRAINPOOLP160R1", NULL } | |
120 | }, | |
121 | #endif | |
122 | #ifdef LTC_ECC_BRAINPOOLP192R1 | |
123 | { | |
124 | "1.3.36.3.3.2.8.1.1.3", { "BRAINPOOLP192R1", NULL } | |
125 | }, | |
126 | #endif | |
127 | #ifdef LTC_ECC_BRAINPOOLP224R1 | |
128 | { | |
129 | "1.3.36.3.3.2.8.1.1.5", { "BRAINPOOLP224R1", NULL } | |
130 | }, | |
131 | #endif | |
132 | #ifdef LTC_ECC_BRAINPOOLP256R1 | |
133 | { | |
134 | "1.3.36.3.3.2.8.1.1.7", { "BRAINPOOLP256R1", NULL } | |
135 | }, | |
136 | #endif | |
137 | #ifdef LTC_ECC_BRAINPOOLP320R1 | |
138 | { | |
139 | "1.3.36.3.3.2.8.1.1.9", { "BRAINPOOLP320R1", NULL } | |
140 | }, | |
141 | #endif | |
142 | #ifdef LTC_ECC_BRAINPOOLP384R1 | |
143 | { | |
144 | "1.3.36.3.3.2.8.1.1.11", { "BRAINPOOLP384R1", NULL } | |
145 | }, | |
146 | #endif | |
147 | #ifdef LTC_ECC_BRAINPOOLP512R1 | |
148 | { | |
149 | "1.3.36.3.3.2.8.1.1.13", { "BRAINPOOLP512R1", NULL } | |
150 | }, | |
151 | #endif | |
152 | #ifdef LTC_ECC_BRAINPOOLP160T1 | |
153 | { | |
154 | "1.3.36.3.3.2.8.1.1.2", { "BRAINPOOLP160T1", NULL } | |
155 | }, | |
156 | #endif | |
157 | #ifdef LTC_ECC_BRAINPOOLP192T1 | |
158 | { | |
159 | "1.3.36.3.3.2.8.1.1.4", { "BRAINPOOLP192T1", NULL } | |
160 | }, | |
161 | #endif | |
162 | #ifdef LTC_ECC_BRAINPOOLP224T1 | |
163 | { | |
164 | "1.3.36.3.3.2.8.1.1.6", { "BRAINPOOLP224T1", NULL } | |
165 | }, | |
166 | #endif | |
167 | #ifdef LTC_ECC_BRAINPOOLP256T1 | |
168 | { | |
169 | "1.3.36.3.3.2.8.1.1.8", { "BRAINPOOLP256T1", NULL } | |
170 | }, | |
171 | #endif | |
172 | #ifdef LTC_ECC_BRAINPOOLP320T1 | |
173 | { | |
174 | "1.3.36.3.3.2.8.1.1.10", { "BRAINPOOLP320T1", NULL } | |
175 | }, | |
176 | #endif | |
177 | #ifdef LTC_ECC_BRAINPOOLP384T1 | |
178 | { | |
179 | "1.3.36.3.3.2.8.1.1.12", { "BRAINPOOLP384T1", NULL } | |
180 | }, | |
181 | #endif | |
182 | #ifdef LTC_ECC_BRAINPOOLP512T1 | |
183 | { | |
184 | "1.3.36.3.3.2.8.1.1.14", { "BRAINPOOLP512T1", NULL } | |
185 | }, | |
186 | #endif | |
187 | { | |
188 | NULL, { NULL } | |
189 | } | |
190 | }; | |
191 | ||
192 | /* case-insensitive match + ignore '-', '_', ' ' */ | |
193 | static int _name_match(const char *left, const char *right) | |
194 | { | |
195 | char lc_r, lc_l; | |
196 | ||
197 | while ((*left != '\0') && (*right != '\0')) { | |
198 | while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; | |
199 | while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; | |
200 | if (*left == '\0' || *right == '\0') break; | |
201 | lc_r = *right; | |
202 | lc_l = *left; | |
203 | if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; | |
204 | if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; | |
205 | if (lc_l != lc_r) return 0; | |
206 | left++; | |
207 | right++; | |
208 | } | |
209 | ||
210 | if ((*left == '\0') && (*right == '\0')) return 1; | |
211 | return 0; | |
212 | } | |
213 | ||
214 | int ecc_find_curve(const char *name_or_oid, const ltc_ecc_curve **cu) | |
215 | { | |
216 | int i, j; | |
217 | const char *OID = NULL; | |
218 | ||
219 | LTC_ARGCHK(cu != NULL); | |
220 | LTC_ARGCHK(name_or_oid != NULL); | |
221 | ||
222 | *cu = NULL; | |
223 | ||
224 | for (i = 0; _curve_names[i].OID != NULL && !OID; i++) { | |
225 | if (XSTRCMP(_curve_names[i].OID, name_or_oid) == 0) { | |
226 | OID = _curve_names[i].OID; | |
227 | } | |
228 | for (j = 0; _curve_names[i].names[j] != NULL && !OID; j++) { | |
229 | if (_name_match(_curve_names[i].names[j], name_or_oid)) { | |
230 | OID = _curve_names[i].OID; | |
231 | } | |
232 | } | |
233 | } | |
234 | ||
235 | if (OID != NULL) { | |
236 | for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { | |
237 | if (XSTRCMP(ltc_ecc_curves[i].OID, OID) == 0) { | |
238 | *cu = <c_ecc_curves[i]; | |
239 | return CRYPT_OK; | |
240 | } | |
241 | } | |
242 | } | |
243 | ||
244 | return CRYPT_INVALID_ARG; /* not found */ | |
245 | } | |
246 | ||
247 | #endif | |
248 | ||
249 | /* ref: $Format:%D$ */ | |
250 | /* git commit: $Format:%H$ */ | |
251 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | static const struct { | |
14 | const char *OID; | |
15 | const char *names[6]; | |
16 | } _curve_names[] = { | |
17 | #ifdef LTC_ECC_SECP112R1 | |
18 | { | |
19 | "1.3.132.0.6", { "SECP112R1", "ECC-112", NULL } | |
20 | }, | |
21 | #endif | |
22 | #ifdef LTC_ECC_SECP112R2 | |
23 | { | |
24 | "1.3.132.0.7", { "SECP112R2", NULL } | |
25 | }, | |
26 | #endif | |
27 | #ifdef LTC_ECC_SECP128R1 | |
28 | { | |
29 | "1.3.132.0.28", { "SECP128R1", "ECC-128", NULL } | |
30 | }, | |
31 | #endif | |
32 | #ifdef LTC_ECC_SECP128R2 | |
33 | { | |
34 | "1.3.132.0.29", { "SECP128R2", NULL } | |
35 | }, | |
36 | #endif | |
37 | #ifdef LTC_ECC_SECP160R1 | |
38 | { | |
39 | "1.3.132.0.8", { "SECP160R1", "ECC-160", NULL } | |
40 | }, | |
41 | #endif | |
42 | #ifdef LTC_ECC_SECP160R2 | |
43 | { | |
44 | "1.3.132.0.30", { "SECP160R2", NULL } | |
45 | }, | |
46 | #endif | |
47 | #ifdef LTC_ECC_SECP160K1 | |
48 | { | |
49 | "1.3.132.0.9", { "SECP160K1", NULL } | |
50 | }, | |
51 | #endif | |
52 | #ifdef LTC_ECC_SECP192R1 | |
53 | { | |
54 | "1.2.840.10045.3.1.1", { "SECP192R1", "NISTP192", "PRIME192V1", "ECC-192", "P-192", NULL } | |
55 | }, | |
56 | #endif | |
57 | #ifdef LTC_ECC_PRIME192V2 | |
58 | { | |
59 | "1.2.840.10045.3.1.2", { "PRIME192V2", NULL } | |
60 | }, | |
61 | #endif | |
62 | #ifdef LTC_ECC_PRIME192V3 | |
63 | { | |
64 | "1.2.840.10045.3.1.3", { "PRIME192V3", NULL } | |
65 | }, | |
66 | #endif | |
67 | #ifdef LTC_ECC_SECP192K1 | |
68 | { | |
69 | "1.3.132.0.31", { "SECP192K1", NULL } | |
70 | }, | |
71 | #endif | |
72 | #ifdef LTC_ECC_SECP224R1 | |
73 | { | |
74 | "1.3.132.0.33", { "SECP224R1", "NISTP224", "ECC-224", "P-224", NULL } | |
75 | }, | |
76 | #endif | |
77 | #ifdef LTC_ECC_SECP224K1 | |
78 | { | |
79 | "1.3.132.0.32", { "SECP224K1", NULL } | |
80 | }, | |
81 | #endif | |
82 | #ifdef LTC_ECC_SECP256R1 | |
83 | { | |
84 | "1.2.840.10045.3.1.7", { "SECP256R1", "NISTP256", "PRIME256V1", "ECC-256", "P-256", NULL } | |
85 | }, | |
86 | #endif | |
87 | #ifdef LTC_ECC_SECP256K1 | |
88 | { | |
89 | "1.3.132.0.10", { "SECP256K1", NULL } | |
90 | }, | |
91 | #endif | |
92 | #ifdef LTC_ECC_SECP384R1 | |
93 | { | |
94 | "1.3.132.0.34", { "SECP384R1", "NISTP384", "ECC-384", "P-384", NULL } | |
95 | }, | |
96 | #endif | |
97 | #ifdef LTC_ECC_SECP521R1 | |
98 | { | |
99 | "1.3.132.0.35", { "SECP521R1", "NISTP521", "ECC-521", "P-521", NULL } | |
100 | }, | |
101 | #endif | |
102 | #ifdef LTC_ECC_PRIME239V1 | |
103 | { | |
104 | "1.2.840.10045.3.1.4", { "PRIME239V1", NULL } | |
105 | }, | |
106 | #endif | |
107 | #ifdef LTC_ECC_PRIME239V2 | |
108 | { | |
109 | "1.2.840.10045.3.1.5", { "PRIME239V2", NULL } | |
110 | }, | |
111 | #endif | |
112 | #ifdef LTC_ECC_PRIME239V3 | |
113 | { | |
114 | "1.2.840.10045.3.1.6", { "PRIME239V3", NULL } | |
115 | }, | |
116 | #endif | |
117 | #ifdef LTC_ECC_BRAINPOOLP160R1 | |
118 | { | |
119 | "1.3.36.3.3.2.8.1.1.1", { "BRAINPOOLP160R1", NULL } | |
120 | }, | |
121 | #endif | |
122 | #ifdef LTC_ECC_BRAINPOOLP192R1 | |
123 | { | |
124 | "1.3.36.3.3.2.8.1.1.3", { "BRAINPOOLP192R1", NULL } | |
125 | }, | |
126 | #endif | |
127 | #ifdef LTC_ECC_BRAINPOOLP224R1 | |
128 | { | |
129 | "1.3.36.3.3.2.8.1.1.5", { "BRAINPOOLP224R1", NULL } | |
130 | }, | |
131 | #endif | |
132 | #ifdef LTC_ECC_BRAINPOOLP256R1 | |
133 | { | |
134 | "1.3.36.3.3.2.8.1.1.7", { "BRAINPOOLP256R1", NULL } | |
135 | }, | |
136 | #endif | |
137 | #ifdef LTC_ECC_BRAINPOOLP320R1 | |
138 | { | |
139 | "1.3.36.3.3.2.8.1.1.9", { "BRAINPOOLP320R1", NULL } | |
140 | }, | |
141 | #endif | |
142 | #ifdef LTC_ECC_BRAINPOOLP384R1 | |
143 | { | |
144 | "1.3.36.3.3.2.8.1.1.11", { "BRAINPOOLP384R1", NULL } | |
145 | }, | |
146 | #endif | |
147 | #ifdef LTC_ECC_BRAINPOOLP512R1 | |
148 | { | |
149 | "1.3.36.3.3.2.8.1.1.13", { "BRAINPOOLP512R1", NULL } | |
150 | }, | |
151 | #endif | |
152 | #ifdef LTC_ECC_BRAINPOOLP160T1 | |
153 | { | |
154 | "1.3.36.3.3.2.8.1.1.2", { "BRAINPOOLP160T1", NULL } | |
155 | }, | |
156 | #endif | |
157 | #ifdef LTC_ECC_BRAINPOOLP192T1 | |
158 | { | |
159 | "1.3.36.3.3.2.8.1.1.4", { "BRAINPOOLP192T1", NULL } | |
160 | }, | |
161 | #endif | |
162 | #ifdef LTC_ECC_BRAINPOOLP224T1 | |
163 | { | |
164 | "1.3.36.3.3.2.8.1.1.6", { "BRAINPOOLP224T1", NULL } | |
165 | }, | |
166 | #endif | |
167 | #ifdef LTC_ECC_BRAINPOOLP256T1 | |
168 | { | |
169 | "1.3.36.3.3.2.8.1.1.8", { "BRAINPOOLP256T1", NULL } | |
170 | }, | |
171 | #endif | |
172 | #ifdef LTC_ECC_BRAINPOOLP320T1 | |
173 | { | |
174 | "1.3.36.3.3.2.8.1.1.10", { "BRAINPOOLP320T1", NULL } | |
175 | }, | |
176 | #endif | |
177 | #ifdef LTC_ECC_BRAINPOOLP384T1 | |
178 | { | |
179 | "1.3.36.3.3.2.8.1.1.12", { "BRAINPOOLP384T1", NULL } | |
180 | }, | |
181 | #endif | |
182 | #ifdef LTC_ECC_BRAINPOOLP512T1 | |
183 | { | |
184 | "1.3.36.3.3.2.8.1.1.14", { "BRAINPOOLP512T1", NULL } | |
185 | }, | |
186 | #endif | |
187 | { | |
188 | NULL, { NULL } | |
189 | } | |
190 | }; | |
191 | ||
192 | /* case-insensitive match + ignore '-', '_', ' ' */ | |
193 | static int _name_match(const char *left, const char *right) | |
194 | { | |
195 | char lc_r, lc_l; | |
196 | ||
197 | while ((*left != '\0') && (*right != '\0')) { | |
198 | while ((*left == ' ') || (*left == '-') || (*left == '_')) left++; | |
199 | while ((*right == ' ') || (*right == '-') || (*right == '_')) right++; | |
200 | if (*left == '\0' || *right == '\0') break; | |
201 | lc_r = *right; | |
202 | lc_l = *left; | |
203 | if ((lc_r >= 'A') && (lc_r <= 'Z')) lc_r += 32; | |
204 | if ((lc_l >= 'A') && (lc_l <= 'Z')) lc_l += 32; | |
205 | if (lc_l != lc_r) return 0; | |
206 | left++; | |
207 | right++; | |
208 | } | |
209 | ||
210 | if ((*left == '\0') && (*right == '\0')) | |
211 | return 1; | |
212 | else | |
213 | return 0; | |
214 | } | |
215 | ||
216 | int ecc_get_curve(const char *name_or_oid, const ltc_ecc_curve **cu) | |
217 | { | |
218 | int i, j; | |
219 | const char *OID = NULL; | |
220 | ||
221 | LTC_ARGCHK(cu != NULL); | |
222 | LTC_ARGCHK(name_or_oid != NULL); | |
223 | ||
224 | *cu = NULL; | |
225 | ||
226 | for (i = 0; _curve_names[i].OID != NULL && !OID; i++) { | |
227 | if (XSTRCMP(_curve_names[i].OID, name_or_oid) == 0) { | |
228 | OID = _curve_names[i].OID; | |
229 | } | |
230 | for (j = 0; _curve_names[i].names[j] != NULL && !OID; j++) { | |
231 | if (_name_match(_curve_names[i].names[j], name_or_oid)) { | |
232 | OID = _curve_names[i].OID; | |
233 | } | |
234 | } | |
235 | } | |
236 | ||
237 | if (OID != NULL) { | |
238 | for (i = 0; ltc_ecc_curves[i].prime != NULL; i++) { | |
239 | if (XSTRCMP(ltc_ecc_curves[i].OID, OID) == 0) { | |
240 | *cu = <c_ecc_curves[i]; | |
241 | return CRYPT_OK; | |
242 | } | |
243 | } | |
244 | } | |
245 | ||
246 | return CRYPT_INVALID_ARG; /* not found */ | |
247 | } | |
248 | ||
249 | #endif | |
250 | ||
251 | /* ref: $Format:%D$ */ | |
252 | /* git commit: $Format:%H$ */ | |
253 | /* commit time: $Format:%ai$ */ |
55 | 55 | |
56 | 56 | /* allocate & initialize the key */ |
57 | 57 | if (cu == NULL) { |
58 | if ((err = ecc_set_dp_by_size(key_size, key)) != CRYPT_OK) { goto done; } | |
58 | if ((err = ecc_set_curve_by_size(key_size, key)) != CRYPT_OK) { goto done; } | |
59 | 59 | } else { |
60 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { goto done; } | |
60 | if ((err = ecc_set_curve(cu, key)) != CRYPT_OK) { goto done; } | |
61 | 61 | } |
62 | 62 | |
63 | 63 | if (flags[0] == 1) { |
35 | 35 | /* load curve parameters for given curve OID */ |
36 | 36 | len = sizeof(OID); |
37 | 37 | if ((err = pk_oid_num_to_str(curveoid, custom[0].size, OID, &len)) != CRYPT_OK) { goto error; } |
38 | if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto error; } | |
39 | if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto error; } | |
38 | if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; } | |
39 | if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; } | |
40 | 40 | /* load private+public key */ |
41 | 41 | err = ecc_set_key(bin_k, seq_priv[1].size, PK_PRIVATE, key); |
42 | 42 | } |
95 | 95 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } |
96 | 96 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } |
97 | 97 | /* load curve parameters */ |
98 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
98 | if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
99 | 99 | /* load private+public key */ |
100 | 100 | err = ecc_set_key(bin_k, len_k, PK_PRIVATE, key); |
101 | 101 | } |
53 | 53 | { { 0 }, 0 }, |
54 | 54 | }; |
55 | 55 | |
56 | static int _simple_utf8_to_utf16(const unsigned char *in, unsigned long inlen, | |
57 | unsigned char *out, unsigned long *outlen) { | |
58 | unsigned long len = 0; | |
59 | const unsigned char* in_end = in + inlen; | |
60 | const ulong32 offset[6] = { | |
61 | 0x00000000UL, 0x00003080UL, 0x000E2080UL, | |
62 | 0x03C82080UL, 0xFA082080UL, 0x82082080UL | |
63 | }; | |
64 | int err = CRYPT_ERROR; | |
65 | ||
66 | while (in < in_end) { | |
67 | ulong32 ch = 0; | |
68 | unsigned short extra = 0; /* 0 */ | |
69 | if (*in >= 192) extra++; /* 1 */ | |
70 | if (*in >= 224) extra++; /* 2 */ | |
71 | if (*in >= 240) extra++; /* 3 */ | |
72 | if (*in >= 248) extra++; /* 4 */ | |
73 | if (*in >= 252) extra++; /* 5 */ | |
74 | if (in + extra >= in_end) goto ERROR; | |
75 | switch (extra) { | |
76 | case 5: ch += *in++; ch <<= 6; | |
77 | /* FALLTHROUGH */ | |
78 | case 4: ch += *in++; ch <<= 6; | |
79 | /* FALLTHROUGH */ | |
80 | case 3: ch += *in++; ch <<= 6; | |
81 | /* FALLTHROUGH */ | |
82 | case 2: ch += *in++; ch <<= 6; | |
83 | /* FALLTHROUGH */ | |
84 | case 1: ch += *in++; ch <<= 6; | |
85 | /* FALLTHROUGH */ | |
86 | case 0: ch += *in++; | |
87 | } | |
88 | ch -= offset[extra]; | |
89 | if (ch > 0xFFFF) goto ERROR; | |
90 | if (*outlen >= len + 2) { | |
91 | out[len] = (unsigned short)((ch >> 8) & 0xFF); | |
92 | out[len + 1] = (unsigned char)(ch & 0xFF); | |
93 | } | |
94 | len += 2; | |
95 | } | |
96 | ||
97 | err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK; | |
98 | *outlen = len; | |
99 | ERROR: | |
100 | return err; | |
101 | } | |
102 | ||
103 | static int _kdf_pkcs12(int hash_id, const unsigned char *pw, unsigned long pwlen, | |
104 | const unsigned char *salt, unsigned long saltlen, | |
105 | unsigned int iterations, unsigned char purpose, | |
106 | unsigned char *out, unsigned long outlen) | |
107 | { | |
108 | unsigned long u = hash_descriptor[hash_id].hashsize; | |
109 | unsigned long v = hash_descriptor[hash_id].blocksize; | |
110 | unsigned long c = (outlen + u - 1) / u; | |
111 | unsigned long Slen = ((saltlen + v - 1) / v) * v; | |
112 | unsigned long Plen = ((pwlen + v - 1) / v) * v; | |
113 | unsigned long k = (Plen + Slen) / v; | |
114 | unsigned long Alen, keylen = 0; | |
115 | unsigned int tmp, i, j, n; | |
116 | unsigned char ch; | |
117 | unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE]; | |
118 | unsigned char *I = NULL, *key = NULL; | |
119 | int err = CRYPT_ERROR; | |
120 | ||
121 | key = XMALLOC(u * c); | |
122 | I = XMALLOC(Plen + Slen); | |
123 | if (key == NULL || I == NULL) goto DONE; | |
124 | zeromem(key, u * c); | |
125 | ||
126 | for (i = 0; i < v; i++) D[i] = purpose; /* D - diversifier */ | |
127 | for (i = 0; i < Slen; i++) I[i] = salt[i % saltlen]; | |
128 | for (i = 0; i < Plen; i++) I[Slen + i] = pw[i % pwlen]; /* I = Salt || Pass */ | |
129 | ||
130 | for (i = 0; i < c; i++) { | |
131 | Alen = u; /* hash size */ | |
132 | err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */ | |
133 | if (err != CRYPT_OK) goto DONE; | |
134 | for (j = 1; j < iterations; j++) { | |
135 | err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */ | |
136 | if (err != CRYPT_OK) goto DONE; | |
137 | } | |
138 | /* fill buffer B with A */ | |
139 | for (j = 0; j < v; j++) B[j] = A[j % Alen]; | |
140 | /* B += 1 */ | |
141 | for (j = v; j > 0; j--) { | |
142 | if (++B[j - 1] != 0) break; | |
143 | } | |
144 | /* I_n += B */ | |
145 | for (n = 0; n < k; n++) { | |
146 | ch = 0; | |
147 | for (j = v; j > 0; j--) { | |
148 | tmp = I[n * v + j - 1] + B[j - 1] + ch; | |
149 | ch = (unsigned char)((tmp >> 8) & 0xFF); | |
150 | I[n * v + j - 1] = (unsigned char)(tmp & 0xFF); | |
151 | } | |
152 | } | |
153 | /* store derived key block */ | |
154 | for (j = 0; j < Alen; j++) key[keylen++] = A[j]; | |
155 | } | |
156 | ||
157 | for (i = 0; i < outlen; i++) out[i] = key[i]; | |
158 | err = CRYPT_OK; | |
159 | DONE: | |
160 | if (I) XFREE(I); | |
161 | if (key) XFREE(key); | |
162 | return err; | |
163 | } | |
164 | ||
165 | 56 | static int _oid_to_id(const unsigned long *oid, unsigned long oid_size) |
166 | 57 | { |
167 | 58 | int i, j; |
215 | 106 | pwlen = pass_size * 2; |
216 | 107 | pw = XMALLOC(pwlen + 2); |
217 | 108 | if (pw == NULL) goto LBL_ERROR; |
218 | if ((err = _simple_utf8_to_utf16(pass, pass_size, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR; | |
109 | if ((err = pkcs12_utf8_to_utf16(pass, pass_size, pw, &pwlen) != CRYPT_OK)) goto LBL_ERROR; | |
219 | 110 | pw[pwlen++] = 0; |
220 | 111 | pw[pwlen++] = 0; |
221 | 112 | /* derive KEY */ |
222 | if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 1, key_iv, keylen)) != CRYPT_OK) goto LBL_ERROR; | |
113 | if ((err = pkcs12_kdf(hid, pw, pwlen, salt, salt_size, iterations, 1, key_iv, keylen)) != CRYPT_OK) goto LBL_ERROR; | |
223 | 114 | /* derive IV */ |
224 | if ((err = _kdf_pkcs12(hid, pw, pwlen, salt, salt_size, iterations, 2, key_iv+24, blklen)) != CRYPT_OK) goto LBL_ERROR; | |
115 | if ((err = pkcs12_kdf(hid, pw, pwlen, salt, salt_size, iterations, 2, key_iv+24, blklen)) != CRYPT_OK) goto LBL_ERROR; | |
225 | 116 | } |
226 | 117 | else { |
227 | 118 | if ((err = pkcs_5_alg1(pass, pass_size, salt, iterations, hid, key_iv, &len)) != CRYPT_OK) goto LBL_ERROR; |
514 | 405 | ltc_asn1_list *loid = lseq->child->next; |
515 | 406 | len = sizeof(OID); |
516 | 407 | if ((err = pk_oid_num_to_str(loid->data, loid->size, OID, &len)) != CRYPT_OK) { goto LBL_DONE; } |
517 | if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto LBL_DONE; } | |
518 | if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto LBL_DONE; } | |
408 | if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto LBL_DONE; } | |
409 | if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto LBL_DONE; } | |
519 | 410 | } |
520 | 411 | else if (LTC_ASN1_IS_TYPE(lseq->child->next, LTC_ASN1_SEQUENCE)) { |
521 | 412 | /* CASE 2: explicit curve parameters (AKA long variant): |
566 | 457 | if ((err = ltc_ecc_import_point(lg->data, lg->size, lprime->data, a, b, gx, gy)) != CRYPT_OK) { |
567 | 458 | goto LBL_DONE; |
568 | 459 | } |
569 | if ((err = ecc_set_dp_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { | |
460 | if ((err = ecc_set_curve_from_mpis(a, b, lprime->data, lorder->data, gx, gy, cofactor, key)) != CRYPT_OK) { | |
570 | 461 | goto LBL_DONE; |
571 | 462 | } |
572 | 463 | } |
26 | 26 | /* load curve parameters for given curve OID */ |
27 | 27 | len = sizeof(OID); |
28 | 28 | if ((err = pk_oid_num_to_str(curveoid, len_oid, OID, &len)) != CRYPT_OK) { goto error; } |
29 | if ((err = ecc_get_curve(OID, &curve)) != CRYPT_OK) { goto error; } | |
30 | if ((err = ecc_set_dp(curve, key)) != CRYPT_OK) { goto error; } | |
29 | if ((err = ecc_find_curve(OID, &curve)) != CRYPT_OK) { goto error; } | |
30 | if ((err = ecc_set_curve(curve, key)) != CRYPT_OK) { goto error; } | |
31 | 31 | /* load public key */ |
32 | 32 | err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key); |
33 | 33 | } |
79 | 79 | if ((err = mp_read_unsigned_bin(b, bin_b, len_b)) != CRYPT_OK) { goto error; } |
80 | 80 | if ((err = ltc_ecc_import_point(bin_g, len_g, prime, a, b, gx, gy)) != CRYPT_OK) { goto error; } |
81 | 81 | /* load curve parameters */ |
82 | if ((err = ecc_set_dp_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
82 | if ((err = ecc_set_curve_from_mpis(a, b, prime, order, gx, gy, cofactor, key)) != CRYPT_OK) { goto error; } | |
83 | 83 | /* load public key */ |
84 | 84 | err = ecc_set_key(bin_xy, len_xy, PK_PUBLIC, key); |
85 | 85 | } |
27 | 27 | { |
28 | 28 | int err; |
29 | 29 | |
30 | if ((err = ecc_set_dp_by_size(keysize, key)) != CRYPT_OK) { return err; } | |
31 | if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } | |
30 | if ((err = ecc_set_curve_by_size(keysize, key)) != CRYPT_OK) { return err; } | |
31 | if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } | |
32 | 32 | return CRYPT_OK; |
33 | 33 | } |
34 | 34 | |
35 | 35 | int ecc_make_key_ex(prng_state *prng, int wprng, ecc_key *key, const ltc_ecc_curve *cu) |
36 | 36 | { |
37 | 37 | int err; |
38 | if ((err = ecc_set_dp(cu, key)) != CRYPT_OK) { return err; } | |
38 | if ((err = ecc_set_curve(cu, key)) != CRYPT_OK) { return err; } | |
39 | 39 | if ((err = ecc_generate_key(prng, wprng, key)) != CRYPT_OK) { return err; } |
40 | 40 | return CRYPT_OK; |
41 | 41 | } |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | int ecc_set_curve(const ltc_ecc_curve *cu, ecc_key *key) | |
14 | { | |
15 | int err; | |
16 | ||
17 | LTC_ARGCHK(key != NULL); | |
18 | LTC_ARGCHK(cu != NULL); | |
19 | ||
20 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
21 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
22 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
23 | NULL)) != CRYPT_OK) { | |
24 | return err; | |
25 | } | |
26 | ||
27 | /* A, B, order, prime, Gx, Gy */ | |
28 | if ((err = mp_read_radix(key->dp.prime, cu->prime, 16)) != CRYPT_OK) { goto error; } | |
29 | if ((err = mp_read_radix(key->dp.order, cu->order, 16)) != CRYPT_OK) { goto error; } | |
30 | if ((err = mp_read_radix(key->dp.A, cu->A, 16)) != CRYPT_OK) { goto error; } | |
31 | if ((err = mp_read_radix(key->dp.B, cu->B, 16)) != CRYPT_OK) { goto error; } | |
32 | if ((err = mp_read_radix(key->dp.base.x, cu->Gx, 16)) != CRYPT_OK) { goto error; } | |
33 | if ((err = mp_read_radix(key->dp.base.y, cu->Gy, 16)) != CRYPT_OK) { goto error; } | |
34 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
35 | /* cofactor & size */ | |
36 | key->dp.cofactor = cu->cofactor; | |
37 | key->dp.size = mp_unsigned_bin_size(key->dp.prime); | |
38 | /* OID string >> unsigned long oid[16] + oidlen */ | |
39 | key->dp.oidlen = 16; | |
40 | if ((err = pk_oid_str_to_num(cu->OID, key->dp.oid, &key->dp.oidlen)) != CRYPT_OK) { goto error; } | |
41 | /* success */ | |
42 | return CRYPT_OK; | |
43 | ||
44 | error: | |
45 | ecc_free(key); | |
46 | return err; | |
47 | } | |
48 | ||
49 | int ecc_set_curve_by_size(int size, ecc_key *key) | |
50 | { | |
51 | const ltc_ecc_curve *cu = NULL; | |
52 | int err = CRYPT_ERROR; | |
53 | ||
54 | /* for compatibility with libtomcrypt-1.17 the sizes below must match the specific curves */ | |
55 | if (size <= 14) { | |
56 | err = ecc_find_curve("SECP112R1", &cu); | |
57 | } | |
58 | else if (size <= 16) { | |
59 | err = ecc_find_curve("SECP128R1", &cu); | |
60 | } | |
61 | else if (size <= 20) { | |
62 | err = ecc_find_curve("SECP160R1", &cu); | |
63 | } | |
64 | else if (size <= 24) { | |
65 | err = ecc_find_curve("SECP192R1", &cu); | |
66 | } | |
67 | else if (size <= 28) { | |
68 | err = ecc_find_curve("SECP224R1", &cu); | |
69 | } | |
70 | else if (size <= 32) { | |
71 | err = ecc_find_curve("SECP256R1", &cu); | |
72 | } | |
73 | else if (size <= 48) { | |
74 | err = ecc_find_curve("SECP384R1", &cu); | |
75 | } | |
76 | else if (size <= 66) { | |
77 | err = ecc_find_curve("SECP521R1", &cu); | |
78 | } | |
79 | ||
80 | if (err == CRYPT_OK && cu != NULL) return ecc_set_curve(cu, key); | |
81 | ||
82 | return CRYPT_INVALID_ARG; | |
83 | } | |
84 | ||
85 | #endif | |
86 | ||
87 | /* ref: $Format:%D$ */ | |
88 | /* git commit: $Format:%H$ */ | |
89 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | static int _ecc_cmp_hex_bn(const char *left_hex, void *right_bn, void *tmp_bn) | |
14 | { | |
15 | if (mp_read_radix(tmp_bn, left_hex, 16) != CRYPT_OK) return 0; | |
16 | if (mp_cmp(tmp_bn, right_bn) != LTC_MP_EQ) return 0; | |
17 | return 1; | |
18 | } | |
19 | ||
20 | static void _ecc_oid_lookup(ecc_key *key) | |
21 | { | |
22 | void *bn; | |
23 | const ltc_ecc_curve *curve; | |
24 | ||
25 | key->dp.oidlen = 0; | |
26 | if (mp_init(&bn) != CRYPT_OK) return; | |
27 | for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) { | |
28 | if (_ecc_cmp_hex_bn(curve->prime, key->dp.prime, bn) != 1) continue; | |
29 | if (_ecc_cmp_hex_bn(curve->order, key->dp.order, bn) != 1) continue; | |
30 | if (_ecc_cmp_hex_bn(curve->A, key->dp.A, bn) != 1) continue; | |
31 | if (_ecc_cmp_hex_bn(curve->B, key->dp.B, bn) != 1) continue; | |
32 | if (_ecc_cmp_hex_bn(curve->Gx, key->dp.base.x, bn) != 1) continue; | |
33 | if (_ecc_cmp_hex_bn(curve->Gy, key->dp.base.y, bn) != 1) continue; | |
34 | if (key->dp.cofactor != curve->cofactor) continue; | |
35 | break; /* found */ | |
36 | } | |
37 | mp_clear(bn); | |
38 | if (curve->prime && curve->OID) { | |
39 | key->dp.oidlen = 16; /* size of key->dp.oid */ | |
40 | pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen); | |
41 | } | |
42 | } | |
43 | ||
44 | int ecc_copy_curve(const ecc_key *srckey, ecc_key *key) | |
45 | { | |
46 | unsigned long i; | |
47 | int err; | |
48 | ||
49 | LTC_ARGCHK(key != NULL); | |
50 | LTC_ARGCHK(srckey != NULL); | |
51 | ||
52 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
53 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
54 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
55 | NULL)) != CRYPT_OK) { | |
56 | return err; | |
57 | } | |
58 | ||
59 | /* A, B, order, prime, Gx, Gy */ | |
60 | if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; } | |
61 | if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; } | |
62 | if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; } | |
63 | if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; } | |
64 | if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; } | |
65 | /* cofactor & size */ | |
66 | key->dp.cofactor = srckey->dp.cofactor; | |
67 | key->dp.size = srckey->dp.size; | |
68 | /* OID */ | |
69 | if (srckey->dp.oidlen > 0) { | |
70 | key->dp.oidlen = srckey->dp.oidlen; | |
71 | for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i]; | |
72 | } | |
73 | else { | |
74 | _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */ | |
75 | } | |
76 | /* success */ | |
77 | return CRYPT_OK; | |
78 | ||
79 | error: | |
80 | ecc_free(key); | |
81 | return err; | |
82 | } | |
83 | ||
84 | int ecc_set_curve_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) | |
85 | { | |
86 | int err; | |
87 | ||
88 | LTC_ARGCHK(key != NULL); | |
89 | LTC_ARGCHK(a != NULL); | |
90 | LTC_ARGCHK(b != NULL); | |
91 | LTC_ARGCHK(prime != NULL); | |
92 | LTC_ARGCHK(order != NULL); | |
93 | LTC_ARGCHK(gx != NULL); | |
94 | LTC_ARGCHK(gy != NULL); | |
95 | ||
96 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
97 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
98 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
99 | NULL)) != CRYPT_OK) { | |
100 | return err; | |
101 | } | |
102 | ||
103 | /* A, B, order, prime, Gx, Gy */ | |
104 | if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; } | |
105 | if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; } | |
106 | if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; } | |
107 | if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; } | |
108 | if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; } | |
109 | if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; } | |
110 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
111 | /* cofactor & size */ | |
112 | key->dp.cofactor = cofactor; | |
113 | key->dp.size = mp_unsigned_bin_size(prime); | |
114 | /* try to find OID in ltc_ecc_curves */ | |
115 | _ecc_oid_lookup(key); | |
116 | /* success */ | |
117 | return CRYPT_OK; | |
118 | ||
119 | error: | |
120 | ecc_free(key); | |
121 | return err; | |
122 | } | |
123 | ||
124 | #endif | |
125 | ||
126 | /* ref: $Format:%D$ */ | |
127 | /* git commit: $Format:%H$ */ | |
128 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | int ecc_set_dp(const ltc_ecc_curve *curve, ecc_key *key) | |
14 | { | |
15 | int err; | |
16 | ||
17 | LTC_ARGCHK(key != NULL); | |
18 | LTC_ARGCHK(curve != NULL); | |
19 | ||
20 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
21 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
22 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
23 | NULL)) != CRYPT_OK) { | |
24 | return err; | |
25 | } | |
26 | ||
27 | /* A, B, order, prime, Gx, Gy */ | |
28 | if ((err = mp_read_radix(key->dp.prime, curve->prime, 16)) != CRYPT_OK) { goto error; } | |
29 | if ((err = mp_read_radix(key->dp.order, curve->order, 16)) != CRYPT_OK) { goto error; } | |
30 | if ((err = mp_read_radix(key->dp.A, curve->A, 16)) != CRYPT_OK) { goto error; } | |
31 | if ((err = mp_read_radix(key->dp.B, curve->B, 16)) != CRYPT_OK) { goto error; } | |
32 | if ((err = mp_read_radix(key->dp.base.x, curve->Gx, 16)) != CRYPT_OK) { goto error; } | |
33 | if ((err = mp_read_radix(key->dp.base.y, curve->Gy, 16)) != CRYPT_OK) { goto error; } | |
34 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
35 | /* cofactor & size */ | |
36 | key->dp.cofactor = curve->cofactor; | |
37 | key->dp.size = mp_unsigned_bin_size(key->dp.prime); | |
38 | /* OID string >> unsigned long oid[16] + oidlen */ | |
39 | key->dp.oidlen = 16; | |
40 | if ((err = pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen)) != CRYPT_OK) { goto error; } | |
41 | /* success */ | |
42 | return CRYPT_OK; | |
43 | ||
44 | error: | |
45 | ecc_free(key); | |
46 | return err; | |
47 | } | |
48 | ||
49 | int ecc_set_dp_by_size(int size, ecc_key *key) | |
50 | { | |
51 | const ltc_ecc_curve *cu = NULL; | |
52 | int err = CRYPT_ERROR; | |
53 | ||
54 | /* for compatibility with libtomcrypt-1.17 the sizes below must match the specific curves */ | |
55 | if (size <= 14) { | |
56 | err = ecc_get_curve("SECP112R1", &cu); | |
57 | } | |
58 | else if (size <= 16) { | |
59 | err = ecc_get_curve("SECP128R1", &cu); | |
60 | } | |
61 | else if (size <= 20) { | |
62 | err = ecc_get_curve("SECP160R1", &cu); | |
63 | } | |
64 | else if (size <= 24) { | |
65 | err = ecc_get_curve("SECP192R1", &cu); | |
66 | } | |
67 | else if (size <= 28) { | |
68 | err = ecc_get_curve("SECP224R1", &cu); | |
69 | } | |
70 | else if (size <= 32) { | |
71 | err = ecc_get_curve("SECP256R1", &cu); | |
72 | } | |
73 | else if (size <= 48) { | |
74 | err = ecc_get_curve("SECP384R1", &cu); | |
75 | } | |
76 | else if (size <= 66) { | |
77 | err = ecc_get_curve("SECP521R1", &cu); | |
78 | } | |
79 | ||
80 | if (err == CRYPT_OK && cu != NULL) return ecc_set_dp(cu, key); | |
81 | ||
82 | return CRYPT_INVALID_ARG; | |
83 | } | |
84 | ||
85 | #endif | |
86 | ||
87 | /* ref: $Format:%D$ */ | |
88 | /* git commit: $Format:%H$ */ | |
89 | /* commit time: $Format:%ai$ */ |
0 | /* LibTomCrypt, modular cryptographic library -- Tom St Denis | |
1 | * | |
2 | * LibTomCrypt is a library that provides various cryptographic | |
3 | * algorithms in a highly modular and flexible manner. | |
4 | * | |
5 | * The library is free for all purposes without any express | |
6 | * guarantee it works. | |
7 | */ | |
8 | ||
9 | #include "tomcrypt_private.h" | |
10 | ||
11 | #ifdef LTC_MECC | |
12 | ||
13 | static int _ecc_cmp_hex_bn(const char *left_hex, void *right_bn, void *tmp_bn) | |
14 | { | |
15 | if (mp_read_radix(tmp_bn, left_hex, 16) != CRYPT_OK) return 0; | |
16 | if (mp_cmp(tmp_bn, right_bn) != LTC_MP_EQ) return 0; | |
17 | return 1; | |
18 | } | |
19 | ||
20 | static void _ecc_oid_lookup(ecc_key *key) | |
21 | { | |
22 | void *bn; | |
23 | const ltc_ecc_curve *curve; | |
24 | ||
25 | key->dp.oidlen = 0; | |
26 | if (mp_init(&bn) != CRYPT_OK) return; | |
27 | for (curve = ltc_ecc_curves; curve->prime != NULL; curve++) { | |
28 | if (_ecc_cmp_hex_bn(curve->prime, key->dp.prime, bn) != 1) continue; | |
29 | if (_ecc_cmp_hex_bn(curve->order, key->dp.order, bn) != 1) continue; | |
30 | if (_ecc_cmp_hex_bn(curve->A, key->dp.A, bn) != 1) continue; | |
31 | if (_ecc_cmp_hex_bn(curve->B, key->dp.B, bn) != 1) continue; | |
32 | if (_ecc_cmp_hex_bn(curve->Gx, key->dp.base.x, bn) != 1) continue; | |
33 | if (_ecc_cmp_hex_bn(curve->Gy, key->dp.base.y, bn) != 1) continue; | |
34 | if (key->dp.cofactor != curve->cofactor) continue; | |
35 | break; /* found */ | |
36 | } | |
37 | mp_clear(bn); | |
38 | if (curve->prime && curve->OID) { | |
39 | key->dp.oidlen = 16; /* size of key->dp.oid */ | |
40 | pk_oid_str_to_num(curve->OID, key->dp.oid, &key->dp.oidlen); | |
41 | } | |
42 | } | |
43 | ||
44 | int ecc_copy_dp(const ecc_key *srckey, ecc_key *key) | |
45 | { | |
46 | unsigned long i; | |
47 | int err; | |
48 | ||
49 | LTC_ARGCHK(key != NULL); | |
50 | LTC_ARGCHK(srckey != NULL); | |
51 | ||
52 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
53 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
54 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
55 | NULL)) != CRYPT_OK) { | |
56 | return err; | |
57 | } | |
58 | ||
59 | /* A, B, order, prime, Gx, Gy */ | |
60 | if ((err = mp_copy(srckey->dp.prime, key->dp.prime )) != CRYPT_OK) { goto error; } | |
61 | if ((err = mp_copy(srckey->dp.order, key->dp.order )) != CRYPT_OK) { goto error; } | |
62 | if ((err = mp_copy(srckey->dp.A, key->dp.A )) != CRYPT_OK) { goto error; } | |
63 | if ((err = mp_copy(srckey->dp.B, key->dp.B )) != CRYPT_OK) { goto error; } | |
64 | if ((err = ltc_ecc_copy_point(&srckey->dp.base, &key->dp.base)) != CRYPT_OK) { goto error; } | |
65 | /* cofactor & size */ | |
66 | key->dp.cofactor = srckey->dp.cofactor; | |
67 | key->dp.size = srckey->dp.size; | |
68 | /* OID */ | |
69 | if (srckey->dp.oidlen > 0) { | |
70 | key->dp.oidlen = srckey->dp.oidlen; | |
71 | for (i = 0; i < key->dp.oidlen; i++) key->dp.oid[i] = srckey->dp.oid[i]; | |
72 | } | |
73 | else { | |
74 | _ecc_oid_lookup(key); /* try to find OID in ltc_ecc_curves */ | |
75 | } | |
76 | /* success */ | |
77 | return CRYPT_OK; | |
78 | ||
79 | error: | |
80 | ecc_free(key); | |
81 | return err; | |
82 | } | |
83 | ||
84 | int ecc_set_dp_from_mpis(void *a, void *b, void *prime, void *order, void *gx, void *gy, unsigned long cofactor, ecc_key *key) | |
85 | { | |
86 | int err; | |
87 | ||
88 | LTC_ARGCHK(key != NULL); | |
89 | LTC_ARGCHK(a != NULL); | |
90 | LTC_ARGCHK(b != NULL); | |
91 | LTC_ARGCHK(prime != NULL); | |
92 | LTC_ARGCHK(order != NULL); | |
93 | LTC_ARGCHK(gx != NULL); | |
94 | LTC_ARGCHK(gy != NULL); | |
95 | ||
96 | if ((err = mp_init_multi(&key->dp.prime, &key->dp.order, &key->dp.A, &key->dp.B, | |
97 | &key->dp.base.x, &key->dp.base.y, &key->dp.base.z, | |
98 | &key->pubkey.x, &key->pubkey.y, &key->pubkey.z, &key->k, | |
99 | NULL)) != CRYPT_OK) { | |
100 | return err; | |
101 | } | |
102 | ||
103 | /* A, B, order, prime, Gx, Gy */ | |
104 | if ((err = mp_copy(prime, key->dp.prime )) != CRYPT_OK) { goto error; } | |
105 | if ((err = mp_copy(order, key->dp.order )) != CRYPT_OK) { goto error; } | |
106 | if ((err = mp_copy(a, key->dp.A )) != CRYPT_OK) { goto error; } | |
107 | if ((err = mp_copy(b, key->dp.B )) != CRYPT_OK) { goto error; } | |
108 | if ((err = mp_copy(gx, key->dp.base.x)) != CRYPT_OK) { goto error; } | |
109 | if ((err = mp_copy(gy, key->dp.base.y)) != CRYPT_OK) { goto error; } | |
110 | if ((err = mp_set(key->dp.base.z, 1)) != CRYPT_OK) { goto error; } | |
111 | /* cofactor & size */ | |
112 | key->dp.cofactor = cofactor; | |
113 | key->dp.size = mp_unsigned_bin_size(prime); | |
114 | /* try to find OID in ltc_ecc_curves */ | |
115 | _ecc_oid_lookup(key); | |
116 | /* success */ | |
117 | return CRYPT_OK; | |
118 | ||
119 | error: | |
120 | ecc_free(key); | |
121 | return err; | |
122 | } | |
123 | ||
124 | #endif | |
125 | ||
126 | /* ref: $Format:%D$ */ | |
127 | /* git commit: $Format:%H$ */ | |
128 | /* commit time: $Format:%ai$ */ |
62 | 62 | |
63 | 63 | /* make up a key and export the public copy */ |
64 | 64 | do { |
65 | if ((err = ecc_copy_dp(key, &pubkey)) != CRYPT_OK) { goto errnokey; } | |
65 | if ((err = ecc_copy_curve(key, &pubkey)) != CRYPT_OK) { goto errnokey; } | |
66 | 66 | if ((err = ecc_generate_key(prng, wprng, &pubkey)) != CRYPT_OK) { goto errnokey; } |
67 | 67 | |
68 | 68 | /* find r = x1 mod n */ |
43 | 43 | |
44 | 44 | /* test y^2 == x^3 */ |
45 | 45 | err = CRYPT_OK; |
46 | if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) | |
46 | if ((mp_cmp(x3, y2) == LTC_MP_EQ) && !mp_iszero(y2)) { | |
47 | 47 | *retval = 1; |
48 | else | |
48 | } else { | |
49 | 49 | *retval = 0; |
50 | } | |
50 | 51 | |
51 | 52 | cleanup: |
52 | 53 | mp_clear_multi(x3, y2, NULL); |
25 | 25 | int rsa_export(unsigned char *out, unsigned long *outlen, int type, const rsa_key *key) |
26 | 26 | { |
27 | 27 | unsigned long zero=0; |
28 | int err; | |
28 | int err, std; | |
29 | 29 | LTC_ARGCHK(out != NULL); |
30 | 30 | LTC_ARGCHK(outlen != NULL); |
31 | 31 | LTC_ARGCHK(key != NULL); |
32 | 32 | |
33 | /* type valid? */ | |
34 | if (!(key->type == PK_PRIVATE) && (type == PK_PRIVATE)) { | |
35 | return CRYPT_PK_INVALID_TYPE; | |
33 | std = type & PK_STD; | |
34 | type &= ~PK_STD; | |
35 | ||
36 | if (type == PK_PRIVATE && key->type != PK_PRIVATE) { | |
37 | return CRYPT_PK_TYPE_MISMATCH; | |
36 | 38 | } |
37 | 39 | |
38 | 40 | if (type == PK_PRIVATE) { |
51 | 53 | LTC_ASN1_INTEGER, 1UL, key->dQ, |
52 | 54 | LTC_ASN1_INTEGER, 1UL, key->qP, |
53 | 55 | LTC_ASN1_EOL, 0UL, NULL); |
54 | } else { | |
56 | } | |
57 | ||
58 | if (type == PK_PUBLIC) { | |
55 | 59 | /* public key */ |
56 | 60 | unsigned long tmplen, *ptmplen; |
57 | 61 | unsigned char* tmp = NULL; |
58 | 62 | |
59 | if (type & PK_STD) { | |
63 | if (std) { | |
60 | 64 | tmplen = (unsigned long)(mp_count_bits(key->N) / 8) * 2 + 8; |
61 | 65 | tmp = XMALLOC(tmplen); |
62 | 66 | ptmplen = &tmplen; |
74 | 78 | LTC_ASN1_INTEGER, 1UL, key->e, |
75 | 79 | LTC_ASN1_EOL, 0UL, NULL); |
76 | 80 | |
77 | if ((err != CRYPT_OK) || !(type & PK_STD)) { | |
81 | if ((err != CRYPT_OK) || !std) { | |
78 | 82 | goto finish; |
79 | 83 | } |
80 | 84 | |
82 | 86 | PKA_RSA, tmp, tmplen, LTC_ASN1_NULL, NULL, 0); |
83 | 87 | |
84 | 88 | finish: |
85 | if (tmp != out) | |
86 | XFREE(tmp); | |
89 | if (tmp != out) XFREE(tmp); | |
87 | 90 | return err; |
91 | } | |
88 | 92 | |
89 | } | |
93 | return CRYPT_INVALID_ARG; | |
90 | 94 | } |
91 | 95 | |
92 | 96 | #endif /* LTC_MRSA */ |
115 | 115 | mp_clear_multi(key->d, key->e, key->N, key->dQ, key->dP, key->qP, key->p, key->q, NULL); |
116 | 116 | |
117 | 117 | LBL_FREE: |
118 | if (tmpbuf != NULL) | |
119 | XFREE(tmpbuf); | |
120 | ||
118 | if (tmpbuf != NULL) { | |
119 | XFREE(tmpbuf); | |
120 | } | |
121 | 121 | return err; |
122 | 122 | } |
123 | 123 |
107 | 107 | |
108 | 108 | #ifdef LTC_FORTUNA_RESEED_RATELIMIT_TIMED |
109 | 109 | ulong64 now = _fortuna_current_time(); |
110 | if (now == prng->u.fortuna.wd) | |
110 | if (now == prng->u.fortuna.wd) { | |
111 | 111 | return CRYPT_OK; |
112 | } | |
112 | 113 | #else |
113 | if (++prng->u.fortuna.wd < LTC_FORTUNA_WD) | |
114 | if (++prng->u.fortuna.wd < LTC_FORTUNA_WD) { | |
114 | 115 | return CRYPT_OK; |
116 | } | |
115 | 117 | #endif |
116 | 118 | |
117 | 119 | /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ |
29 | 29 | LTC_UNUSED_PARAM(callback); |
30 | 30 | #ifdef LTC_TRY_URANDOM_FIRST |
31 | 31 | f = fopen("/dev/urandom", "rb"); |
32 | if (f == NULL) | |
32 | if (f == NULL) { | |
33 | f = fopen("/dev/random", "rb"); | |
34 | } | |
35 | #else | |
36 | f = fopen("/dev/random", "rb"); | |
33 | 37 | #endif /* LTC_TRY_URANDOM_FIRST */ |
34 | f = fopen("/dev/random", "rb"); | |
35 | 38 | |
36 | 39 | if (f == NULL) { |
37 | 40 | return 0; |
101 | 101 | @param prng The PRNG to export |
102 | 102 | @return CRYPT_OK if successful |
103 | 103 | */ |
104 | /* NOLINTNEXTLINE(readability-non-const-parameter) - silence clang-tidy warning */ | |
104 | 105 | int sprng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) |
105 | 106 | { |
106 | 107 | LTC_ARGCHK(outlen != NULL); |
98 | 98 | ulong32 g[8], c_old[8], i; |
99 | 99 | |
100 | 100 | /* Save old counter values */ |
101 | for (i=0; i<8; i++) | |
101 | for (i=0; i<8; i++) { | |
102 | 102 | c_old[i] = p_instance->c[i]; |
103 | } | |
103 | 104 | |
104 | 105 | /* Calculate new counter values */ |
105 | 106 | p_instance->c[0] = (ulong32)(p_instance->c[0] + 0x4D34D34D + p_instance->carry); |
113 | 114 | p_instance->carry = (p_instance->c[7] < c_old[7]); |
114 | 115 | |
115 | 116 | /* Calculate the g-values */ |
116 | for (i=0;i<8;i++) | |
117 | for (i=0;i<8;i++) { | |
117 | 118 | g[i] = _rabbit_g_func((ulong32)(p_instance->x[i] + p_instance->c[i])); |
119 | } | |
118 | 120 | |
119 | 121 | /* Calculate new state values */ |
120 | 122 | p_instance->x[0] = (ulong32)(g[0] + ROLc(g[7],16) + ROLc(g[6], 16)); |
197 | 199 | st->master_ctx.carry = 0; |
198 | 200 | |
199 | 201 | /* Iterate the master context four times */ |
200 | for (i=0; i<4; i++) | |
202 | for (i=0; i<4; i++) { | |
201 | 203 | _rabbit_next_state(&(st->master_ctx)); |
204 | } | |
202 | 205 | |
203 | 206 | /* Modify the counters */ |
204 | for (i=0; i<8; i++) | |
207 | for (i=0; i<8; i++) { | |
205 | 208 | st->master_ctx.c[i] ^= st->master_ctx.x[(i+4)&0x7]; |
209 | } | |
206 | 210 | |
207 | 211 | /* Copy master instance to work instance */ |
208 | 212 | for (i=0; i<8; i++) { |
249 | 253 | st->work_ctx.c[7] = st->master_ctx.c[7] ^ i3; |
250 | 254 | |
251 | 255 | /* Copy state variables */ |
252 | for (i=0; i<8; i++) | |
256 | for (i=0; i<8; i++) { | |
253 | 257 | st->work_ctx.x[i] = st->master_ctx.x[i]; |
258 | } | |
254 | 259 | st->work_ctx.carry = st->master_ctx.carry; |
255 | 260 | |
256 | 261 | /* Iterate the work context four times */ |
257 | for (i=0; i<4; i++) | |
262 | for (i=0; i<4; i++) { | |
258 | 263 | _rabbit_next_state(&(st->work_ctx)); |
264 | } | |
259 | 265 | |
260 | 266 | /* reset keystream buffer and unused count */ |
261 | 267 | XMEMSET(&(st->block), 0, sizeof(st->block)); |
296 | 302 | /* copy remainder to block */ |
297 | 303 | for (i = inlen; i < 16; ++i) st->block[i] = buf[i]; |
298 | 304 | return CRYPT_OK; |
299 | } else { | |
300 | /* XOR entire buf and send to out */ | |
301 | for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i]; | |
302 | inlen -= 16; | |
303 | out += 16; | |
304 | in += 16; | |
305 | 305 | } |
306 | /* XOR entire buf and send to out */ | |
307 | for (i = 0; i < 16; ++i) out[i] = in[i] ^ buf[i]; | |
308 | inlen -= 16; | |
309 | out += 16; | |
310 | in += 16; | |
306 | 311 | } |
307 | 312 | } |
308 | 313 |
67 | 67 | |
68 | 68 | /* Return a non-linear function of some parts of the register. |
69 | 69 | */ |
70 | #define NLFUNC(c,z) \ | |
70 | #define NLFUNC(st,z) \ | |
71 | 71 | { \ |
72 | t = c->R[OFF(z,0)] + c->R[OFF(z,16)]; \ | |
72 | t = st->R[OFF(z,0)] + st->R[OFF(z,16)]; \ | |
73 | 73 | t ^= Sbox[(t >> 24) & 0xFF]; \ |
74 | 74 | t = RORc(t, 8); \ |
75 | t = ((t + c->R[OFF(z,1)]) ^ c->konst) + c->R[OFF(z,6)]; \ | |
75 | t = ((t + st->R[OFF(z,1)]) ^ st->konst) + st->R[OFF(z,6)]; \ | |
76 | 76 | t ^= Sbox[(t >> 24) & 0xFF]; \ |
77 | t = t + c->R[OFF(z,13)]; \ | |
78 | } | |
79 | ||
80 | static ulong32 nltap(const sober128_state *c) | |
77 | t = t + st->R[OFF(z,13)]; \ | |
78 | } | |
79 | ||
80 | static ulong32 nltap(const sober128_state *st) | |
81 | 81 | { |
82 | 82 | ulong32 t; |
83 | NLFUNC(c, 0); | |
83 | NLFUNC(st, 0); | |
84 | 84 | return t; |
85 | 85 | } |
86 | 86 | |
87 | 87 | /* Save the current register state |
88 | 88 | */ |
89 | static void s128_savestate(sober128_state *c) | |
89 | static void s128_savestate(sober128_state *st) | |
90 | 90 | { |
91 | 91 | int i; |
92 | 92 | for (i = 0; i < N; ++i) { |
93 | c->initR[i] = c->R[i]; | |
93 | st->initR[i] = st->R[i]; | |
94 | 94 | } |
95 | 95 | } |
96 | 96 | |
97 | 97 | /* initialise to previously saved register state |
98 | 98 | */ |
99 | static void s128_reloadstate(sober128_state *c) | |
99 | static void s128_reloadstate(sober128_state *st) | |
100 | 100 | { |
101 | 101 | int i; |
102 | 102 | |
103 | 103 | for (i = 0; i < N; ++i) { |
104 | c->R[i] = c->initR[i]; | |
104 | st->R[i] = st->initR[i]; | |
105 | 105 | } |
106 | 106 | } |
107 | 107 | |
108 | 108 | /* Initialise "konst" |
109 | 109 | */ |
110 | static void s128_genkonst(sober128_state *c) | |
110 | static void s128_genkonst(sober128_state *st) | |
111 | 111 | { |
112 | 112 | ulong32 newkonst; |
113 | 113 | |
114 | 114 | do { |
115 | cycle(c->R); | |
116 | newkonst = nltap(c); | |
115 | cycle(st->R); | |
116 | newkonst = nltap(st); | |
117 | 117 | } while ((newkonst & 0xFF000000) == 0); |
118 | c->konst = newkonst; | |
118 | st->konst = newkonst; | |
119 | 119 | } |
120 | 120 | |
121 | 121 | /* Load key material into the register |
122 | 122 | */ |
123 | 123 | #define ADDKEY(k) \ |
124 | c->R[KEYP] += (k); | |
124 | st->R[KEYP] += (k); | |
125 | 125 | |
126 | 126 | #define XORNL(nl) \ |
127 | c->R[FOLDP] ^= (nl); | |
127 | st->R[FOLDP] ^= (nl); | |
128 | 128 | |
129 | 129 | /* nonlinear diffusion of register for key */ |
130 | #define DROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); c->R[OFF((z+1),FOLDP)] ^= t; | |
131 | static void s128_diffuse(sober128_state *c) | |
130 | #define DROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); st->R[OFF((z+1),FOLDP)] ^= t; | |
131 | static void s128_diffuse(sober128_state *st) | |
132 | 132 | { |
133 | 133 | ulong32 t; |
134 | 134 | /* relies on FOLD == N == 17! */ |
153 | 153 | |
154 | 154 | /** |
155 | 155 | Initialize an Sober128 context (only the key) |
156 | @param c [out] The destination of the Sober128 state | |
156 | @param st [out] The destination of the Sober128 state | |
157 | 157 | @param key The secret key |
158 | 158 | @param keylen The length of the secret key (octets) |
159 | 159 | @return CRYPT_OK if successful |
160 | 160 | */ |
161 | int sober128_stream_setup(sober128_state *c, const unsigned char *key, unsigned long keylen) | |
161 | int sober128_stream_setup(sober128_state *st, const unsigned char *key, unsigned long keylen) | |
162 | 162 | { |
163 | 163 | ulong32 i, k; |
164 | 164 | |
165 | LTC_ARGCHK(c != NULL); | |
165 | LTC_ARGCHK(st != NULL); | |
166 | 166 | LTC_ARGCHK(key != NULL); |
167 | 167 | LTC_ARGCHK(keylen > 0); |
168 | 168 | |
172 | 172 | } |
173 | 173 | |
174 | 174 | /* Register initialised to Fibonacci numbers */ |
175 | c->R[0] = 1; | |
176 | c->R[1] = 1; | |
175 | st->R[0] = 1; | |
176 | st->R[1] = 1; | |
177 | 177 | for (i = 2; i < N; ++i) { |
178 | c->R[i] = c->R[i-1] + c->R[i-2]; | |
179 | } | |
180 | c->konst = INITKONST; | |
178 | st->R[i] = st->R[i-1] + st->R[i-2]; | |
179 | } | |
180 | st->konst = INITKONST; | |
181 | 181 | |
182 | 182 | for (i = 0; i < keylen; i += 4) { |
183 | 183 | k = BYTE2WORD((unsigned char *)&key[i]); |
184 | 184 | ADDKEY(k); |
185 | cycle(c->R); | |
186 | XORNL(nltap(c)); | |
185 | cycle(st->R); | |
186 | XORNL(nltap(st)); | |
187 | 187 | } |
188 | 188 | |
189 | 189 | /* also fold in the length of the key */ |
190 | 190 | ADDKEY(keylen); |
191 | 191 | |
192 | 192 | /* now diffuse */ |
193 | s128_diffuse(c); | |
194 | s128_genkonst(c); | |
195 | s128_savestate(c); | |
196 | c->nbuf = 0; | |
193 | s128_diffuse(st); | |
194 | s128_genkonst(st); | |
195 | s128_savestate(st); | |
196 | st->nbuf = 0; | |
197 | 197 | |
198 | 198 | return CRYPT_OK; |
199 | 199 | } |
200 | 200 | |
201 | 201 | /** |
202 | 202 | Set IV to the Sober128 state |
203 | @param c The Sober12820 state | |
203 | @param st The Sober12820 state | |
204 | 204 | @param iv The IV data to add |
205 | 205 | @param ivlen The length of the IV (must be 12) |
206 | 206 | @return CRYPT_OK on success |
207 | 207 | */ |
208 | int sober128_stream_setiv(sober128_state *c, const unsigned char *iv, unsigned long ivlen) | |
208 | int sober128_stream_setiv(sober128_state *st, const unsigned char *iv, unsigned long ivlen) | |
209 | 209 | { |
210 | 210 | ulong32 i, k; |
211 | 211 | |
212 | LTC_ARGCHK(c != NULL); | |
212 | LTC_ARGCHK(st != NULL); | |
213 | 213 | LTC_ARGCHK(iv != NULL); |
214 | 214 | LTC_ARGCHK(ivlen > 0); |
215 | 215 | |
216 | 216 | /* ok we are adding an IV then... */ |
217 | s128_reloadstate(c); | |
217 | s128_reloadstate(st); | |
218 | 218 | |
219 | 219 | /* ivlen must be multiple of 4 bytes */ |
220 | 220 | if ((ivlen & 3) != 0) { |
224 | 224 | for (i = 0; i < ivlen; i += 4) { |
225 | 225 | k = BYTE2WORD((unsigned char *)&iv[i]); |
226 | 226 | ADDKEY(k); |
227 | cycle(c->R); | |
228 | XORNL(nltap(c)); | |
227 | cycle(st->R); | |
228 | XORNL(nltap(st)); | |
229 | 229 | } |
230 | 230 | |
231 | 231 | /* also fold in the length of the key */ |
232 | 232 | ADDKEY(ivlen); |
233 | 233 | |
234 | 234 | /* now diffuse */ |
235 | s128_diffuse(c); | |
236 | c->nbuf = 0; | |
235 | s128_diffuse(st); | |
236 | st->nbuf = 0; | |
237 | 237 | |
238 | 238 | return CRYPT_OK; |
239 | 239 | } |
240 | 240 | |
241 | 241 | /* XOR pseudo-random bytes into buffer |
242 | 242 | */ |
243 | #define SROUND(z) STEP(c->R,z); NLFUNC(c,(z+1)); XORWORD(t, in+(z*4), out+(z*4)); | |
243 | #define SROUND(z) STEP(st->R,z); NLFUNC(st,(z+1)); XORWORD(t, in+(z*4), out+(z*4)); | |
244 | 244 | |
245 | 245 | /** |
246 | 246 | Encrypt (or decrypt) bytes of ciphertext (or plaintext) with Sober128 |
247 | @param c The Sober128 state | |
247 | @param st The Sober128 state | |
248 | 248 | @param in The plaintext (or ciphertext) |
249 | 249 | @param inlen The length of the input (octets) |
250 | 250 | @param out [out] The ciphertext (or plaintext), length inlen |
251 | 251 | @return CRYPT_OK if successful |
252 | 252 | */ |
253 | int sober128_stream_crypt(sober128_state *c, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
253 | int sober128_stream_crypt(sober128_state *st, const unsigned char *in, unsigned long inlen, unsigned char *out) | |
254 | 254 | { |
255 | 255 | ulong32 t; |
256 | 256 | |
257 | 257 | if (inlen == 0) return CRYPT_OK; /* nothing to do */ |
258 | 258 | LTC_ARGCHK(out != NULL); |
259 | LTC_ARGCHK(c != NULL); | |
259 | LTC_ARGCHK(st != NULL); | |
260 | 260 | |
261 | 261 | /* handle any previously buffered bytes */ |
262 | while (c->nbuf != 0 && inlen != 0) { | |
263 | *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF); | |
264 | c->sbuf >>= 8; | |
265 | c->nbuf -= 8; | |
262 | while (st->nbuf != 0 && inlen != 0) { | |
263 | *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF); | |
264 | st->sbuf >>= 8; | |
265 | st->nbuf -= 8; | |
266 | 266 | --inlen; |
267 | 267 | } |
268 | 268 | |
294 | 294 | |
295 | 295 | /* do small or odd size buffers the slow way */ |
296 | 296 | while (4 <= inlen) { |
297 | cycle(c->R); | |
298 | t = nltap(c); | |
297 | cycle(st->R); | |
298 | t = nltap(st); | |
299 | 299 | XORWORD(t, in, out); |
300 | 300 | out += 4; |
301 | 301 | in += 4; |
304 | 304 | |
305 | 305 | /* handle any trailing bytes */ |
306 | 306 | if (inlen != 0) { |
307 | cycle(c->R); | |
308 | c->sbuf = nltap(c); | |
309 | c->nbuf = 32; | |
310 | while (c->nbuf != 0 && inlen != 0) { | |
311 | *out++ = *in++ ^ (unsigned char)(c->sbuf & 0xFF); | |
312 | c->sbuf >>= 8; | |
313 | c->nbuf -= 8; | |
307 | cycle(st->R); | |
308 | st->sbuf = nltap(st); | |
309 | st->nbuf = 32; | |
310 | while (st->nbuf != 0 && inlen != 0) { | |
311 | *out++ = *in++ ^ (unsigned char)(st->sbuf & 0xFF); | |
312 | st->sbuf >>= 8; | |
313 | st->nbuf -= 8; | |
314 | 314 | --inlen; |
315 | 315 | } |
316 | 316 | } |
318 | 318 | return CRYPT_OK; |
319 | 319 | } |
320 | 320 | |
321 | int sober128_stream_keystream(sober128_state *c, unsigned char *out, unsigned long outlen) | |
321 | int sober128_stream_keystream(sober128_state *st, unsigned char *out, unsigned long outlen) | |
322 | 322 | { |
323 | 323 | if (outlen == 0) return CRYPT_OK; /* nothing to do */ |
324 | 324 | LTC_ARGCHK(out != NULL); |
325 | 325 | XMEMSET(out, 0, outlen); |
326 | return sober128_stream_crypt(c, out, outlen, out); | |
326 | return sober128_stream_crypt(st, out, outlen, out); | |
327 | 327 | } |
328 | 328 | |
329 | 329 | /** |
330 | 330 | Terminate and clear Sober128 state |
331 | @param c The Sober128 state | |
331 | @param st The Sober128 state | |
332 | 332 | @return CRYPT_OK on success |
333 | 333 | */ |
334 | int sober128_stream_done(sober128_state *c) | |
335 | { | |
336 | LTC_ARGCHK(c != NULL); | |
337 | XMEMSET(c, 0, sizeof(sober128_state)); | |
334 | int sober128_stream_done(sober128_state *st) | |
335 | { | |
336 | LTC_ARGCHK(st != NULL); | |
337 | XMEMSET(st, 0, sizeof(sober128_state)); | |
338 | 338 | return CRYPT_OK; |
339 | 339 | } |
340 | 340 |
265 | 265 | XMEMCPY(wbuf, key, keylen); |
266 | 266 | if (keylen < 32) { |
267 | 267 | wbuf[keylen] = 0x01; |
268 | if (keylen < 31) | |
268 | if (keylen < 31) { | |
269 | 269 | XMEMSET(wbuf + keylen + 1, 0, 31 - keylen); |
270 | } | |
270 | 271 | } |
271 | 272 | |
272 | 273 | LOAD32L(w0, wbuf); |
724 | 725 | static LTC_INLINE void _xorbuf(const unsigned char *in1, const unsigned char *in2, |
725 | 726 | unsigned char *out, unsigned long datalen) |
726 | 727 | { |
727 | while (datalen -- > 0) | |
728 | while (datalen -- > 0) { | |
728 | 729 | *out ++ = *in1 ++ ^ *in2 ++; |
730 | } | |
729 | 731 | } |
730 | 732 | |
731 | 733 | |
750 | 752 | if (ss->ptr < (sizeof(ss->buf))) { |
751 | 753 | unsigned long rlen = (sizeof(ss->buf)) - ss->ptr; |
752 | 754 | |
753 | if (rlen > inlen) | |
755 | if (rlen > inlen) { | |
754 | 756 | rlen = inlen; |
757 | } | |
755 | 758 | _xorbuf(ss->buf + ss->ptr, in, out, rlen); |
756 | 759 | in += rlen; |
757 | 760 | out += rlen; |