ltc update
Karel Miko
6 years ago
583 | 583 | { |
584 | 584 | STRLEN in_len; |
585 | 585 | unsigned long out_len; |
586 | unsigned char *out_data, *in_data; | |
586 | unsigned char *in_data; | |
587 | char *out_data; | |
587 | 588 | int id = -1; |
588 | 589 | |
589 | 590 | if (!SvPOK(in)) XSRETURN_UNDEF; |
600 | 601 | out_len = (unsigned long)((8 * in_len + 4) / 5); |
601 | 602 | RETVAL = NEWSV(0, out_len); /* avoid zero! */ |
602 | 603 | SvPOK_only(RETVAL); |
603 | out_data = (unsigned char *)SvPVX(RETVAL); | |
604 | out_data = SvPVX(RETVAL); | |
604 | 605 | if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { |
605 | 606 | SvREFCNT_dec(RETVAL); |
606 | 607 | XSRETURN_UNDEF; |
621 | 622 | { |
622 | 623 | STRLEN in_len; |
623 | 624 | unsigned long out_len; |
624 | unsigned char *out_data, *in_data; | |
625 | unsigned char *out_data; | |
626 | char *in_data; | |
625 | 627 | int id = -1; |
626 | 628 | |
627 | 629 | if (!SvPOK(in)) XSRETURN_UNDEF; |
630 | 632 | if (ix == 2) id = BASE32_ZBASE32; |
631 | 633 | if (ix == 3) id = BASE32_CROCKFORD; |
632 | 634 | if (id == -1) XSRETURN_UNDEF; |
633 | in_data = (unsigned char *)SvPVbyte(in, in_len); | |
635 | in_data = SvPVbyte(in, in_len); | |
634 | 636 | if (in_len == 0) { |
635 | 637 | RETVAL = newSVpvn("", 0); |
636 | 638 | } |
41 | 41 | ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \ |
42 | 42 | ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/copy_or_zeromem.o \ |
43 | 43 | ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o \ |
44 | ltc/misc/zeromem.o ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o \ | |
45 | ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o \ | |
46 | ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o \ | |
47 | ltc/misc/crypt/crypt_constants.o ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o \ | |
48 | ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o \ | |
49 | ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o \ | |
50 | ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o \ | |
51 | ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o \ | |
52 | ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \ | |
44 | ltc/misc/zeromem.o ltc/misc/base16/base16_decode.o ltc/misc/base16/base16_encode.o \ | |
45 | ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o \ | |
46 | ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \ | |
47 | ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o \ | |
48 | ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \ | |
49 | ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \ | |
50 | ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \ | |
51 | ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \ | |
52 | ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \ | |
53 | ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \ | |
53 | 54 | ltc/misc/crypt/crypt_register_all_hashes.o ltc/misc/crypt/crypt_register_all_prngs.o \ |
54 | 55 | ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \ |
55 | 56 | ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \ |
56 | ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/pkcs5/pkcs_5_1.o \ | |
57 | ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ | |
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 \ | |
58 | 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 \ |
59 | 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 \ |
60 | 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 \ |
44 | 44 | ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \ |
45 | 45 | ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/copy_or_zeromem.obj \ |
46 | 46 | ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj \ |
47 | ltc/misc/zeromem.obj ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj \ | |
48 | ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj \ | |
49 | ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ | |
47 | ltc/misc/zeromem.obj ltc/misc/base16/base16_decode.obj ltc/misc/base16/base16_encode.obj \ | |
48 | ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj \ | |
49 | ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \ | |
50 | ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ | |
50 | 51 | ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \ |
51 | 52 | ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \ |
52 | 53 | ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \ |
57 | 58 | ltc/misc/crypt/crypt_register_all_prngs.obj ltc/misc/crypt/crypt_register_cipher.obj \ |
58 | 59 | ltc/misc/crypt/crypt_register_hash.obj ltc/misc/crypt/crypt_register_prng.obj ltc/misc/crypt/crypt_sizes.obj \ |
59 | 60 | ltc/misc/crypt/crypt_unregister_cipher.obj ltc/misc/crypt/crypt_unregister_hash.obj \ |
60 | ltc/misc/crypt/crypt_unregister_prng.obj ltc/misc/hkdf/hkdf.obj ltc/misc/pkcs5/pkcs_5_1.obj \ | |
61 | ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj ltc/modes/cbc/cbc_done.obj \ | |
62 | ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj ltc/modes/cbc/cbc_setiv.obj \ | |
63 | ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj ltc/modes/cfb/cfb_done.obj \ | |
64 | ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj ltc/modes/cfb/cfb_setiv.obj \ | |
65 | ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj ltc/modes/ctr/ctr_done.obj \ | |
66 | ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj ltc/modes/ctr/ctr_setiv.obj \ | |
67 | ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj ltc/modes/ecb/ecb_done.obj \ | |
68 | ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj ltc/modes/ofb/ofb_decrypt.obj \ | |
69 | ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj ltc/modes/ofb/ofb_getiv.obj \ | |
70 | ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj ltc/pk/asn1/der/bit/der_decode_bit_string.obj \ | |
71 | ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_encode_bit_string.obj \ | |
72 | ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_length_bit_string.obj \ | |
73 | ltc/pk/asn1/der/boolean/der_decode_boolean.obj ltc/pk/asn1/der/boolean/der_encode_boolean.obj \ | |
74 | ltc/pk/asn1/der/boolean/der_length_boolean.obj ltc/pk/asn1/der/choice/der_decode_choice.obj \ | |
75 | ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj \ | |
76 | ltc/pk/asn1/der/custom_type/der_length_custom_type.obj ltc/pk/asn1/der/general/der_asn1_maps.obj \ | |
77 | ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj ltc/pk/asn1/der/general/der_decode_asn1_length.obj \ | |
78 | ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj ltc/pk/asn1/der/general/der_encode_asn1_length.obj \ | |
79 | ltc/pk/asn1/der/general/der_length_asn1_identifier.obj ltc/pk/asn1/der/general/der_length_asn1_length.obj \ | |
80 | ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ | |
81 | ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \ | |
82 | ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \ | |
83 | ltc/pk/asn1/der/integer/der_decode_integer.obj ltc/pk/asn1/der/integer/der_encode_integer.obj \ | |
84 | ltc/pk/asn1/der/integer/der_length_integer.obj ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ | |
85 | ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ | |
86 | ltc/pk/asn1/der/octet/der_decode_octet_string.obj ltc/pk/asn1/der/octet/der_encode_octet_string.obj \ | |
87 | ltc/pk/asn1/der/octet/der_length_octet_string.obj ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj \ | |
88 | ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj ltc/pk/asn1/der/printable_string/der_length_printable_string.obj \ | |
89 | ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ | |
90 | ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ | |
91 | ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \ | |
92 | ltc/pk/asn1/der/sequence/der_sequence_free.obj ltc/pk/asn1/der/sequence/der_sequence_shrink.obj \ | |
93 | ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ | |
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 \ | |
73 | ltc/pk/asn1/der/bit/der_encode_bit_string.obj ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj \ | |
74 | ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ | |
75 | ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ | |
76 | ltc/pk/asn1/der/choice/der_decode_choice.obj ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj \ | |
77 | ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj ltc/pk/asn1/der/custom_type/der_length_custom_type.obj \ | |
78 | ltc/pk/asn1/der/general/der_asn1_maps.obj ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj \ | |
79 | ltc/pk/asn1/der/general/der_decode_asn1_length.obj ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj \ | |
80 | ltc/pk/asn1/der/general/der_encode_asn1_length.obj ltc/pk/asn1/der/general/der_length_asn1_identifier.obj \ | |
81 | ltc/pk/asn1/der/general/der_length_asn1_length.obj ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj \ | |
82 | ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ | |
83 | ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj \ | |
84 | ltc/pk/asn1/der/ia5/der_length_ia5_string.obj ltc/pk/asn1/der/integer/der_decode_integer.obj \ | |
85 | ltc/pk/asn1/der/integer/der_encode_integer.obj ltc/pk/asn1/der/integer/der_length_integer.obj \ | |
86 | ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ | |
87 | ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj ltc/pk/asn1/der/octet/der_decode_octet_string.obj \ | |
88 | ltc/pk/asn1/der/octet/der_encode_octet_string.obj ltc/pk/asn1/der/octet/der_length_octet_string.obj \ | |
89 | ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj \ | |
90 | ltc/pk/asn1/der/printable_string/der_length_printable_string.obj ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ | |
91 | ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ | |
92 | ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj \ | |
93 | ltc/pk/asn1/der/sequence/der_length_sequence.obj ltc/pk/asn1/der/sequence/der_sequence_free.obj \ | |
94 | ltc/pk/asn1/der/sequence/der_sequence_shrink.obj ltc/pk/asn1/der/set/der_encode_set.obj \ | |
95 | ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ | |
94 | 96 | ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \ |
95 | 97 | ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.obj ltc/pk/asn1/der/teletex_string/der_length_teletex_string.obj \ |
96 | 98 | ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \ |
449 | 449 | #define LTC_BASE64_URL |
450 | 450 | /* Base32 encoding/decoding */ |
451 | 451 | #define LTC_BASE32 |
452 | /* Base16/hex encoding/decoding */ | |
453 | #define LTC_BASE16 | |
452 | 454 | |
453 | 455 | /* Keep LTC_NO_HKDF for compatibility reasons |
454 | 456 | * superseeded by LTC_NO_MISC*/ |
460 | 462 | #define LTC_ADLER32 |
461 | 463 | |
462 | 464 | #define LTC_CRC32 |
465 | ||
466 | #define LTC_PADDING | |
463 | 467 | |
464 | 468 | #endif /* LTC_NO_MISC */ |
465 | 469 |
38 | 38 | BASE32_CROCKFORD = 3 |
39 | 39 | } base32_alphabet; |
40 | 40 | int base32_encode(const unsigned char *in, unsigned long inlen, |
41 | char *out, unsigned long *outlen, | |
42 | base32_alphabet id); | |
43 | int base32_decode(const char *in, unsigned long inlen, | |
41 | 44 | unsigned char *out, unsigned long *outlen, |
42 | 45 | base32_alphabet id); |
43 | int base32_decode(const unsigned char *in, unsigned long inlen, | |
44 | unsigned char *out, unsigned long *outlen, | |
45 | base32_alphabet id); | |
46 | #endif | |
47 | ||
48 | /* ---- BASE16 Routines ---- */ | |
49 | #ifdef LTC_BASE16 | |
50 | int base16_encode(const unsigned char *in, unsigned long inlen, | |
51 | char *out, unsigned long *outlen, | |
52 | int caps); | |
53 | int base16_decode(const char *in, | |
54 | unsigned char *out, unsigned long *outlen); | |
46 | 55 | #endif |
47 | 56 | |
48 | 57 | /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ |
125 | 134 | int crc32_test(void); |
126 | 135 | #endif |
127 | 136 | |
137 | ||
138 | #ifdef LTC_PADDING | |
139 | ||
140 | enum padding_type { | |
141 | LTC_PAD_PKCS7 = 0x0000U, | |
142 | #ifdef LTC_RNG_GET_BYTES | |
143 | LTC_PAD_ISO_10126 = 0x1000U, | |
144 | #endif | |
145 | LTC_PAD_ANSI_X923 = 0x2000U, | |
146 | LTC_PAD_ONE_AND_ZERO = 0x8000U, | |
147 | LTC_PAD_ZERO = 0x9000U, | |
148 | LTC_PAD_ZERO_ALWAYS = 0xA000U, | |
149 | }; | |
150 | ||
151 | int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode); | |
152 | int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode); | |
153 | ||
154 | #ifdef LTC_SOURCE | |
155 | /* internal helper functions */ | |
156 | #define LTC_PAD_MASK (0xF000U) | |
157 | #endif | |
158 | #endif /* LTC_PADDING */ | |
159 | ||
128 | 160 | int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); |
129 | 161 | |
130 | 162 | /* ref: $Format:%D$ */ |
8 | 8 | |
9 | 9 | /* ---- NUMBER THEORY ---- */ |
10 | 10 | |
11 | enum { | |
12 | PK_PUBLIC=0, | |
13 | PK_PRIVATE=1 | |
11 | enum public_key_type { | |
12 | /* Refers to the public key */ | |
13 | PK_PUBLIC = 0x0000, | |
14 | /* Refers to the private key */ | |
15 | PK_PRIVATE = 0x0001, | |
16 | ||
17 | /* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ | |
18 | PK_STD = 0x1000, | |
19 | /* Indicates compressed public ECC key */ | |
20 | PK_COMPRESSED = 0x2000, | |
21 | /* Indicates ECC key with the curve specified by OID */ | |
22 | PK_CURVEOID = 0x4000 | |
14 | 23 | }; |
15 | ||
16 | /* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ | |
17 | #define PK_STD 0x1000 | |
18 | /* Indicates compressed public ECC key */ | |
19 | #define PK_COMPRESSED 0x2000 | |
20 | /* Indicates ECC key with the curve specified by OID */ | |
21 | #define PK_CURVEOID 0x4000 | |
22 | 24 | |
23 | 25 | int rand_prime(void *N, long len, prng_state *prng, int wprng); |
24 | 26 | |
604 | 606 | /** Flag used to indicate optional items in ASN.1 sequences */ |
605 | 607 | int optional; |
606 | 608 | /** ASN.1 identifier */ |
607 | ltc_asn1_class class; | |
609 | ltc_asn1_class klass; | |
608 | 610 | ltc_asn1_pc pc; |
609 | 611 | ulong64 tag; |
610 | 612 | /** prev/next entry in the list */ |
620 | 622 | LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ |
621 | 623 | LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ |
622 | 624 | LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \ |
623 | LTC_MACRO_list[LTC_MACRO_temp].class = 0; \ | |
625 | LTC_MACRO_list[LTC_MACRO_temp].klass = 0; \ | |
624 | 626 | LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \ |
625 | 627 | LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ |
626 | 628 | } while (0) |
630 | 632 | int LTC_MACRO_temp = (index); \ |
631 | 633 | ltc_asn1_list *LTC_MACRO_list = (list); \ |
632 | 634 | LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \ |
633 | LTC_MACRO_list[LTC_MACRO_temp].class = (Class); \ | |
635 | LTC_MACRO_list[LTC_MACRO_temp].klass = (Class); \ | |
634 | 636 | LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \ |
635 | 637 | LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \ |
636 | 638 | } while (0) |
906 | 908 | /* internal helper functions */ |
907 | 909 | /* SUBJECT PUBLIC KEY INFO */ |
908 | 910 | int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, |
909 | unsigned int algorithm, void* public_key, unsigned long public_key_len, | |
910 | unsigned long parameters_type, void* parameters, unsigned long parameters_len); | |
911 | unsigned int algorithm, const void* public_key, unsigned long public_key_len, | |
912 | ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); | |
911 | 913 | |
912 | 914 | int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, |
913 | 915 | unsigned int algorithm, void* public_key, unsigned long* public_key_len, |
914 | unsigned long parameters_type, void* parameters, unsigned long *parameters_len); | |
916 | ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); | |
915 | 917 | #endif /* LTC_SOURCE */ |
916 | 918 | |
917 | 919 | #endif |
211 | 211 | int prng_is_valid(int idx); |
212 | 212 | LTC_MUTEX_PROTO(ltc_prng_mutex) |
213 | 213 | |
214 | #ifdef LTC_SOURCE | |
215 | /* internal helper functions */ | |
216 | #define _LTC_PRNG_EXPORT(which) \ | |
217 | int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng) \ | |
218 | { \ | |
219 | unsigned long len = which ## _desc.export_size; \ | |
220 | \ | |
221 | LTC_ARGCHK(prng != NULL); \ | |
222 | LTC_ARGCHK(out != NULL); \ | |
223 | LTC_ARGCHK(outlen != NULL); \ | |
224 | \ | |
225 | if (*outlen < len) { \ | |
226 | *outlen = len; \ | |
227 | return CRYPT_BUFFER_OVERFLOW; \ | |
228 | } \ | |
229 | \ | |
230 | if (which ## _read(out, len, prng) != len) { \ | |
231 | return CRYPT_ERROR_READPRNG; \ | |
232 | } \ | |
233 | \ | |
234 | *outlen = len; \ | |
235 | return CRYPT_OK; \ | |
236 | } | |
237 | #endif | |
238 | ||
214 | 239 | /* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this |
215 | 240 | * might not work on all platforms as planned |
216 | 241 | */ |
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.h" | |
10 | ||
11 | /** | |
12 | @file base16_decode.c | |
13 | Base16/Hex decode a string. | |
14 | Based on https://stackoverflow.com/a/23898449 | |
15 | Adapted for libtomcrypt by Steffen Jaeckel | |
16 | */ | |
17 | ||
18 | #ifdef LTC_BASE16 | |
19 | ||
20 | /** | |
21 | Base16 decode a string | |
22 | @param in The Base16 string to decode | |
23 | @param out [out] The destination of the binary decoded data | |
24 | @param outlen [in/out] The max size and resulting size of the decoded data | |
25 | @return CRYPT_OK if successful | |
26 | */ | |
27 | int base16_decode(const char *in, | |
28 | unsigned char *out, unsigned long *outlen) | |
29 | { | |
30 | unsigned long pos, in_len, out_len; | |
31 | unsigned char idx0; | |
32 | unsigned char idx1; | |
33 | ||
34 | const unsigned char hashmap[] = { | |
35 | 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ | |
36 | 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */ | |
37 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */ | |
38 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */ | |
39 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */ | |
40 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */ | |
41 | 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */ | |
42 | }; | |
43 | ||
44 | LTC_ARGCHK(in != NULL); | |
45 | LTC_ARGCHK(out != NULL); | |
46 | LTC_ARGCHK(outlen != NULL); | |
47 | ||
48 | in_len = strlen(in); | |
49 | if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET; | |
50 | out_len = *outlen * 2; | |
51 | for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) { | |
52 | idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10; | |
53 | idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10; | |
54 | out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1]; | |
55 | } | |
56 | *outlen = pos / 2; | |
57 | return CRYPT_OK; | |
58 | } | |
59 | ||
60 | #endif | |
61 | ||
62 | /* ref: $Format:%D$ */ | |
63 | /* git commit: $Format:%H$ */ | |
64 | /* 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.h" | |
10 | ||
11 | /** | |
12 | @file base16_encode.c | |
13 | Base16/Hex encode a string, Steffen Jaeckel | |
14 | */ | |
15 | ||
16 | #ifdef LTC_BASE16 | |
17 | ||
18 | /** | |
19 | Base16 encode a buffer | |
20 | @param in The input buffer to encode | |
21 | @param inlen The length of the input buffer | |
22 | @param out [out] The destination of the Base16 encoded data | |
23 | @param outlen [in/out] The max size and resulting size of the encoded data | |
24 | @param caps Output 'a-f' on 0 and 'A-F' otherwise. | |
25 | @return CRYPT_OK if successful | |
26 | */ | |
27 | int base16_encode(const unsigned char *in, unsigned long inlen, | |
28 | char *out, unsigned long *outlen, | |
29 | int caps) | |
30 | { | |
31 | unsigned long i, x; | |
32 | const char *alphabet; | |
33 | const char *alphabets[2] = { | |
34 | "0123456789abcdef", | |
35 | "0123456789ABCDEF", | |
36 | }; | |
37 | ||
38 | LTC_ARGCHK(in != NULL); | |
39 | LTC_ARGCHK(out != NULL); | |
40 | LTC_ARGCHK(outlen != NULL); | |
41 | ||
42 | /* check the sizes */ | |
43 | x = inlen * 2 + 1; | |
44 | ||
45 | if (x < inlen) return CRYPT_OVERFLOW; | |
46 | ||
47 | if (*outlen < x) { | |
48 | *outlen = x; | |
49 | return CRYPT_BUFFER_OVERFLOW; | |
50 | } | |
51 | *outlen = x; | |
52 | ||
53 | if (caps == 0) alphabet = alphabets[0]; | |
54 | else alphabet = alphabets[1]; | |
55 | ||
56 | x -= 1; | |
57 | for (i = 0; i < x; i += 2) { | |
58 | out[i] = alphabet[(in[i/2] >> 4) & 0x0f]; | |
59 | out[i+1] = alphabet[in[i/2] & 0x0f]; | |
60 | } | |
61 | out[x] = '\0'; | |
62 | ||
63 | return CRYPT_OK; | |
64 | } | |
65 | ||
66 | #endif | |
67 | ||
68 | /* ref: $Format:%D$ */ | |
69 | /* git commit: $Format:%H$ */ | |
70 | /* commit time: $Format:%ai$ */ |
19 | 19 | @param id Alphabet to use BASE32_RFC4648, BASE32_BASE32HEX, BASE32_ZBASE32 or BASE32_CROCKFORD |
20 | 20 | @return CRYPT_OK if successful |
21 | 21 | */ |
22 | int base32_decode(const unsigned char *in, unsigned long inlen, | |
22 | int base32_decode(const char *in, unsigned long inlen, | |
23 | 23 | unsigned char *out, unsigned long *outlen, |
24 | 24 | base32_alphabet id) |
25 | 25 | { |
26 | 26 | unsigned long x; |
27 | 27 | int y = 0; |
28 | 28 | ulong64 t = 0; |
29 | unsigned char c; | |
29 | char c; | |
30 | 30 | const unsigned char *map; |
31 | 31 | const unsigned char tables[4][43] = { |
32 | 32 | { /* id = BASE32_RFC4648 : ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 */ |
89 | 89 | c = in[x]; |
90 | 90 | /* convert to upper case */ |
91 | 91 | if ((c >= 'a') && (c <= 'z')) c -= 32; |
92 | /* '0' = 48 .. 'Z' = 90 */ | |
93 | if (c < 48 || c > 90 || map[c-48] > 31) { | |
92 | if (c < '0' || c > 'Z' || map[c-'0'] > 31) { | |
94 | 93 | return CRYPT_INVALID_PACKET; |
95 | 94 | } |
96 | t = (t<<5)|map[c-48]; | |
95 | t = (t<<5) | map[c-'0']; | |
97 | 96 | if (++y == 8) { |
98 | 97 | *out++ = (unsigned char)((t>>32) & 255); |
99 | 98 | *out++ = (unsigned char)((t>>24) & 255); |
20 | 20 | @return CRYPT_OK if successful |
21 | 21 | */ |
22 | 22 | int base32_encode(const unsigned char *in, unsigned long inlen, |
23 | unsigned char *out, unsigned long *outlen, | |
23 | char *out, unsigned long *outlen, | |
24 | 24 | base32_alphabet id) |
25 | 25 | { |
26 | 26 | unsigned long i, x; |
27 | unsigned char *codes; | |
27 | const char *codes; | |
28 | 28 | const char *alphabet[4] = { |
29 | 29 | "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", /* id = BASE32_RFC4648 */ |
30 | 30 | "0123456789ABCDEFGHIJKLMNOPQRSTUV", /* id = BASE32_BASE32HEX */ |
52 | 52 | } |
53 | 53 | *outlen = x; |
54 | 54 | |
55 | codes = (unsigned char*)alphabet[id]; | |
55 | codes = alphabet[id]; | |
56 | 56 | x = 5 * (inlen / 5); |
57 | 57 | for (i = 0; i < x; i += 5) { |
58 | 58 | *out++ = codes[(in[0] >> 3) & 0x1F]; |
16 | 16 | |
17 | 17 | #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) |
18 | 18 | |
19 | /* 253 - ignored in "relaxed" mode: TAB(9), CR(13), LF(10), space(32) | |
20 | * 254 - padding character '=' (allowed only at the end) | |
21 | * 255 - invalid character (not allowed even in relaxed mode) | |
22 | */ | |
23 | ||
19 | 24 | #if defined(LTC_BASE64) |
20 | 25 | static const unsigned char map_base64[256] = { |
21 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
22 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
23 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
26 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 255, | |
27 | 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
28 | 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, | |
24 | 29 | 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, |
25 | 30 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, |
26 | 31 | 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, |
44 | 49 | |
45 | 50 | static const unsigned char map_base64url[] = { |
46 | 51 | #if defined(LTC_BASE64_URL) |
47 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
48 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
49 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
52 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 255, | |
53 | 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, | |
54 | 255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, | |
50 | 55 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, |
51 | 56 | 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, |
52 | 57 | 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, |
88 | 93 | |
89 | 94 | g = 0; /* '=' counter */ |
90 | 95 | for (x = y = z = t = 0; x < inlen; x++) { |
96 | if (in[x] == 0 && x == (inlen - 1)) continue; /* allow the last byte to be NUL */ | |
91 | 97 | c = map[in[x]&0xFF]; |
92 | 98 | if (c == 254) { |
93 | 99 | g++; |
94 | 100 | continue; |
95 | 101 | } |
96 | else if (is_strict && g > 0) { | |
97 | /* we only allow '=' to be at the end */ | |
98 | return CRYPT_INVALID_PACKET; | |
99 | } | |
100 | if (c == 255) { | |
102 | if (c == 253) { | |
101 | 103 | if (is_strict) |
102 | 104 | return CRYPT_INVALID_PACKET; |
103 | 105 | else |
104 | 106 | continue; |
107 | } | |
108 | if (c == 255) { | |
109 | return CRYPT_INVALID_PACKET; | |
110 | } | |
111 | if (g > 0) { | |
112 | /* we only allow '=' to be at the end */ | |
113 | return CRYPT_INVALID_PACKET; | |
105 | 114 | } |
106 | 115 | |
107 | 116 | t = (t<<6)|c; |
413 | 413 | #if defined(LTC_BASE32) |
414 | 414 | " BASE32 " |
415 | 415 | #endif |
416 | #if defined(LTC_BASE16) | |
417 | " BASE16 " | |
418 | #endif | |
416 | 419 | #if defined(LTC_CRC32) |
417 | 420 | " CRC32 " |
418 | 421 | #endif |
424 | 427 | #endif |
425 | 428 | #if defined(LTC_PKCS_5) |
426 | 429 | " PKCS#5 " |
430 | #endif | |
431 | #if defined(LTC_PADDING) | |
432 | " PADDING " | |
427 | 433 | #endif |
428 | 434 | #if defined(LTC_HKDF) |
429 | 435 | " HKDF " |
74 | 74 | {"LTC_PKCS_1", 0}, |
75 | 75 | #endif |
76 | 76 | |
77 | #ifdef LTC_PADDING | |
78 | {"LTC_PADDING", 1}, | |
79 | ||
80 | _C_STRINGIFY(LTC_PAD_PKCS7), | |
81 | #ifdef LTC_RNG_GET_BYTES | |
82 | _C_STRINGIFY(LTC_PAD_ISO_10126), | |
83 | #endif | |
84 | _C_STRINGIFY(LTC_PAD_ANSI_X923), | |
85 | _C_STRINGIFY(LTC_PAD_ONE_AND_ZERO), | |
86 | _C_STRINGIFY(LTC_PAD_ZERO), | |
87 | _C_STRINGIFY(LTC_PAD_ZERO_ALWAYS), | |
88 | #else | |
89 | {"LTC_PADDING", 0}, | |
90 | #endif | |
91 | ||
77 | 92 | #ifdef LTC_MRSA |
78 | 93 | {"LTC_MRSA", 1}, |
79 | 94 | #else |
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 | #include "tomcrypt.h" | |
9 | ||
10 | #ifdef LTC_PADDING | |
11 | ||
12 | /** | |
13 | Remove padding from your data | |
14 | ||
15 | This depads your data. | |
16 | ||
17 | @param data The data to depad | |
18 | @param length [in/out] The size of the data before/after (removing padding) | |
19 | @param mode One of the LTC_PAD_xx flags | |
20 | @return CRYPT_OK on success | |
21 | */ | |
22 | int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode) | |
23 | { | |
24 | unsigned long padded_length, unpadded_length, n; | |
25 | unsigned char pad; | |
26 | enum padding_type type; | |
27 | ||
28 | LTC_ARGCHK(data != NULL); | |
29 | LTC_ARGCHK(length != NULL); | |
30 | ||
31 | padded_length = *length; | |
32 | ||
33 | type = mode & LTC_PAD_MASK; | |
34 | ||
35 | if (type < LTC_PAD_ONE_AND_ZERO) { | |
36 | pad = data[padded_length - 1]; | |
37 | ||
38 | if (pad > padded_length) return CRYPT_INVALID_ARG; | |
39 | ||
40 | unpadded_length = padded_length - pad; | |
41 | } else { | |
42 | /* init pad to calm old compilers */ | |
43 | pad = 0x0; | |
44 | unpadded_length = padded_length; | |
45 | } | |
46 | ||
47 | switch (type) { | |
48 | case LTC_PAD_ANSI_X923: | |
49 | pad = 0x0; | |
50 | /* FALLTHROUGH */ | |
51 | case LTC_PAD_PKCS7: | |
52 | for (n = unpadded_length; n < padded_length - 1; ++n) { | |
53 | if (data[n] != pad) return CRYPT_INVALID_PACKET; | |
54 | } | |
55 | break; | |
56 | #ifdef LTC_RNG_GET_BYTES | |
57 | case LTC_PAD_ISO_10126: | |
58 | /* nop */ | |
59 | break; | |
60 | #endif | |
61 | case LTC_PAD_ONE_AND_ZERO: | |
62 | while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) { | |
63 | if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET; | |
64 | unpadded_length--; | |
65 | } | |
66 | if (unpadded_length == 0) return CRYPT_INVALID_PACKET; | |
67 | unpadded_length--; | |
68 | if (data[unpadded_length] != 0x80) return CRYPT_INVALID_PACKET; | |
69 | break; | |
70 | case LTC_PAD_ZERO: | |
71 | case LTC_PAD_ZERO_ALWAYS: | |
72 | while (unpadded_length > 0 && data[unpadded_length - 1] == 0x0) { | |
73 | unpadded_length--; | |
74 | } | |
75 | if (type == LTC_PAD_ZERO_ALWAYS) { | |
76 | if (unpadded_length == padded_length) return CRYPT_INVALID_PACKET; | |
77 | if (data[unpadded_length] != 0x0) return CRYPT_INVALID_PACKET; | |
78 | } | |
79 | break; | |
80 | default: | |
81 | return CRYPT_INVALID_ARG; | |
82 | } | |
83 | ||
84 | *length = unpadded_length; | |
85 | ||
86 | return CRYPT_OK; | |
87 | } | |
88 | ||
89 | #endif | |
90 | ||
91 | /* ref: $Format:%D$ */ | |
92 | /* git commit: $Format:%H$ */ | |
93 | /* 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 | #include "tomcrypt.h" | |
9 | ||
10 | #ifdef LTC_PADDING | |
11 | ||
12 | /** | |
13 | Determine the to-be-padded length. | |
14 | ||
15 | @param length [in/out] The size of the data before/after padding | |
16 | @param mode Mask of (LTC_PAD_xxx | block_length) | |
17 | @return CRYPT_OK on success | |
18 | */ | |
19 | static int _padding_padded_length(unsigned long *length, unsigned long mode) | |
20 | { | |
21 | enum padding_type padding; | |
22 | unsigned char pad, block_length, r, t; | |
23 | ||
24 | LTC_ARGCHK(length != NULL); | |
25 | ||
26 | block_length = mode & 0xff; | |
27 | padding = mode & LTC_PAD_MASK; | |
28 | r = *length % block_length; | |
29 | ||
30 | switch (padding) { | |
31 | case LTC_PAD_ZERO: | |
32 | if (r == 0) { | |
33 | t = 0; | |
34 | break; | |
35 | } | |
36 | /* FALLTHROUGH */ | |
37 | case LTC_PAD_PKCS7: | |
38 | case LTC_PAD_ONE_AND_ZERO: | |
39 | case LTC_PAD_ZERO_ALWAYS: | |
40 | t = 1; | |
41 | break; | |
42 | #ifdef LTC_RNG_GET_BYTES | |
43 | case LTC_PAD_ISO_10126: | |
44 | do { | |
45 | if (rng_get_bytes(&t, sizeof(t), NULL) != sizeof(t)) { | |
46 | return CRYPT_ERROR_READPRNG; | |
47 | } | |
48 | t %= (256 / block_length); | |
49 | } while (t == 0); | |
50 | break; | |
51 | #endif | |
52 | case LTC_PAD_ANSI_X923: | |
53 | if (block_length != 16) { | |
54 | return CRYPT_INVALID_ARG; | |
55 | } | |
56 | t = 1; | |
57 | break; | |
58 | default: | |
59 | return CRYPT_INVALID_ARG; | |
60 | } | |
61 | ||
62 | pad = (t * block_length) - r; | |
63 | ||
64 | if ((pad == 0) && (padding != LTC_PAD_ZERO)) { | |
65 | pad = block_length; | |
66 | } | |
67 | ||
68 | *length += pad; | |
69 | ||
70 | return CRYPT_OK; | |
71 | } | |
72 | ||
73 | /** | |
74 | Add padding to data. | |
75 | ||
76 | This pads your data. | |
77 | ||
78 | @param data The data to depad | |
79 | @param length The size of the data before padding | |
80 | @param padded_length [in/out] The size of the data available/after padding | |
81 | @param mode One of the LTC_PAD_xx flags | |
82 | @return CRYPT_OK on success | |
83 | */ | |
84 | int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode) | |
85 | { | |
86 | unsigned long diff, l; | |
87 | enum padding_type type; | |
88 | int err; | |
89 | ||
90 | LTC_ARGCHK(data != NULL); | |
91 | LTC_ARGCHK(padded_length != NULL); | |
92 | ||
93 | l = length; | |
94 | if ((err = _padding_padded_length(&l, mode)) != CRYPT_OK) { | |
95 | return err; | |
96 | } | |
97 | ||
98 | type = mode & LTC_PAD_MASK; | |
99 | ||
100 | if (*padded_length < l) { | |
101 | if (type != LTC_PAD_ISO_10126) *padded_length = l; | |
102 | else *padded_length = length + 256; | |
103 | return CRYPT_BUFFER_OVERFLOW; | |
104 | } | |
105 | ||
106 | diff = l - length; | |
107 | if (diff > 255) return CRYPT_INVALID_ARG; | |
108 | ||
109 | switch (type) { | |
110 | case LTC_PAD_PKCS7: | |
111 | XMEMSET(&data[length], diff, diff); | |
112 | break; | |
113 | #ifdef LTC_RNG_GET_BYTES | |
114 | case LTC_PAD_ISO_10126: | |
115 | if (rng_get_bytes(&data[length], diff-1, NULL) != diff-1) { | |
116 | return CRYPT_ERROR_READPRNG; | |
117 | } | |
118 | data[l-1] = diff; | |
119 | break; | |
120 | #endif | |
121 | case LTC_PAD_ANSI_X923: | |
122 | XMEMSET(&data[length], 0, diff-1); | |
123 | data[l-1] = diff; | |
124 | break; | |
125 | case LTC_PAD_ONE_AND_ZERO: | |
126 | XMEMSET(&data[length + 1], 0, diff); | |
127 | data[length] = 0x80; | |
128 | break; | |
129 | case LTC_PAD_ZERO: | |
130 | case LTC_PAD_ZERO_ALWAYS: | |
131 | XMEMSET(&data[length], 0, diff); | |
132 | break; | |
133 | default: | |
134 | return CRYPT_INVALID_ARG; | |
135 | } | |
136 | *padded_length = l; | |
137 | ||
138 | return CRYPT_OK; | |
139 | } | |
140 | ||
141 | #endif | |
142 | ||
143 | /* ref: $Format:%D$ */ | |
144 | /* git commit: $Format:%H$ */ | |
145 | /* commit time: $Format:%ai$ */ |
92 | 92 | goto LBL_ERR; |
93 | 93 | } |
94 | 94 | if ((ident.type != root->type) || |
95 | (ident.class != root->class) || | |
95 | (ident.klass != root->klass) || | |
96 | 96 | (ident.pc != root->pc) || |
97 | 97 | (ident.tag != root->tag)) { |
98 | 98 | err = CRYPT_INVALID_PACKET; |
76 | 76 | } |
77 | 77 | |
78 | 78 | tag_len = 1; |
79 | id->class = (in[0] >> 6) & 0x3; | |
79 | id->klass = (in[0] >> 6) & 0x3; | |
80 | 80 | id->pc = (in[0] >> 5) & 0x1; |
81 | 81 | id->tag = in[0] & 0x1f; |
82 | 82 | |
104 | 104 | |
105 | 105 | if (err != CRYPT_OK) { |
106 | 106 | id->pc = 0; |
107 | id->class = 0; | |
107 | id->klass = 0; | |
108 | 108 | id->tag = 0; |
109 | 109 | } else { |
110 | 110 | *inlen = tag_len; |
111 | if ((id->class == LTC_ASN1_CL_UNIVERSAL) && | |
111 | if ((id->klass == LTC_ASN1_CL_UNIVERSAL) && | |
112 | 112 | (id->tag < der_asn1_tag_to_type_map_sz) && |
113 | 113 | (id->tag < tag_constructed_map_sz) && |
114 | 114 | (id->pc == tag_constructed_map[id->tag])) { |
115 | 115 | id->type = der_asn1_tag_to_type_map[id->tag]; |
116 | 116 | } else { |
117 | if ((id->class == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) { | |
117 | if ((id->klass == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) { | |
118 | 118 | id->type = LTC_ASN1_EOL; |
119 | 119 | } else { |
120 | 120 | id->type = LTC_ASN1_CUSTOM_TYPE; |
41 | 41 | *outlen = 1; |
42 | 42 | return CRYPT_OK; |
43 | 43 | } else { |
44 | if (id->class < LTC_ASN1_CL_UNIVERSAL || id->class > LTC_ASN1_CL_PRIVATE) { | |
44 | if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) { | |
45 | 45 | return CRYPT_INVALID_ARG; |
46 | 46 | } |
47 | 47 | if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { |
57 | 57 | return CRYPT_BUFFER_OVERFLOW; |
58 | 58 | } |
59 | 59 | |
60 | out[0] = id->class << 6 | id->pc << 5; | |
60 | out[0] = id->klass << 6 | id->pc << 5; | |
61 | 61 | } |
62 | 62 | |
63 | 63 | if (id->tag < 0x1f) { |
95 | 95 | } |
96 | 96 | data_offset = id_len + len_len; |
97 | 97 | #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 |
98 | if (l->type == LTC_ASN1_CUSTOM_TYPE && l->class == LTC_ASN1_CL_CONTEXT_SPECIFIC) { | |
98 | if (l->type == LTC_ASN1_CUSTOM_TYPE && l->klass == LTC_ASN1_CL_CONTEXT_SPECIFIC) { | |
99 | 99 | fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - Context Specific[%s %llu]\n", identifier, data_offset, len, der_asn1_pc_to_string_map[l->pc], l->tag); |
100 | 100 | } else { |
101 | 101 | fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]); |
38 | 38 | */ |
39 | 39 | int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, |
40 | 40 | unsigned int algorithm, void* public_key, unsigned long* public_key_len, |
41 | unsigned long parameters_type, void* parameters, unsigned long *parameters_len) | |
41 | ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len) | |
42 | 42 | { |
43 | 43 | int err; |
44 | unsigned long len; | |
44 | unsigned long len, alg_id_num; | |
45 | 45 | oid_st oid; |
46 | 46 | unsigned char *tmpbuf; |
47 | 47 | unsigned long tmpoid[16]; |
51 | 51 | LTC_ARGCHK(in != NULL); |
52 | 52 | LTC_ARGCHK(inlen != 0); |
53 | 53 | LTC_ARGCHK(public_key_len != NULL); |
54 | LTC_ARGCHK(parameters_len != NULL); | |
54 | if (parameters_type != LTC_ASN1_EOL) { | |
55 | LTC_ARGCHK(parameters_len != NULL); | |
56 | } | |
55 | 57 | |
56 | 58 | err = pk_get_oid(algorithm, &oid); |
57 | 59 | if (err != CRYPT_OK) { |
67 | 69 | |
68 | 70 | /* this includes the internal hash ID and optional params (NULL in this case) */ |
69 | 71 | LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); |
70 | LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, *parameters_len); | |
72 | if (parameters_type == LTC_ASN1_EOL) { | |
73 | alg_id_num = 1; | |
74 | } | |
75 | else { | |
76 | LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, *parameters_len); | |
77 | alg_id_num = 2; | |
78 | } | |
71 | 79 | |
72 | 80 | /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey |
73 | 81 | * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet |
74 | 82 | */ |
75 | LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); | |
83 | LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, alg_id_num); | |
76 | 84 | LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U); |
77 | 85 | |
78 | 86 | err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); |
79 | 87 | if (err != CRYPT_OK) { |
80 | 88 | goto LBL_ERR; |
81 | 89 | } |
82 | ||
83 | *parameters_len = alg_id[1].size; | |
90 | if (parameters_type != LTC_ASN1_EOL) { | |
91 | *parameters_len = alg_id[1].size; | |
92 | } | |
84 | 93 | |
85 | 94 | if ((alg_id[0].size != oid.OIDlen) || |
86 | 95 | XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { |
90 | 99 | } |
91 | 100 | |
92 | 101 | len = subject_pubkey[1].size/8; |
93 | if (*public_key_len > len) { | |
102 | if (*public_key_len >= len) { | |
94 | 103 | XMEMCPY(public_key, subject_pubkey[1].data, len); |
95 | 104 | *public_key_len = len; |
96 | 105 | } else { |
37 | 37 | @return CRYPT_OK on success |
38 | 38 | */ |
39 | 39 | int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, |
40 | unsigned int algorithm, void* public_key, unsigned long public_key_len, | |
41 | unsigned long parameters_type, void* parameters, unsigned long parameters_len) | |
40 | unsigned int algorithm, const void* public_key, unsigned long public_key_len, | |
41 | ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) | |
42 | 42 | { |
43 | 43 | int err; |
44 | 44 | ltc_asn1_list alg_id[2]; |
53 | 53 | } |
54 | 54 | |
55 | 55 | LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); |
56 | LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); | |
56 | LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); | |
57 | 57 | |
58 | 58 | return der_encode_sequence_multi(out, outlen, |
59 | 59 | LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, |
27 | 27 | |
28 | 28 | len_xy = sizeof(bin_xy); |
29 | 29 | len_oid = 16; |
30 | err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, &len_oid); | |
30 | err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); | |
31 | 31 | if (err == CRYPT_OK) { |
32 | 32 | /* load curve parameters for given curve OID */ |
33 | 33 | if ((err = ecc_set_dp_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } |
149 | 149 | @param prng The PRNG to export |
150 | 150 | @return CRYPT_OK if successful |
151 | 151 | */ |
152 | int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
153 | { | |
154 | unsigned long len = chacha20_prng_desc.export_size; | |
155 | ||
156 | LTC_ARGCHK(prng != NULL); | |
157 | LTC_ARGCHK(out != NULL); | |
158 | LTC_ARGCHK(outlen != NULL); | |
159 | ||
160 | if (*outlen < len) { | |
161 | *outlen = len; | |
162 | return CRYPT_BUFFER_OVERFLOW; | |
163 | } | |
164 | ||
165 | if (chacha20_prng_read(out, len, prng) != len) { | |
166 | return CRYPT_ERROR_READPRNG; | |
167 | } | |
168 | ||
169 | *outlen = len; | |
170 | return CRYPT_OK; | |
171 | } | |
152 | _LTC_PRNG_EXPORT(chacha20_prng) | |
172 | 153 | |
173 | 154 | /** |
174 | 155 | Import a PRNG state |
36 | 36 | |
37 | 37 | const struct ltc_prng_descriptor fortuna_desc = { |
38 | 38 | "fortuna", |
39 | (32 * LTC_FORTUNA_POOLS), /* default: 1024 */ | |
39 | 64, | |
40 | 40 | &fortuna_start, |
41 | 41 | &fortuna_add_entropy, |
42 | 42 | &fortuna_ready, |
65 | 65 | { |
66 | 66 | unsigned char tmp[MAXBLOCKSIZE]; |
67 | 67 | hash_state md; |
68 | ulong64 reset_cnt; | |
68 | 69 | int err, x; |
69 | 70 | |
70 | ++prng->fortuna.reset_cnt; | |
71 | 71 | |
72 | 72 | /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ |
73 | 73 | sha256_init(&md); |
76 | 76 | return err; |
77 | 77 | } |
78 | 78 | |
79 | reset_cnt = prng->fortuna.reset_cnt + 1; | |
80 | ||
79 | 81 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { |
80 | if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { | |
82 | if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) { | |
81 | 83 | /* terminate this hash */ |
82 | 84 | if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { |
83 | 85 | sha256_done(&md, tmp); |
107 | 109 | } |
108 | 110 | _fortuna_update_iv(prng); |
109 | 111 | |
110 | /* reset pool len */ | |
112 | /* reset/update internals */ | |
111 | 113 | prng->fortuna.pool0_len = 0; |
112 | 114 | prng->fortuna.wd = 0; |
115 | prng->fortuna.reset_cnt = reset_cnt; | |
113 | 116 | |
114 | 117 | |
115 | 118 | #ifdef LTC_CLEAN_STACK |
118 | 121 | #endif |
119 | 122 | |
120 | 123 | return CRYPT_OK; |
124 | } | |
125 | ||
126 | /** | |
127 | "Update Seed File"-compliant update of K | |
128 | ||
129 | @param in The PRNG state | |
130 | @param inlen Size of the state | |
131 | @param prng The PRNG to import | |
132 | @return CRYPT_OK if successful | |
133 | */ | |
134 | static int _fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng) | |
135 | { | |
136 | int err; | |
137 | unsigned char tmp[MAXBLOCKSIZE]; | |
138 | hash_state md; | |
139 | ||
140 | LTC_MUTEX_LOCK(&prng->lock); | |
141 | /* new K = LTC_SHA256(K || in) */ | |
142 | sha256_init(&md); | |
143 | if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { | |
144 | sha256_done(&md, tmp); | |
145 | goto LBL_UNLOCK; | |
146 | } | |
147 | if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) { | |
148 | sha256_done(&md, tmp); | |
149 | goto LBL_UNLOCK; | |
150 | } | |
151 | /* finish key */ | |
152 | if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { | |
153 | goto LBL_UNLOCK; | |
154 | } | |
155 | _fortuna_update_iv(prng); | |
156 | ||
157 | LBL_UNLOCK: | |
158 | LTC_MUTEX_UNLOCK(&prng->lock); | |
159 | #ifdef LTC_CLEAN_STACK | |
160 | zeromem(&md, sizeof(md)); | |
161 | #endif | |
162 | ||
163 | return err; | |
121 | 164 | } |
122 | 165 | |
123 | 166 | /** |
250 | 293 | } |
251 | 294 | } |
252 | 295 | |
296 | /* ensure that one reseed happened before allowing to read */ | |
297 | if (prng->fortuna.reset_cnt == 0) { | |
298 | goto LBL_UNLOCK; | |
299 | } | |
300 | ||
253 | 301 | /* now generate the blocks required */ |
254 | 302 | tlen = outlen; |
255 | 303 | |
328 | 376 | @param prng The PRNG to export |
329 | 377 | @return CRYPT_OK if successful |
330 | 378 | */ |
331 | int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
332 | { | |
333 | int x, err; | |
334 | hash_state *md; | |
335 | unsigned long len = fortuna_desc.export_size; | |
336 | ||
337 | LTC_ARGCHK(out != NULL); | |
338 | LTC_ARGCHK(outlen != NULL); | |
339 | LTC_ARGCHK(prng != NULL); | |
340 | ||
341 | LTC_MUTEX_LOCK(&prng->lock); | |
342 | ||
343 | if (!prng->ready) { | |
344 | err = CRYPT_ERROR; | |
345 | goto LBL_UNLOCK; | |
346 | } | |
347 | ||
348 | /* we'll write bytes for s&g's */ | |
349 | if (*outlen < len) { | |
350 | *outlen = len; | |
351 | err = CRYPT_BUFFER_OVERFLOW; | |
352 | goto LBL_UNLOCK; | |
353 | } | |
354 | ||
355 | md = XMALLOC(sizeof(hash_state)); | |
356 | if (md == NULL) { | |
357 | err = CRYPT_MEM; | |
358 | goto LBL_UNLOCK; | |
359 | } | |
360 | ||
361 | /* to emit the state we copy each pool, terminate it then hash it again so | |
362 | * an attacker who sees the state can't determine the current state of the PRNG | |
363 | */ | |
364 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { | |
365 | /* copy the PRNG */ | |
366 | XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); | |
367 | ||
368 | /* terminate it */ | |
369 | if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { | |
370 | goto LBL_ERR; | |
371 | } | |
372 | ||
373 | /* now hash it */ | |
374 | if ((err = sha256_init(md)) != CRYPT_OK) { | |
375 | goto LBL_ERR; | |
376 | } | |
377 | if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { | |
378 | goto LBL_ERR; | |
379 | } | |
380 | if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { | |
381 | goto LBL_ERR; | |
382 | } | |
383 | } | |
384 | *outlen = len; | |
385 | err = CRYPT_OK; | |
386 | ||
387 | LBL_ERR: | |
388 | #ifdef LTC_CLEAN_STACK | |
389 | zeromem(md, sizeof(*md)); | |
390 | #endif | |
391 | XFREE(md); | |
392 | LBL_UNLOCK: | |
393 | LTC_MUTEX_UNLOCK(&prng->lock); | |
394 | return err; | |
395 | } | |
379 | _LTC_PRNG_EXPORT(fortuna) | |
396 | 380 | |
397 | 381 | /** |
398 | 382 | Import a PRNG state |
403 | 387 | */ |
404 | 388 | int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) |
405 | 389 | { |
406 | int err, x; | |
407 | ||
408 | LTC_ARGCHK(in != NULL); | |
409 | LTC_ARGCHK(prng != NULL); | |
390 | int err; | |
391 | ||
392 | LTC_ARGCHK(in != NULL); | |
393 | LTC_ARGCHK(prng != NULL); | |
410 | 394 | |
411 | 395 | if (inlen < (unsigned long)fortuna_desc.export_size) { |
412 | 396 | return CRYPT_INVALID_ARG; |
415 | 399 | if ((err = fortuna_start(prng)) != CRYPT_OK) { |
416 | 400 | return err; |
417 | 401 | } |
418 | for (x = 0; x < LTC_FORTUNA_POOLS; x++) { | |
419 | if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { | |
420 | return err; | |
421 | } | |
422 | } | |
423 | return CRYPT_OK; | |
402 | ||
403 | if ((err = _fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) { | |
404 | return err; | |
405 | } | |
406 | ||
407 | return err; | |
424 | 408 | } |
425 | 409 | |
426 | 410 | /** |
152 | 152 | @param prng The PRNG to export |
153 | 153 | @return CRYPT_OK if successful |
154 | 154 | */ |
155 | int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
156 | { | |
157 | unsigned long len = rc4_desc.export_size; | |
158 | ||
159 | LTC_ARGCHK(prng != NULL); | |
160 | LTC_ARGCHK(out != NULL); | |
161 | LTC_ARGCHK(outlen != NULL); | |
162 | ||
163 | if (*outlen < len) { | |
164 | *outlen = len; | |
165 | return CRYPT_BUFFER_OVERFLOW; | |
166 | } | |
167 | ||
168 | if (rc4_read(out, len, prng) != len) { | |
169 | return CRYPT_ERROR_READPRNG; | |
170 | } | |
171 | ||
172 | *outlen = len; | |
173 | return CRYPT_OK; | |
174 | } | |
155 | _LTC_PRNG_EXPORT(rc4) | |
175 | 156 | |
176 | 157 | /** |
177 | 158 | Import a PRNG state |
15 | 15 | |
16 | 16 | /** |
17 | 17 | Create a PRNG from a RNG |
18 | @param bits Number of bits of entropy desired (64 ... 1024) | |
18 | ||
19 | In case you pass bits as '-1' the PRNG will be setup | |
20 | as if the export/import functionality has been used, | |
21 | but the imported data comes directly from the RNG. | |
22 | ||
23 | @param bits Number of bits of entropy desired (-1 or 64 ... 1024) | |
19 | 24 | @param wprng Index of which PRNG to setup |
20 | 25 | @param prng [out] PRNG state to initialize |
21 | 26 | @param callback A pointer to a void function for when the RNG is slow, this can be NULL |
24 | 29 | int rng_make_prng(int bits, int wprng, prng_state *prng, |
25 | 30 | void (*callback)(void)) |
26 | 31 | { |
27 | unsigned char buf[256]; | |
32 | unsigned char* buf; | |
33 | unsigned long bytes; | |
28 | 34 | int err; |
29 | 35 | |
30 | 36 | LTC_ARGCHK(prng != NULL); |
34 | 40 | return err; |
35 | 41 | } |
36 | 42 | |
37 | if (bits < 64 || bits > 1024) { | |
43 | if (bits == -1) { | |
44 | bytes = prng_descriptor[wprng].export_size; | |
45 | } else if (bits < 64 || bits > 1024) { | |
38 | 46 | return CRYPT_INVALID_PRNGSIZE; |
47 | } else { | |
48 | bytes = (unsigned long)((bits+7)/8) * 2; | |
39 | 49 | } |
40 | 50 | |
41 | 51 | if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { |
42 | 52 | return err; |
43 | 53 | } |
44 | 54 | |
45 | bits = ((bits+7)/8) * 2; | |
46 | if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { | |
47 | return CRYPT_ERROR_READPRNG; | |
55 | buf = XMALLOC(bytes); | |
56 | if (buf == NULL) { | |
57 | return CRYPT_MEM; | |
48 | 58 | } |
49 | 59 | |
50 | if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { | |
51 | return err; | |
60 | if (rng_get_bytes(buf, bytes, callback) != bytes) { | |
61 | err = CRYPT_ERROR_READPRNG; | |
62 | goto LBL_ERR; | |
52 | 63 | } |
53 | 64 | |
65 | if (bits == -1) { | |
66 | if ((err = prng_descriptor[wprng].pimport(buf, bytes, prng)) != CRYPT_OK) { | |
67 | goto LBL_ERR; | |
68 | } | |
69 | } else { | |
70 | if ((err = prng_descriptor[wprng].add_entropy(buf, bytes, prng)) != CRYPT_OK) { | |
71 | goto LBL_ERR; | |
72 | } | |
73 | } | |
54 | 74 | if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { |
55 | return err; | |
75 | goto LBL_ERR; | |
56 | 76 | } |
57 | 77 | |
78 | LBL_ERR: | |
58 | 79 | #ifdef LTC_CLEAN_STACK |
59 | zeromem(buf, sizeof(buf)); | |
80 | zeromem(buf, bytes); | |
60 | 81 | #endif |
61 | return CRYPT_OK; | |
82 | XFREE(buf); | |
83 | return err; | |
62 | 84 | } |
63 | 85 | #endif /* #ifdef LTC_RNG_MAKE_PRNG */ |
64 | 86 |
151 | 151 | @param prng The PRNG to export |
152 | 152 | @return CRYPT_OK if successful |
153 | 153 | */ |
154 | int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
155 | { | |
156 | unsigned long len = sober128_desc.export_size; | |
157 | ||
158 | LTC_ARGCHK(prng != NULL); | |
159 | LTC_ARGCHK(out != NULL); | |
160 | LTC_ARGCHK(outlen != NULL); | |
161 | ||
162 | if (*outlen < len) { | |
163 | *outlen = len; | |
164 | return CRYPT_BUFFER_OVERFLOW; | |
165 | } | |
166 | ||
167 | if (sober128_read(out, len, prng) != len) { | |
168 | return CRYPT_ERROR_READPRNG; | |
169 | } | |
170 | ||
171 | *outlen = len; | |
172 | return CRYPT_OK; | |
173 | } | |
154 | _LTC_PRNG_EXPORT(sober128) | |
174 | 155 | |
175 | 156 | /** |
176 | 157 | Import a PRNG state |
188 | 169 | if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG; |
189 | 170 | |
190 | 171 | if ((err = sober128_start(prng)) != CRYPT_OK) return err; |
191 | if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err; | |
172 | if ((err = sober128_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; | |
192 | 173 | return CRYPT_OK; |
193 | 174 | } |
194 | 175 |
272 | 272 | @param prng The PRNG to export |
273 | 273 | @return CRYPT_OK if successful |
274 | 274 | */ |
275 | int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) | |
276 | { | |
277 | unsigned long len = yarrow_desc.export_size; | |
278 | ||
279 | LTC_ARGCHK(out != NULL); | |
280 | LTC_ARGCHK(outlen != NULL); | |
281 | LTC_ARGCHK(prng != NULL); | |
282 | ||
283 | if (*outlen < len) { | |
284 | *outlen = len; | |
285 | return CRYPT_BUFFER_OVERFLOW; | |
286 | } | |
287 | ||
288 | if (yarrow_read(out, len, prng) != len) { | |
289 | return CRYPT_ERROR_READPRNG; | |
290 | } | |
291 | ||
292 | *outlen = len; | |
293 | return CRYPT_OK; | |
294 | } | |
275 | _LTC_PRNG_EXPORT(yarrow) | |
295 | 276 | |
296 | 277 | /** |
297 | 278 | Import a PRNG state |