diff options
author | Karel Miko <karel.miko@gmail.com> | 2018-03-25 18:17:57 +0200 |
---|---|---|
committer | Karel Miko <karel.miko@gmail.com> | 2018-03-25 18:17:57 +0200 |
commit | 5fd7132958e36a4a3c259cd44ee278349e522ef2 (patch) | |
tree | 993a3a732f19d8915e7e440fddb973b31b15ffbb | |
parent | e8a8ed0e6467701e2e2737fa23c99724c8370036 (diff) |
ltc update
29 files changed, 691 insertions, 278 deletions
@@ -584,7 +584,8 @@ encode_b32r(SV *in) { STRLEN in_len; unsigned long out_len; - unsigned char *out_data, *in_data; + unsigned char *in_data; + char *out_data; int id = -1; if (!SvPOK(in)) XSRETURN_UNDEF; @@ -601,7 +602,7 @@ encode_b32r(SV *in) out_len = (unsigned long)((8 * in_len + 4) / 5); RETVAL = NEWSV(0, out_len); /* avoid zero! */ SvPOK_only(RETVAL); - out_data = (unsigned char *)SvPVX(RETVAL); + out_data = SvPVX(RETVAL); if (base32_encode(in_data, (unsigned long)in_len, out_data, &out_len, id) != CRYPT_OK) { SvREFCNT_dec(RETVAL); XSRETURN_UNDEF; @@ -622,7 +623,8 @@ decode_b32r(SV *in) { STRLEN in_len; unsigned long out_len; - unsigned char *out_data, *in_data; + unsigned char *out_data; + char *in_data; int id = -1; if (!SvPOK(in)) XSRETURN_UNDEF; @@ -631,7 +633,7 @@ decode_b32r(SV *in) if (ix == 2) id = BASE32_ZBASE32; if (ix == 3) id = BASE32_CROCKFORD; if (id == -1) XSRETURN_UNDEF; - in_data = (unsigned char *)SvPVbyte(in, in_len); + in_data = SvPVbyte(in, in_len); if (in_len == 0) { RETVAL = newSVpvn("", 0); } diff --git a/src/Makefile b/src/Makefile index 6775fa91..8c198faf 100644 --- a/src/Makefile +++ b/src/Makefile @@ -42,20 +42,22 @@ ltc/mac/xcbc/xcbc_process.o ltc/math/ltm_desc.o ltc/math/multi.o ltc/math/radix_ ltc/math/rand_bn.o ltc/math/rand_prime.o ltc/math/tfm_desc.o ltc/math/fp/ltc_ecc_fp_mulmod.o \ ltc/misc/adler32.o ltc/misc/burn_stack.o ltc/misc/compare_testvector.o ltc/misc/copy_or_zeromem.o \ ltc/misc/crc32.o ltc/misc/error_to_string.o ltc/misc/mem_neq.o ltc/misc/pk_get_oid.o \ -ltc/misc/zeromem.o ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o \ -ltc/misc/base64/base64_decode.o ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o \ -ltc/misc/crypt/crypt_argchk.o ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o \ -ltc/misc/crypt/crypt_constants.o ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o \ -ltc/misc/crypt/crypt_find_cipher_id.o ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o \ -ltc/misc/crypt/crypt_find_hash_id.o ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o \ -ltc/misc/crypt/crypt_fsa.o ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o \ -ltc/misc/crypt/crypt_inits.o ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o \ -ltc/misc/crypt/crypt_prng_is_valid.o ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \ +ltc/misc/zeromem.o ltc/misc/base16/base16_decode.o ltc/misc/base16/base16_encode.o \ +ltc/misc/base32/base32_decode.o ltc/misc/base32/base32_encode.o ltc/misc/base64/base64_decode.o \ +ltc/misc/base64/base64_encode.o ltc/misc/crypt/crypt.o ltc/misc/crypt/crypt_argchk.o \ +ltc/misc/crypt/crypt_cipher_descriptor.o ltc/misc/crypt/crypt_cipher_is_valid.o ltc/misc/crypt/crypt_constants.o \ +ltc/misc/crypt/crypt_find_cipher.o ltc/misc/crypt/crypt_find_cipher_any.o ltc/misc/crypt/crypt_find_cipher_id.o \ +ltc/misc/crypt/crypt_find_hash.o ltc/misc/crypt/crypt_find_hash_any.o ltc/misc/crypt/crypt_find_hash_id.o \ +ltc/misc/crypt/crypt_find_hash_oid.o ltc/misc/crypt/crypt_find_prng.o ltc/misc/crypt/crypt_fsa.o \ +ltc/misc/crypt/crypt_hash_descriptor.o ltc/misc/crypt/crypt_hash_is_valid.o ltc/misc/crypt/crypt_inits.o \ +ltc/misc/crypt/crypt_ltc_mp_descriptor.o ltc/misc/crypt/crypt_prng_descriptor.o ltc/misc/crypt/crypt_prng_is_valid.o \ +ltc/misc/crypt/crypt_prng_rng_descriptor.o ltc/misc/crypt/crypt_register_all_ciphers.o \ ltc/misc/crypt/crypt_register_all_hashes.o ltc/misc/crypt/crypt_register_all_prngs.o \ ltc/misc/crypt/crypt_register_cipher.o ltc/misc/crypt/crypt_register_hash.o ltc/misc/crypt/crypt_register_prng.o \ ltc/misc/crypt/crypt_sizes.o ltc/misc/crypt/crypt_unregister_cipher.o ltc/misc/crypt/crypt_unregister_hash.o \ -ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/pkcs5/pkcs_5_1.o \ -ltc/misc/pkcs5/pkcs_5_2.o ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ +ltc/misc/crypt/crypt_unregister_prng.o ltc/misc/hkdf/hkdf.o ltc/misc/padding/padding_depad.o \ +ltc/misc/padding/padding_pad.o ltc/misc/pkcs5/pkcs_5_1.o ltc/misc/pkcs5/pkcs_5_2.o \ +ltc/modes/cbc/cbc_decrypt.o ltc/modes/cbc/cbc_done.o ltc/modes/cbc/cbc_encrypt.o \ ltc/modes/cbc/cbc_getiv.o ltc/modes/cbc/cbc_setiv.o ltc/modes/cbc/cbc_start.o ltc/modes/cfb/cfb_decrypt.o \ ltc/modes/cfb/cfb_done.o ltc/modes/cfb/cfb_encrypt.o ltc/modes/cfb/cfb_getiv.o ltc/modes/cfb/cfb_setiv.o \ ltc/modes/cfb/cfb_start.o ltc/modes/ctr/ctr_decrypt.o ltc/modes/ctr/ctr_done.o ltc/modes/ctr/ctr_encrypt.o \ diff --git a/src/Makefile.nmake b/src/Makefile.nmake index 3bef06ea..04fe3434 100644 --- a/src/Makefile.nmake +++ b/src/Makefile.nmake @@ -45,9 +45,10 @@ ltc/mac/xcbc/xcbc_process.obj ltc/math/ltm_desc.obj ltc/math/multi.obj ltc/math/ ltc/math/rand_bn.obj ltc/math/rand_prime.obj ltc/math/tfm_desc.obj ltc/math/fp/ltc_ecc_fp_mulmod.obj \ ltc/misc/adler32.obj ltc/misc/burn_stack.obj ltc/misc/compare_testvector.obj ltc/misc/copy_or_zeromem.obj \ ltc/misc/crc32.obj ltc/misc/error_to_string.obj ltc/misc/mem_neq.obj ltc/misc/pk_get_oid.obj \ -ltc/misc/zeromem.obj ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj \ -ltc/misc/base64/base64_decode.obj ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj \ -ltc/misc/crypt/crypt_argchk.obj ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ +ltc/misc/zeromem.obj ltc/misc/base16/base16_decode.obj ltc/misc/base16/base16_encode.obj \ +ltc/misc/base32/base32_decode.obj ltc/misc/base32/base32_encode.obj ltc/misc/base64/base64_decode.obj \ +ltc/misc/base64/base64_encode.obj ltc/misc/crypt/crypt.obj ltc/misc/crypt/crypt_argchk.obj \ +ltc/misc/crypt/crypt_cipher_descriptor.obj ltc/misc/crypt/crypt_cipher_is_valid.obj \ ltc/misc/crypt/crypt_constants.obj ltc/misc/crypt/crypt_find_cipher.obj ltc/misc/crypt/crypt_find_cipher_any.obj \ ltc/misc/crypt/crypt_find_cipher_id.obj ltc/misc/crypt/crypt_find_hash.obj ltc/misc/crypt/crypt_find_hash_any.obj \ ltc/misc/crypt/crypt_find_hash_id.obj ltc/misc/crypt/crypt_find_hash_oid.obj ltc/misc/crypt/crypt_find_prng.obj \ @@ -58,40 +59,41 @@ ltc/misc/crypt/crypt_register_all_ciphers.obj ltc/misc/crypt/crypt_register_all_ ltc/misc/crypt/crypt_register_all_prngs.obj ltc/misc/crypt/crypt_register_cipher.obj \ ltc/misc/crypt/crypt_register_hash.obj ltc/misc/crypt/crypt_register_prng.obj ltc/misc/crypt/crypt_sizes.obj \ ltc/misc/crypt/crypt_unregister_cipher.obj ltc/misc/crypt/crypt_unregister_hash.obj \ -ltc/misc/crypt/crypt_unregister_prng.obj ltc/misc/hkdf/hkdf.obj ltc/misc/pkcs5/pkcs_5_1.obj \ -ltc/misc/pkcs5/pkcs_5_2.obj ltc/modes/cbc/cbc_decrypt.obj ltc/modes/cbc/cbc_done.obj \ -ltc/modes/cbc/cbc_encrypt.obj ltc/modes/cbc/cbc_getiv.obj ltc/modes/cbc/cbc_setiv.obj \ -ltc/modes/cbc/cbc_start.obj ltc/modes/cfb/cfb_decrypt.obj ltc/modes/cfb/cfb_done.obj \ -ltc/modes/cfb/cfb_encrypt.obj ltc/modes/cfb/cfb_getiv.obj ltc/modes/cfb/cfb_setiv.obj \ -ltc/modes/cfb/cfb_start.obj ltc/modes/ctr/ctr_decrypt.obj ltc/modes/ctr/ctr_done.obj \ -ltc/modes/ctr/ctr_encrypt.obj ltc/modes/ctr/ctr_getiv.obj ltc/modes/ctr/ctr_setiv.obj \ -ltc/modes/ctr/ctr_start.obj ltc/modes/ecb/ecb_decrypt.obj ltc/modes/ecb/ecb_done.obj \ -ltc/modes/ecb/ecb_encrypt.obj ltc/modes/ecb/ecb_start.obj ltc/modes/ofb/ofb_decrypt.obj \ -ltc/modes/ofb/ofb_done.obj ltc/modes/ofb/ofb_encrypt.obj ltc/modes/ofb/ofb_getiv.obj \ -ltc/modes/ofb/ofb_setiv.obj ltc/modes/ofb/ofb_start.obj ltc/pk/asn1/der/bit/der_decode_bit_string.obj \ -ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_encode_bit_string.obj \ -ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj ltc/pk/asn1/der/bit/der_length_bit_string.obj \ -ltc/pk/asn1/der/boolean/der_decode_boolean.obj ltc/pk/asn1/der/boolean/der_encode_boolean.obj \ -ltc/pk/asn1/der/boolean/der_length_boolean.obj ltc/pk/asn1/der/choice/der_decode_choice.obj \ -ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj \ -ltc/pk/asn1/der/custom_type/der_length_custom_type.obj ltc/pk/asn1/der/general/der_asn1_maps.obj \ -ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj ltc/pk/asn1/der/general/der_decode_asn1_length.obj \ -ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj ltc/pk/asn1/der/general/der_encode_asn1_length.obj \ -ltc/pk/asn1/der/general/der_length_asn1_identifier.obj ltc/pk/asn1/der/general/der_length_asn1_length.obj \ -ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj \ -ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj \ -ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj ltc/pk/asn1/der/ia5/der_length_ia5_string.obj \ -ltc/pk/asn1/der/integer/der_decode_integer.obj ltc/pk/asn1/der/integer/der_encode_integer.obj \ -ltc/pk/asn1/der/integer/der_length_integer.obj ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj \ -ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj \ -ltc/pk/asn1/der/octet/der_decode_octet_string.obj ltc/pk/asn1/der/octet/der_encode_octet_string.obj \ -ltc/pk/asn1/der/octet/der_length_octet_string.obj ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj \ -ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj ltc/pk/asn1/der/printable_string/der_length_printable_string.obj \ -ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj \ -ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj \ -ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj ltc/pk/asn1/der/sequence/der_length_sequence.obj \ -ltc/pk/asn1/der/sequence/der_sequence_free.obj ltc/pk/asn1/der/sequence/der_sequence_shrink.obj \ -ltc/pk/asn1/der/set/der_encode_set.obj ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ +ltc/misc/crypt/crypt_unregister_prng.obj ltc/misc/hkdf/hkdf.obj ltc/misc/padding/padding_depad.obj \ +ltc/misc/padding/padding_pad.obj ltc/misc/pkcs5/pkcs_5_1.obj ltc/misc/pkcs5/pkcs_5_2.obj \ +ltc/modes/cbc/cbc_decrypt.obj ltc/modes/cbc/cbc_done.obj ltc/modes/cbc/cbc_encrypt.obj \ +ltc/modes/cbc/cbc_getiv.obj ltc/modes/cbc/cbc_setiv.obj ltc/modes/cbc/cbc_start.obj \ +ltc/modes/cfb/cfb_decrypt.obj ltc/modes/cfb/cfb_done.obj ltc/modes/cfb/cfb_encrypt.obj \ +ltc/modes/cfb/cfb_getiv.obj ltc/modes/cfb/cfb_setiv.obj ltc/modes/cfb/cfb_start.obj \ +ltc/modes/ctr/ctr_decrypt.obj ltc/modes/ctr/ctr_done.obj ltc/modes/ctr/ctr_encrypt.obj \ +ltc/modes/ctr/ctr_getiv.obj ltc/modes/ctr/ctr_setiv.obj ltc/modes/ctr/ctr_start.obj \ +ltc/modes/ecb/ecb_decrypt.obj ltc/modes/ecb/ecb_done.obj ltc/modes/ecb/ecb_encrypt.obj \ +ltc/modes/ecb/ecb_start.obj ltc/modes/ofb/ofb_decrypt.obj ltc/modes/ofb/ofb_done.obj \ +ltc/modes/ofb/ofb_encrypt.obj ltc/modes/ofb/ofb_getiv.obj ltc/modes/ofb/ofb_setiv.obj \ +ltc/modes/ofb/ofb_start.obj ltc/pk/asn1/der/bit/der_decode_bit_string.obj ltc/pk/asn1/der/bit/der_decode_raw_bit_string.obj \ +ltc/pk/asn1/der/bit/der_encode_bit_string.obj ltc/pk/asn1/der/bit/der_encode_raw_bit_string.obj \ +ltc/pk/asn1/der/bit/der_length_bit_string.obj ltc/pk/asn1/der/boolean/der_decode_boolean.obj \ +ltc/pk/asn1/der/boolean/der_encode_boolean.obj ltc/pk/asn1/der/boolean/der_length_boolean.obj \ +ltc/pk/asn1/der/choice/der_decode_choice.obj ltc/pk/asn1/der/custom_type/der_decode_custom_type.obj \ +ltc/pk/asn1/der/custom_type/der_encode_custom_type.obj ltc/pk/asn1/der/custom_type/der_length_custom_type.obj \ +ltc/pk/asn1/der/general/der_asn1_maps.obj ltc/pk/asn1/der/general/der_decode_asn1_identifier.obj \ +ltc/pk/asn1/der/general/der_decode_asn1_length.obj ltc/pk/asn1/der/general/der_encode_asn1_identifier.obj \ +ltc/pk/asn1/der/general/der_encode_asn1_length.obj ltc/pk/asn1/der/general/der_length_asn1_identifier.obj \ +ltc/pk/asn1/der/general/der_length_asn1_length.obj ltc/pk/asn1/der/generalizedtime/der_decode_generalizedtime.obj \ +ltc/pk/asn1/der/generalizedtime/der_encode_generalizedtime.obj ltc/pk/asn1/der/generalizedtime/der_length_generalizedtime.obj \ +ltc/pk/asn1/der/ia5/der_decode_ia5_string.obj ltc/pk/asn1/der/ia5/der_encode_ia5_string.obj \ +ltc/pk/asn1/der/ia5/der_length_ia5_string.obj ltc/pk/asn1/der/integer/der_decode_integer.obj \ +ltc/pk/asn1/der/integer/der_encode_integer.obj ltc/pk/asn1/der/integer/der_length_integer.obj \ +ltc/pk/asn1/der/object_identifier/der_decode_object_identifier.obj ltc/pk/asn1/der/object_identifier/der_encode_object_identifier.obj \ +ltc/pk/asn1/der/object_identifier/der_length_object_identifier.obj ltc/pk/asn1/der/octet/der_decode_octet_string.obj \ +ltc/pk/asn1/der/octet/der_encode_octet_string.obj ltc/pk/asn1/der/octet/der_length_octet_string.obj \ +ltc/pk/asn1/der/printable_string/der_decode_printable_string.obj ltc/pk/asn1/der/printable_string/der_encode_printable_string.obj \ +ltc/pk/asn1/der/printable_string/der_length_printable_string.obj ltc/pk/asn1/der/sequence/der_decode_sequence_ex.obj \ +ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.obj ltc/pk/asn1/der/sequence/der_decode_sequence_multi.obj \ +ltc/pk/asn1/der/sequence/der_encode_sequence_ex.obj ltc/pk/asn1/der/sequence/der_encode_sequence_multi.obj \ +ltc/pk/asn1/der/sequence/der_length_sequence.obj ltc/pk/asn1/der/sequence/der_sequence_free.obj \ +ltc/pk/asn1/der/sequence/der_sequence_shrink.obj ltc/pk/asn1/der/set/der_encode_set.obj \ +ltc/pk/asn1/der/set/der_encode_setof.obj ltc/pk/asn1/der/short_integer/der_decode_short_integer.obj \ ltc/pk/asn1/der/short_integer/der_encode_short_integer.obj ltc/pk/asn1/der/short_integer/der_length_short_integer.obj \ ltc/pk/asn1/der/teletex_string/der_decode_teletex_string.obj ltc/pk/asn1/der/teletex_string/der_length_teletex_string.obj \ ltc/pk/asn1/der/utctime/der_decode_utctime.obj ltc/pk/asn1/der/utctime/der_encode_utctime.obj \ diff --git a/src/ltc/headers/tomcrypt_custom.h b/src/ltc/headers/tomcrypt_custom.h index c4af2165..550b1782 100644 --- a/src/ltc/headers/tomcrypt_custom.h +++ b/src/ltc/headers/tomcrypt_custom.h @@ -450,6 +450,8 @@ #define LTC_BASE64_URL /* Base32 encoding/decoding */ #define LTC_BASE32 +/* Base16/hex encoding/decoding */ +#define LTC_BASE16 /* Keep LTC_NO_HKDF for compatibility reasons * superseeded by LTC_NO_MISC*/ @@ -462,6 +464,8 @@ #define LTC_CRC32 +#define LTC_PADDING + #endif /* LTC_NO_MISC */ /* cleanup */ diff --git a/src/ltc/headers/tomcrypt_misc.h b/src/ltc/headers/tomcrypt_misc.h index 63fc3a89..865f2ddd 100644 --- a/src/ltc/headers/tomcrypt_misc.h +++ b/src/ltc/headers/tomcrypt_misc.h @@ -39,13 +39,22 @@ typedef enum { BASE32_CROCKFORD = 3 } base32_alphabet; int base32_encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, + char *out, unsigned long *outlen, base32_alphabet id); -int base32_decode(const unsigned char *in, unsigned long inlen, +int base32_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, base32_alphabet id); #endif +/* ---- BASE16 Routines ---- */ +#ifdef LTC_BASE16 +int base16_encode(const unsigned char *in, unsigned long inlen, + char *out, unsigned long *outlen, + int caps); +int base16_decode(const char *in, + unsigned char *out, unsigned long *outlen); +#endif + /* ===> LTC_HKDF -- RFC5869 HMAC-based Key Derivation Function <=== */ #ifdef LTC_HKDF @@ -126,6 +135,29 @@ void crc32_finish(crc32_state *ctx, void *hash, unsigned long size); int crc32_test(void); #endif + +#ifdef LTC_PADDING + +enum padding_type { + LTC_PAD_PKCS7 = 0x0000U, +#ifdef LTC_RNG_GET_BYTES + LTC_PAD_ISO_10126 = 0x1000U, +#endif + LTC_PAD_ANSI_X923 = 0x2000U, + LTC_PAD_ONE_AND_ZERO = 0x8000U, + LTC_PAD_ZERO = 0x9000U, + LTC_PAD_ZERO_ALWAYS = 0xA000U, +}; + +int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode); +int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode); + +#ifdef LTC_SOURCE +/* internal helper functions */ +#define LTC_PAD_MASK (0xF000U) +#endif +#endif /* LTC_PADDING */ + int compare_testvector(const void* is, const unsigned long is_len, const void* should, const unsigned long should_len, const char* what, int which); /* ref: $Format:%D$ */ diff --git a/src/ltc/headers/tomcrypt_pk.h b/src/ltc/headers/tomcrypt_pk.h index ac4353ca..3f685d72 100644 --- a/src/ltc/headers/tomcrypt_pk.h +++ b/src/ltc/headers/tomcrypt_pk.h @@ -9,18 +9,20 @@ /* ---- NUMBER THEORY ---- */ -enum { - PK_PUBLIC=0, - PK_PRIVATE=1 +enum public_key_type { + /* Refers to the public key */ + PK_PUBLIC = 0x0000, + /* Refers to the private key */ + PK_PRIVATE = 0x0001, + + /* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ + PK_STD = 0x1000, + /* Indicates compressed public ECC key */ + PK_COMPRESSED = 0x2000, + /* Indicates ECC key with the curve specified by OID */ + PK_CURVEOID = 0x4000 }; -/* Indicates standard output formats that can be read e.g. by OpenSSL or GnuTLS */ -#define PK_STD 0x1000 -/* Indicates compressed public ECC key */ -#define PK_COMPRESSED 0x2000 -/* Indicates ECC key with the curve specified by OID */ -#define PK_CURVEOID 0x4000 - int rand_prime(void *N, long len, prng_state *prng, int wprng); #ifdef LTC_SOURCE @@ -605,7 +607,7 @@ typedef struct ltc_asn1_list_ { /** Flag used to indicate optional items in ASN.1 sequences */ int optional; /** ASN.1 identifier */ - ltc_asn1_class class; + ltc_asn1_class klass; ltc_asn1_pc pc; ulong64 tag; /** prev/next entry in the list */ @@ -621,7 +623,7 @@ typedef struct ltc_asn1_list_ { LTC_MACRO_list[LTC_MACRO_temp].size = (Size); \ LTC_MACRO_list[LTC_MACRO_temp].used = 0; \ LTC_MACRO_list[LTC_MACRO_temp].optional = 0; \ - LTC_MACRO_list[LTC_MACRO_temp].class = 0; \ + LTC_MACRO_list[LTC_MACRO_temp].klass = 0; \ LTC_MACRO_list[LTC_MACRO_temp].pc = 0; \ LTC_MACRO_list[LTC_MACRO_temp].tag = 0; \ } while (0) @@ -631,7 +633,7 @@ typedef struct ltc_asn1_list_ { int LTC_MACRO_temp = (index); \ ltc_asn1_list *LTC_MACRO_list = (list); \ LTC_MACRO_list[LTC_MACRO_temp].type = LTC_ASN1_CUSTOM_TYPE; \ - LTC_MACRO_list[LTC_MACRO_temp].class = (Class); \ + LTC_MACRO_list[LTC_MACRO_temp].klass = (Class); \ LTC_MACRO_list[LTC_MACRO_temp].pc = (Pc); \ LTC_MACRO_list[LTC_MACRO_temp].tag = (Tag); \ } while (0) @@ -907,12 +909,12 @@ int der_length_generalizedtime(ltc_generalizedtime *gtime, unsigned long *outlen /* internal helper functions */ /* SUBJECT PUBLIC KEY INFO */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, - unsigned int algorithm, void* public_key, unsigned long public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len); + unsigned int algorithm, const void* public_key, unsigned long public_key_len, + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len); int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long *parameters_len); + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len); #endif /* LTC_SOURCE */ #endif diff --git a/src/ltc/headers/tomcrypt_prng.h b/src/ltc/headers/tomcrypt_prng.h index c516b8cd..2f45522d 100644 --- a/src/ltc/headers/tomcrypt_prng.h +++ b/src/ltc/headers/tomcrypt_prng.h @@ -212,6 +212,31 @@ int register_all_prngs(void); int prng_is_valid(int idx); LTC_MUTEX_PROTO(ltc_prng_mutex) +#ifdef LTC_SOURCE +/* internal helper functions */ +#define _LTC_PRNG_EXPORT(which) \ +int which ## _export(unsigned char *out, unsigned long *outlen, prng_state *prng) \ +{ \ + unsigned long len = which ## _desc.export_size; \ + \ + LTC_ARGCHK(prng != NULL); \ + LTC_ARGCHK(out != NULL); \ + LTC_ARGCHK(outlen != NULL); \ + \ + if (*outlen < len) { \ + *outlen = len; \ + return CRYPT_BUFFER_OVERFLOW; \ + } \ + \ + if (which ## _read(out, len, prng) != len) { \ + return CRYPT_ERROR_READPRNG; \ + } \ + \ + *outlen = len; \ + return CRYPT_OK; \ +} +#endif + /* Slow RNG you **might** be able to use to seed a PRNG with. Be careful as this * might not work on all platforms as planned */ diff --git a/src/ltc/misc/base16/base16_decode.c b/src/ltc/misc/base16/base16_decode.c new file mode 100644 index 00000000..5743be9e --- /dev/null +++ b/src/ltc/misc/base16/base16_decode.c @@ -0,0 +1,65 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt.h" + +/** + @file base16_decode.c + Base16/Hex decode a string. + Based on https://stackoverflow.com/a/23898449 + Adapted for libtomcrypt by Steffen Jaeckel +*/ + +#ifdef LTC_BASE16 + +/** + Base16 decode a string + @param in The Base16 string to decode + @param out [out] The destination of the binary decoded data + @param outlen [in/out] The max size and resulting size of the decoded data + @return CRYPT_OK if successful +*/ +int base16_decode(const char *in, + unsigned char *out, unsigned long *outlen) +{ + unsigned long pos, in_len, out_len; + unsigned char idx0; + unsigned char idx1; + + const unsigned char hashmap[] = { + 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, /* 01234567 */ + 0x08, 0x09, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* 89:;<=>? */ + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* @ABCDEFG */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* HIJKLMNO */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* PQRSTUVW */ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* XYZ[\]^_ */ + 0x00, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f, 0x00, /* `abcdefg */ + }; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + in_len = strlen(in); + if ((in_len % 2) == 1) return CRYPT_INVALID_PACKET; + out_len = *outlen * 2; + for (pos = 0; ((pos + 1 < out_len) && (pos + 1 < in_len)); pos += 2) { + idx0 = (unsigned char) (in[pos + 0] & 0x1F) ^ 0x10; + idx1 = (unsigned char) (in[pos + 1] & 0x1F) ^ 0x10; + out[pos / 2] = (unsigned char) (hashmap[idx0] << 4) | hashmap[idx1]; + } + *outlen = pos / 2; + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/base16/base16_encode.c b/src/ltc/misc/base16/base16_encode.c new file mode 100644 index 00000000..d400d76b --- /dev/null +++ b/src/ltc/misc/base16/base16_encode.c @@ -0,0 +1,71 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ + +#include "tomcrypt.h" + +/** + @file base16_encode.c + Base16/Hex encode a string, Steffen Jaeckel +*/ + +#ifdef LTC_BASE16 + +/** + Base16 encode a buffer + @param in The input buffer to encode + @param inlen The length of the input buffer + @param out [out] The destination of the Base16 encoded data + @param outlen [in/out] The max size and resulting size of the encoded data + @param caps Output 'a-f' on 0 and 'A-F' otherwise. + @return CRYPT_OK if successful +*/ +int base16_encode(const unsigned char *in, unsigned long inlen, + char *out, unsigned long *outlen, + int caps) +{ + unsigned long i, x; + const char *alphabet; + const char *alphabets[2] = { + "0123456789abcdef", + "0123456789ABCDEF", + }; + + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(out != NULL); + LTC_ARGCHK(outlen != NULL); + + /* check the sizes */ + x = inlen * 2 + 1; + + if (x < inlen) return CRYPT_OVERFLOW; + + if (*outlen < x) { + *outlen = x; + return CRYPT_BUFFER_OVERFLOW; + } + *outlen = x; + + if (caps == 0) alphabet = alphabets[0]; + else alphabet = alphabets[1]; + + x -= 1; + for (i = 0; i < x; i += 2) { + out[i] = alphabet[(in[i/2] >> 4) & 0x0f]; + out[i+1] = alphabet[in[i/2] & 0x0f]; + } + out[x] = '\0'; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/base32/base32_decode.c b/src/ltc/misc/base32/base32_decode.c index 8bbb19c6..5809553e 100644 --- a/src/ltc/misc/base32/base32_decode.c +++ b/src/ltc/misc/base32/base32_decode.c @@ -20,14 +20,14 @@ @param id Alphabet to use BASE32_RFC4648, BASE32_BASE32HEX, BASE32_ZBASE32 or BASE32_CROCKFORD @return CRYPT_OK if successful */ -int base32_decode(const unsigned char *in, unsigned long inlen, +int base32_decode(const char *in, unsigned long inlen, unsigned char *out, unsigned long *outlen, base32_alphabet id) { unsigned long x; int y = 0; ulong64 t = 0; - unsigned char c; + char c; const unsigned char *map; const unsigned char tables[4][43] = { { /* id = BASE32_RFC4648 : ABCDEFGHIJKLMNOPQRSTUVWXYZ234567 */ @@ -90,11 +90,10 @@ int base32_decode(const unsigned char *in, unsigned long inlen, c = in[x]; /* convert to upper case */ if ((c >= 'a') && (c <= 'z')) c -= 32; - /* '0' = 48 .. 'Z' = 90 */ - if (c < 48 || c > 90 || map[c-48] > 31) { + if (c < '0' || c > 'Z' || map[c-'0'] > 31) { return CRYPT_INVALID_PACKET; } - t = (t<<5)|map[c-48]; + t = (t<<5) | map[c-'0']; if (++y == 8) { *out++ = (unsigned char)((t>>32) & 255); *out++ = (unsigned char)((t>>24) & 255); diff --git a/src/ltc/misc/base32/base32_encode.c b/src/ltc/misc/base32/base32_encode.c index 60fbd8dd..0e072636 100644 --- a/src/ltc/misc/base32/base32_encode.c +++ b/src/ltc/misc/base32/base32_encode.c @@ -21,11 +21,11 @@ @return CRYPT_OK if successful */ int base32_encode(const unsigned char *in, unsigned long inlen, - unsigned char *out, unsigned long *outlen, + char *out, unsigned long *outlen, base32_alphabet id) { unsigned long i, x; - unsigned char *codes; + const char *codes; const char *alphabet[4] = { "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567", /* id = BASE32_RFC4648 */ "0123456789ABCDEFGHIJKLMNOPQRSTUV", /* id = BASE32_BASE32HEX */ @@ -53,7 +53,7 @@ int base32_encode(const unsigned char *in, unsigned long inlen, } *outlen = x; - codes = (unsigned char*)alphabet[id]; + codes = alphabet[id]; x = 5 * (inlen / 5); for (i = 0; i < x; i += 5) { *out++ = codes[(in[0] >> 3) & 0x1F]; diff --git a/src/ltc/misc/base64/base64_decode.c b/src/ltc/misc/base64/base64_decode.c index 4c58c68d..90d7451a 100644 --- a/src/ltc/misc/base64/base64_decode.c +++ b/src/ltc/misc/base64/base64_decode.c @@ -17,11 +17,16 @@ #if defined(LTC_BASE64) || defined (LTC_BASE64_URL) +/* 253 - ignored in "relaxed" mode: TAB(9), CR(13), LF(10), space(32) + * 254 - padding character '=' (allowed only at the end) + * 255 - invalid character (not allowed even in relaxed mode) + */ + #if defined(LTC_BASE64) static const unsigned char map_base64[256] = { -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 255, +255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 255, 63, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, @@ -45,9 +50,9 @@ static const unsigned char map_base64[256] = { static const unsigned char map_base64url[] = { #if defined(LTC_BASE64_URL) -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, -255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 255, 253, 253, 255, +255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, +255, 255, 255, 255, 255, 255, 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 62, 255, 255, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 255, 255, 255, 254, 255, 255, 255, 0, 1, 2, 3, 4, 5, 6, @@ -89,21 +94,25 @@ static int _base64_decode_internal(const unsigned char *in, unsigned long inlen g = 0; /* '=' counter */ for (x = y = z = t = 0; x < inlen; x++) { + if (in[x] == 0 && x == (inlen - 1)) continue; /* allow the last byte to be NUL */ c = map[in[x]&0xFF]; if (c == 254) { g++; continue; } - else if (is_strict && g > 0) { - /* we only allow '=' to be at the end */ - return CRYPT_INVALID_PACKET; - } - if (c == 255) { + if (c == 253) { if (is_strict) return CRYPT_INVALID_PACKET; else continue; } + if (c == 255) { + return CRYPT_INVALID_PACKET; + } + if (g > 0) { + /* we only allow '=' to be at the end */ + return CRYPT_INVALID_PACKET; + } t = (t<<6)|c; diff --git a/src/ltc/misc/crypt/crypt.c b/src/ltc/misc/crypt/crypt.c index bd57a0aa..2d76033a 100644 --- a/src/ltc/misc/crypt/crypt.c +++ b/src/ltc/misc/crypt/crypt.c @@ -414,6 +414,9 @@ const char *crypt_build_settings = #if defined(LTC_BASE32) " BASE32 " #endif +#if defined(LTC_BASE16) + " BASE16 " +#endif #if defined(LTC_CRC32) " CRC32 " #endif @@ -426,6 +429,9 @@ const char *crypt_build_settings = #if defined(LTC_PKCS_5) " PKCS#5 " #endif +#if defined(LTC_PADDING) + " PADDING " +#endif #if defined(LTC_HKDF) " HKDF " #endif diff --git a/src/ltc/misc/crypt/crypt_constants.c b/src/ltc/misc/crypt/crypt_constants.c index 9e76322c..c5517695 100644 --- a/src/ltc/misc/crypt/crypt_constants.c +++ b/src/ltc/misc/crypt/crypt_constants.c @@ -75,6 +75,21 @@ static const crypt_constant _crypt_constants[] = { {"LTC_PKCS_1", 0}, #endif +#ifdef LTC_PADDING + {"LTC_PADDING", 1}, + + _C_STRINGIFY(LTC_PAD_PKCS7), +#ifdef LTC_RNG_GET_BYTES + _C_STRINGIFY(LTC_PAD_ISO_10126), +#endif + _C_STRINGIFY(LTC_PAD_ANSI_X923), + _C_STRINGIFY(LTC_PAD_ONE_AND_ZERO), + _C_STRINGIFY(LTC_PAD_ZERO), + _C_STRINGIFY(LTC_PAD_ZERO_ALWAYS), +#else + {"LTC_PADDING", 0}, +#endif + #ifdef LTC_MRSA {"LTC_MRSA", 1}, #else diff --git a/src/ltc/misc/padding/padding_depad.c b/src/ltc/misc/padding/padding_depad.c new file mode 100644 index 00000000..da511469 --- /dev/null +++ b/src/ltc/misc/padding/padding_depad.c @@ -0,0 +1,94 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +#ifdef LTC_PADDING + +/** + Remove padding from your data + + This depads your data. + + @param data The data to depad + @param length [in/out] The size of the data before/after (removing padding) + @param mode One of the LTC_PAD_xx flags + @return CRYPT_OK on success +*/ +int padding_depad(unsigned char *data, unsigned long *length, unsigned long mode) +{ + unsigned long padded_length, unpadded_length, n; + unsigned char pad; + enum padding_type type; + + LTC_ARGCHK(data != NULL); + LTC_ARGCHK(length != NULL); + + padded_length = *length; + + type = mode & LTC_PAD_MASK; + + if (type < LTC_PAD_ONE_AND_ZERO) { + pad = data[padded_length - 1]; + + if (pad > padded_length) return CRYPT_INVALID_ARG; + + unpadded_length = padded_length - pad; + } else { + /* init pad to calm old compilers */ + pad = 0x0; + unpadded_length = padded_length; + } + + switch (type) { + case LTC_PAD_ANSI_X923: + pad = 0x0; + /* FALLTHROUGH */ + case LTC_PAD_PKCS7: + for (n = unpadded_length; n < padded_length - 1; ++n) { + if (data[n] != pad) return CRYPT_INVALID_PACKET; + } + break; +#ifdef LTC_RNG_GET_BYTES + case LTC_PAD_ISO_10126: + /* nop */ + break; +#endif + case LTC_PAD_ONE_AND_ZERO: + while (unpadded_length > 0 && data[unpadded_length - 1] != 0x80) { + if (data[unpadded_length - 1] != 0x0) return CRYPT_INVALID_PACKET; + unpadded_length--; + } + if (unpadded_length == 0) return CRYPT_INVALID_PACKET; + unpadded_length--; + if (data[unpadded_length] != 0x80) return CRYPT_INVALID_PACKET; + break; + case LTC_PAD_ZERO: + case LTC_PAD_ZERO_ALWAYS: + while (unpadded_length > 0 && data[unpadded_length - 1] == 0x0) { + unpadded_length--; + } + if (type == LTC_PAD_ZERO_ALWAYS) { + if (unpadded_length == padded_length) return CRYPT_INVALID_PACKET; + if (data[unpadded_length] != 0x0) return CRYPT_INVALID_PACKET; + } + break; + default: + return CRYPT_INVALID_ARG; + } + + *length = unpadded_length; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/misc/padding/padding_pad.c b/src/ltc/misc/padding/padding_pad.c new file mode 100644 index 00000000..653e31db --- /dev/null +++ b/src/ltc/misc/padding/padding_pad.c @@ -0,0 +1,146 @@ +/* LibTomCrypt, modular cryptographic library -- Tom St Denis + * + * LibTomCrypt is a library that provides various cryptographic + * algorithms in a highly modular and flexible manner. + * + * The library is free for all purposes without any express + * guarantee it works. + */ +#include "tomcrypt.h" + +#ifdef LTC_PADDING + +/** + Determine the to-be-padded length. + + @param length [in/out] The size of the data before/after padding + @param mode Mask of (LTC_PAD_xxx | block_length) + @return CRYPT_OK on success +*/ +static int _padding_padded_length(unsigned long *length, unsigned long mode) +{ + enum padding_type padding; + unsigned char pad, block_length, r, t; + + LTC_ARGCHK(length != NULL); + + block_length = mode & 0xff; + padding = mode & LTC_PAD_MASK; + r = *length % block_length; + + switch (padding) { + case LTC_PAD_ZERO: + if (r == 0) { + t = 0; + break; + } + /* FALLTHROUGH */ + case LTC_PAD_PKCS7: + case LTC_PAD_ONE_AND_ZERO: + case LTC_PAD_ZERO_ALWAYS: + t = 1; + break; +#ifdef LTC_RNG_GET_BYTES + case LTC_PAD_ISO_10126: + do { + if (rng_get_bytes(&t, sizeof(t), NULL) != sizeof(t)) { + return CRYPT_ERROR_READPRNG; + } + t %= (256 / block_length); + } while (t == 0); + break; +#endif + case LTC_PAD_ANSI_X923: + if (block_length != 16) { + return CRYPT_INVALID_ARG; + } + t = 1; + break; + default: + return CRYPT_INVALID_ARG; + } + + pad = (t * block_length) - r; + + if ((pad == 0) && (padding != LTC_PAD_ZERO)) { + pad = block_length; + } + + *length += pad; + + return CRYPT_OK; +} + +/** + Add padding to data. + + This pads your data. + + @param data The data to depad + @param length The size of the data before padding + @param padded_length [in/out] The size of the data available/after padding + @param mode One of the LTC_PAD_xx flags + @return CRYPT_OK on success +*/ +int padding_pad(unsigned char *data, unsigned long length, unsigned long* padded_length, unsigned long mode) +{ + unsigned long diff, l; + enum padding_type type; + int err; + + LTC_ARGCHK(data != NULL); + LTC_ARGCHK(padded_length != NULL); + + l = length; + if ((err = _padding_padded_length(&l, mode)) != CRYPT_OK) { + return err; + } + + type = mode & LTC_PAD_MASK; + + if (*padded_length < l) { + if (type != LTC_PAD_ISO_10126) *padded_length = l; + else *padded_length = length + 256; + return CRYPT_BUFFER_OVERFLOW; + } + + diff = l - length; + if (diff > 255) return CRYPT_INVALID_ARG; + + switch (type) { + case LTC_PAD_PKCS7: + XMEMSET(&data[length], diff, diff); + break; +#ifdef LTC_RNG_GET_BYTES + case LTC_PAD_ISO_10126: + if (rng_get_bytes(&data[length], diff-1, NULL) != diff-1) { + return CRYPT_ERROR_READPRNG; + } + data[l-1] = diff; + break; +#endif + case LTC_PAD_ANSI_X923: + XMEMSET(&data[length], 0, diff-1); + data[l-1] = diff; + break; + case LTC_PAD_ONE_AND_ZERO: + XMEMSET(&data[length + 1], 0, diff); + data[length] = 0x80; + break; + case LTC_PAD_ZERO: + case LTC_PAD_ZERO_ALWAYS: + XMEMSET(&data[length], 0, diff); + break; + default: + return CRYPT_INVALID_ARG; + } + *padded_length = l; + + return CRYPT_OK; +} + +#endif + +/* ref: $Format:%D$ */ +/* git commit: $Format:%H$ */ +/* commit time: $Format:%ai$ */ diff --git a/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c b/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c index 9bc34312..8a0bc85d 100644 --- a/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c +++ b/src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c @@ -93,7 +93,7 @@ int der_decode_custom_type_ex(const unsigned char *in, unsigned long inlen, goto LBL_ERR; } if ((ident.type != root->type) || - (ident.class != root->class) || + (ident.klass != root->klass) || (ident.pc != root->pc) || (ident.tag != root->tag)) { err = CRYPT_INVALID_PACKET; diff --git a/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c b/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c index b4689f6a..27296fcd 100644 --- a/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c +++ b/src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c @@ -77,7 +77,7 @@ int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, lt } tag_len = 1; - id->class = (in[0] >> 6) & 0x3; + id->klass = (in[0] >> 6) & 0x3; id->pc = (in[0] >> 5) & 0x1; id->tag = in[0] & 0x1f; @@ -105,17 +105,17 @@ int der_decode_asn1_identifier(const unsigned char *in, unsigned long *inlen, lt if (err != CRYPT_OK) { id->pc = 0; - id->class = 0; + id->klass = 0; id->tag = 0; } else { *inlen = tag_len; - if ((id->class == LTC_ASN1_CL_UNIVERSAL) && + if ((id->klass == LTC_ASN1_CL_UNIVERSAL) && (id->tag < der_asn1_tag_to_type_map_sz) && (id->tag < tag_constructed_map_sz) && (id->pc == tag_constructed_map[id->tag])) { id->type = der_asn1_tag_to_type_map[id->tag]; } else { - if ((id->class == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) { + if ((id->klass == LTC_ASN1_CL_UNIVERSAL) && (id->tag == 0)) { id->type = LTC_ASN1_EOL; } else { id->type = LTC_ASN1_CUSTOM_TYPE; diff --git a/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c b/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c index 367bb699..82145d56 100644 --- a/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c +++ b/src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c @@ -42,7 +42,7 @@ int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsi *outlen = 1; return CRYPT_OK; } else { - if (id->class < LTC_ASN1_CL_UNIVERSAL || id->class > LTC_ASN1_CL_PRIVATE) { + if (id->klass < LTC_ASN1_CL_UNIVERSAL || id->klass > LTC_ASN1_CL_PRIVATE) { return CRYPT_INVALID_ARG; } if (id->pc < LTC_ASN1_PC_PRIMITIVE || id->pc > LTC_ASN1_PC_CONSTRUCTED) { @@ -58,7 +58,7 @@ int der_encode_asn1_identifier(const ltc_asn1_list *id, unsigned char *out, unsi return CRYPT_BUFFER_OVERFLOW; } - out[0] = id->class << 6 | id->pc << 5; + out[0] = id->klass << 6 | id->pc << 5; } if (id->tag < 0x1f) { diff --git a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c index 44c9c478..756a6f94 100644 --- a/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c +++ b/src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c @@ -96,7 +96,7 @@ int der_decode_sequence_flexi(const unsigned char *in, unsigned long *inlen, ltc } data_offset = id_len + len_len; #if defined(LTC_TEST_DBG) && LTC_TEST_DBG > 1 - if (l->type == LTC_ASN1_CUSTOM_TYPE && l->class == LTC_ASN1_CL_CONTEXT_SPECIFIC) { + if (l->type == LTC_ASN1_CUSTOM_TYPE && l->klass == LTC_ASN1_CL_CONTEXT_SPECIFIC) { 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); } else { fprintf(stderr, "OK %02lx: hl=%4lu l=%4lu - %s\n", identifier, data_offset, len, der_asn1_tag_to_string_map[l->tag]); diff --git a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c index c68b4a3b..8fef4e2a 100644 --- a/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c @@ -39,10 +39,10 @@ */ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long inlen, unsigned int algorithm, void* public_key, unsigned long* public_key_len, - unsigned long parameters_type, void* parameters, unsigned long *parameters_len) + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long *parameters_len) { int err; - unsigned long len; + unsigned long len, alg_id_num; oid_st oid; unsigned char *tmpbuf; unsigned long tmpoid[16]; @@ -52,7 +52,9 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i LTC_ARGCHK(in != NULL); LTC_ARGCHK(inlen != 0); LTC_ARGCHK(public_key_len != NULL); - LTC_ARGCHK(parameters_len != NULL); + if (parameters_type != LTC_ASN1_EOL) { + LTC_ARGCHK(parameters_len != NULL); + } err = pk_get_oid(algorithm, &oid); if (err != CRYPT_OK) { @@ -68,20 +70,27 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i /* this includes the internal hash ID and optional params (NULL in this case) */ LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, tmpoid, sizeof(tmpoid)/sizeof(tmpoid[0])); - LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, *parameters_len); + if (parameters_type == LTC_ASN1_EOL) { + alg_id_num = 1; + } + else { + LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, *parameters_len); + alg_id_num = 2; + } /* the actual format of the SSL DER key is odd, it stores a RSAPublicKey * in a **BIT** string ... so we have to extract it then proceed to convert bit to octet */ - LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, 2); + LTC_SET_ASN1(subject_pubkey, 0, LTC_ASN1_SEQUENCE, alg_id, alg_id_num); LTC_SET_ASN1(subject_pubkey, 1, LTC_ASN1_RAW_BIT_STRING, tmpbuf, inlen*8U); err=der_decode_sequence(in, inlen, subject_pubkey, 2UL); if (err != CRYPT_OK) { goto LBL_ERR; } - - *parameters_len = alg_id[1].size; + if (parameters_type != LTC_ASN1_EOL) { + *parameters_len = alg_id[1].size; + } if ((alg_id[0].size != oid.OIDlen) || XMEMCMP(oid.OID, alg_id[0].data, oid.OIDlen * sizeof(oid.OID[0]))) { @@ -91,7 +100,7 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i } len = subject_pubkey[1].size/8; - if (*public_key_len > len) { + if (*public_key_len >= len) { XMEMCPY(public_key, subject_pubkey[1].data, len); *public_key_len = len; } else { diff --git a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c index 8148a185..25c1195d 100644 --- a/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c +++ b/src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c @@ -38,8 +38,8 @@ @return CRYPT_OK on success */ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outlen, - unsigned int algorithm, void* public_key, unsigned long public_key_len, - unsigned long parameters_type, void* parameters, unsigned long parameters_len) + unsigned int algorithm, const void* public_key, unsigned long public_key_len, + ltc_asn1_type parameters_type, ltc_asn1_list* parameters, unsigned long parameters_len) { int err; ltc_asn1_list alg_id[2]; @@ -54,7 +54,7 @@ int x509_encode_subject_public_key_info(unsigned char *out, unsigned long *outle } LTC_SET_ASN1(alg_id, 0, LTC_ASN1_OBJECT_IDENTIFIER, oid.OID, oid.OIDlen); - LTC_SET_ASN1(alg_id, 1, (ltc_asn1_type)parameters_type, parameters, parameters_len); + LTC_SET_ASN1(alg_id, 1, parameters_type, parameters, parameters_len); return der_encode_sequence_multi(out, outlen, LTC_ASN1_SEQUENCE, (unsigned long)sizeof(alg_id)/sizeof(alg_id[0]), alg_id, diff --git a/src/ltc/pk/ecc/ecc_import_openssl.c b/src/ltc/pk/ecc/ecc_import_openssl.c index abbf5052..18316ee8 100644 --- a/src/ltc/pk/ecc/ecc_import_openssl.c +++ b/src/ltc/pk/ecc/ecc_import_openssl.c @@ -28,7 +28,7 @@ int ecc_import_openssl(const unsigned char *in, unsigned long inlen, ecc_key *ke len_xy = sizeof(bin_xy); len_oid = 16; - err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, curveoid, &len_oid); + err = x509_decode_subject_public_key_info(in, inlen, PKA_EC, bin_xy, &len_xy, LTC_ASN1_OBJECT_IDENTIFIER, (void *)curveoid, &len_oid); if (err == CRYPT_OK) { /* load curve parameters for given curve OID */ if ((err = ecc_set_dp_oid(curveoid, len_oid, key)) != CRYPT_OK) { goto error; } diff --git a/src/ltc/prngs/chacha20.c b/src/ltc/prngs/chacha20.c index 72a6d63d..59b23227 100644 --- a/src/ltc/prngs/chacha20.c +++ b/src/ltc/prngs/chacha20.c @@ -150,26 +150,7 @@ int chacha20_prng_done(prng_state *prng) @param prng The PRNG to export @return CRYPT_OK if successful */ -int chacha20_prng_export(unsigned char *out, unsigned long *outlen, prng_state *prng) -{ - unsigned long len = chacha20_prng_desc.export_size; - - LTC_ARGCHK(prng != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if (*outlen < len) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (chacha20_prng_read(out, len, prng) != len) { - return CRYPT_ERROR_READPRNG; - } - - *outlen = len; - return CRYPT_OK; -} +_LTC_PRNG_EXPORT(chacha20_prng) /** Import a PRNG state diff --git a/src/ltc/prngs/fortuna.c b/src/ltc/prngs/fortuna.c index 7b1ecb65..f65c32a1 100644 --- a/src/ltc/prngs/fortuna.c +++ b/src/ltc/prngs/fortuna.c @@ -37,7 +37,7 @@ we reseed automatically when len(pool0) >= 64 or every LTC_FORTUNA_WD calls to t const struct ltc_prng_descriptor fortuna_desc = { "fortuna", - (32 * LTC_FORTUNA_POOLS), /* default: 1024 */ + 64, &fortuna_start, &fortuna_add_entropy, &fortuna_ready, @@ -66,9 +66,9 @@ static int _fortuna_reseed(prng_state *prng) { unsigned char tmp[MAXBLOCKSIZE]; hash_state md; + ulong64 reset_cnt; int err, x; - ++prng->fortuna.reset_cnt; /* new K == LTC_SHA256(K || s) where s == LTC_SHA256(P0) || LTC_SHA256(P1) ... */ sha256_init(&md); @@ -77,8 +77,10 @@ static int _fortuna_reseed(prng_state *prng) return err; } + reset_cnt = prng->fortuna.reset_cnt + 1; + for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - if (x == 0 || ((prng->fortuna.reset_cnt >> (x-1)) & 1) == 0) { + if (x == 0 || ((reset_cnt >> (x-1)) & 1) == 0) { /* terminate this hash */ if ((err = sha256_done(&prng->fortuna.pool[x], tmp)) != CRYPT_OK) { sha256_done(&md, tmp); @@ -108,9 +110,10 @@ static int _fortuna_reseed(prng_state *prng) } _fortuna_update_iv(prng); - /* reset pool len */ + /* reset/update internals */ prng->fortuna.pool0_len = 0; prng->fortuna.wd = 0; + prng->fortuna.reset_cnt = reset_cnt; #ifdef LTC_CLEAN_STACK @@ -122,6 +125,46 @@ static int _fortuna_reseed(prng_state *prng) } /** + "Update Seed File"-compliant update of K + + @param in The PRNG state + @param inlen Size of the state + @param prng The PRNG to import + @return CRYPT_OK if successful +*/ +static int _fortuna_update_seed(const unsigned char *in, unsigned long inlen, prng_state *prng) +{ + int err; + unsigned char tmp[MAXBLOCKSIZE]; + hash_state md; + + LTC_MUTEX_LOCK(&prng->lock); + /* new K = LTC_SHA256(K || in) */ + sha256_init(&md); + if ((err = sha256_process(&md, prng->fortuna.K, 32)) != CRYPT_OK) { + sha256_done(&md, tmp); + goto LBL_UNLOCK; + } + if ((err = sha256_process(&md, in, inlen)) != CRYPT_OK) { + sha256_done(&md, tmp); + goto LBL_UNLOCK; + } + /* finish key */ + if ((err = sha256_done(&md, prng->fortuna.K)) != CRYPT_OK) { + goto LBL_UNLOCK; + } + _fortuna_update_iv(prng); + +LBL_UNLOCK: + LTC_MUTEX_UNLOCK(&prng->lock); +#ifdef LTC_CLEAN_STACK + zeromem(&md, sizeof(md)); +#endif + + return err; +} + +/** Start the PRNG @param prng [out] The PRNG state to initialize @return CRYPT_OK if successful @@ -251,6 +294,11 @@ unsigned long fortuna_read(unsigned char *out, unsigned long outlen, prng_state } } + /* ensure that one reseed happened before allowing to read */ + if (prng->fortuna.reset_cnt == 0) { + goto LBL_UNLOCK; + } + /* now generate the blocks required */ tlen = outlen; @@ -329,71 +377,7 @@ LBL_UNLOCK: @param prng The PRNG to export @return CRYPT_OK if successful */ -int fortuna_export(unsigned char *out, unsigned long *outlen, prng_state *prng) -{ - int x, err; - hash_state *md; - unsigned long len = fortuna_desc.export_size; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(prng != NULL); - - LTC_MUTEX_LOCK(&prng->lock); - - if (!prng->ready) { - err = CRYPT_ERROR; - goto LBL_UNLOCK; - } - - /* we'll write bytes for s&g's */ - if (*outlen < len) { - *outlen = len; - err = CRYPT_BUFFER_OVERFLOW; - goto LBL_UNLOCK; - } - - md = XMALLOC(sizeof(hash_state)); - if (md == NULL) { - err = CRYPT_MEM; - goto LBL_UNLOCK; - } - - /* to emit the state we copy each pool, terminate it then hash it again so - * an attacker who sees the state can't determine the current state of the PRNG - */ - for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - /* copy the PRNG */ - XMEMCPY(md, &(prng->fortuna.pool[x]), sizeof(*md)); - - /* terminate it */ - if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { - goto LBL_ERR; - } - - /* now hash it */ - if ((err = sha256_init(md)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = sha256_process(md, out+x*32, 32)) != CRYPT_OK) { - goto LBL_ERR; - } - if ((err = sha256_done(md, out+x*32)) != CRYPT_OK) { - goto LBL_ERR; - } - } - *outlen = len; - err = CRYPT_OK; - -LBL_ERR: -#ifdef LTC_CLEAN_STACK - zeromem(md, sizeof(*md)); -#endif - XFREE(md); -LBL_UNLOCK: - LTC_MUTEX_UNLOCK(&prng->lock); - return err; -} +_LTC_PRNG_EXPORT(fortuna) /** Import a PRNG state @@ -404,10 +388,10 @@ LBL_UNLOCK: */ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prng) { - int err, x; + int err; - LTC_ARGCHK(in != NULL); - LTC_ARGCHK(prng != NULL); + LTC_ARGCHK(in != NULL); + LTC_ARGCHK(prng != NULL); if (inlen < (unsigned long)fortuna_desc.export_size) { return CRYPT_INVALID_ARG; @@ -416,12 +400,12 @@ int fortuna_import(const unsigned char *in, unsigned long inlen, prng_state *prn if ((err = fortuna_start(prng)) != CRYPT_OK) { return err; } - for (x = 0; x < LTC_FORTUNA_POOLS; x++) { - if ((err = fortuna_add_entropy(in+x*32, 32, prng)) != CRYPT_OK) { - return err; - } + + if ((err = _fortuna_update_seed(in, inlen, prng)) != CRYPT_OK) { + return err; } - return CRYPT_OK; + + return err; } /** diff --git a/src/ltc/prngs/rc4.c b/src/ltc/prngs/rc4.c index e2aa9217..7611151d 100644 --- a/src/ltc/prngs/rc4.c +++ b/src/ltc/prngs/rc4.c @@ -153,26 +153,7 @@ int rc4_done(prng_state *prng) @param prng The PRNG to export @return CRYPT_OK if successful */ -int rc4_export(unsigned char *out, unsigned long *outlen, prng_state *prng) -{ - unsigned long len = rc4_desc.export_size; - - LTC_ARGCHK(prng != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if (*outlen < len) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (rc4_read(out, len, prng) != len) { - return CRYPT_ERROR_READPRNG; - } - - *outlen = len; - return CRYPT_OK; -} +_LTC_PRNG_EXPORT(rc4) /** Import a PRNG state diff --git a/src/ltc/prngs/rng_make_prng.c b/src/ltc/prngs/rng_make_prng.c index 2bde291f..19ac1ee3 100644 --- a/src/ltc/prngs/rng_make_prng.c +++ b/src/ltc/prngs/rng_make_prng.c @@ -16,7 +16,12 @@ /** Create a PRNG from a RNG - @param bits Number of bits of entropy desired (64 ... 1024) + + In case you pass bits as '-1' the PRNG will be setup + as if the export/import functionality has been used, + but the imported data comes directly from the RNG. + + @param bits Number of bits of entropy desired (-1 or 64 ... 1024) @param wprng Index of which PRNG to setup @param prng [out] PRNG state to initialize @param callback A pointer to a void function for when the RNG is slow, this can be NULL @@ -25,7 +30,8 @@ int rng_make_prng(int bits, int wprng, prng_state *prng, void (*callback)(void)) { - unsigned char buf[256]; + unsigned char* buf; + unsigned long bytes; int err; LTC_ARGCHK(prng != NULL); @@ -35,31 +41,47 @@ int rng_make_prng(int bits, int wprng, prng_state *prng, return err; } - if (bits < 64 || bits > 1024) { + if (bits == -1) { + bytes = prng_descriptor[wprng].export_size; + } else if (bits < 64 || bits > 1024) { return CRYPT_INVALID_PRNGSIZE; + } else { + bytes = (unsigned long)((bits+7)/8) * 2; } if ((err = prng_descriptor[wprng].start(prng)) != CRYPT_OK) { return err; } - bits = ((bits+7)/8) * 2; - if (rng_get_bytes(buf, (unsigned long)bits, callback) != (unsigned long)bits) { - return CRYPT_ERROR_READPRNG; + buf = XMALLOC(bytes); + if (buf == NULL) { + return CRYPT_MEM; } - if ((err = prng_descriptor[wprng].add_entropy(buf, (unsigned long)bits, prng)) != CRYPT_OK) { - return err; + if (rng_get_bytes(buf, bytes, callback) != bytes) { + err = CRYPT_ERROR_READPRNG; + goto LBL_ERR; } + if (bits == -1) { + if ((err = prng_descriptor[wprng].pimport(buf, bytes, prng)) != CRYPT_OK) { + goto LBL_ERR; + } + } else { + if ((err = prng_descriptor[wprng].add_entropy(buf, bytes, prng)) != CRYPT_OK) { + goto LBL_ERR; + } + } if ((err = prng_descriptor[wprng].ready(prng)) != CRYPT_OK) { - return err; + goto LBL_ERR; } +LBL_ERR: #ifdef LTC_CLEAN_STACK - zeromem(buf, sizeof(buf)); + zeromem(buf, bytes); #endif - return CRYPT_OK; + XFREE(buf); + return err; } #endif /* #ifdef LTC_RNG_MAKE_PRNG */ diff --git a/src/ltc/prngs/sober128.c b/src/ltc/prngs/sober128.c index 8d95491b..95136595 100644 --- a/src/ltc/prngs/sober128.c +++ b/src/ltc/prngs/sober128.c @@ -152,26 +152,7 @@ int sober128_done(prng_state *prng) @param prng The PRNG to export @return CRYPT_OK if successful */ -int sober128_export(unsigned char *out, unsigned long *outlen, prng_state *prng) -{ - unsigned long len = sober128_desc.export_size; - - LTC_ARGCHK(prng != NULL); - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - - if (*outlen < len) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (sober128_read(out, len, prng) != len) { - return CRYPT_ERROR_READPRNG; - } - - *outlen = len; - return CRYPT_OK; -} +_LTC_PRNG_EXPORT(sober128) /** Import a PRNG state @@ -189,7 +170,7 @@ int sober128_import(const unsigned char *in, unsigned long inlen, prng_state *pr if (inlen < (unsigned long)sober128_desc.export_size) return CRYPT_INVALID_ARG; if ((err = sober128_start(prng)) != CRYPT_OK) return err; - if ((err = sober128_add_entropy(in, sober128_desc.export_size, prng)) != CRYPT_OK) return err; + if ((err = sober128_add_entropy(in, inlen, prng)) != CRYPT_OK) return err; return CRYPT_OK; } diff --git a/src/ltc/prngs/yarrow.c b/src/ltc/prngs/yarrow.c index e5988348..6b5057f4 100644 --- a/src/ltc/prngs/yarrow.c +++ b/src/ltc/prngs/yarrow.c @@ -273,26 +273,7 @@ int yarrow_done(prng_state *prng) @param prng The PRNG to export @return CRYPT_OK if successful */ -int yarrow_export(unsigned char *out, unsigned long *outlen, prng_state *prng) -{ - unsigned long len = yarrow_desc.export_size; - - LTC_ARGCHK(out != NULL); - LTC_ARGCHK(outlen != NULL); - LTC_ARGCHK(prng != NULL); - - if (*outlen < len) { - *outlen = len; - return CRYPT_BUFFER_OVERFLOW; - } - - if (yarrow_read(out, len, prng) != len) { - return CRYPT_ERROR_READPRNG; - } - - *outlen = len; - return CRYPT_OK; -} +_LTC_PRNG_EXPORT(yarrow) /** Import a PRNG state |