summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKarel Miko <karel.miko@gmail.com>2018-03-25 18:17:57 +0200
committerKarel Miko <karel.miko@gmail.com>2018-03-25 18:17:57 +0200
commit5fd7132958e36a4a3c259cd44ee278349e522ef2 (patch)
tree993a3a732f19d8915e7e440fddb973b31b15ffbb
parente8a8ed0e6467701e2e2737fa23c99724c8370036 (diff)
ltc update
-rw-r--r--CryptX.xs10
-rw-r--r--src/Makefile24
-rw-r--r--src/Makefile.nmake76
-rw-r--r--src/ltc/headers/tomcrypt_custom.h4
-rw-r--r--src/ltc/headers/tomcrypt_misc.h36
-rw-r--r--src/ltc/headers/tomcrypt_pk.h34
-rw-r--r--src/ltc/headers/tomcrypt_prng.h25
-rw-r--r--src/ltc/misc/base16/base16_decode.c65
-rw-r--r--src/ltc/misc/base16/base16_encode.c71
-rw-r--r--src/ltc/misc/base32/base32_decode.c9
-rw-r--r--src/ltc/misc/base32/base32_encode.c6
-rw-r--r--src/ltc/misc/base64/base64_decode.c31
-rw-r--r--src/ltc/misc/crypt/crypt.c6
-rw-r--r--src/ltc/misc/crypt/crypt_constants.c15
-rw-r--r--src/ltc/misc/padding/padding_depad.c94
-rw-r--r--src/ltc/misc/padding/padding_pad.c146
-rw-r--r--src/ltc/pk/asn1/der/custom_type/der_decode_custom_type.c2
-rw-r--r--src/ltc/pk/asn1/der/general/der_decode_asn1_identifier.c8
-rw-r--r--src/ltc/pk/asn1/der/general/der_encode_asn1_identifier.c4
-rw-r--r--src/ltc/pk/asn1/der/sequence/der_decode_sequence_flexi.c2
-rw-r--r--src/ltc/pk/asn1/x509/x509_decode_subject_public_key_info.c25
-rw-r--r--src/ltc/pk/asn1/x509/x509_encode_subject_public_key_info.c6
-rw-r--r--src/ltc/pk/ecc/ecc_import_openssl.c2
-rw-r--r--src/ltc/prngs/chacha20.c21
-rw-r--r--src/ltc/prngs/fortuna.c138
-rw-r--r--src/ltc/prngs/rc4.c21
-rw-r--r--src/ltc/prngs/rng_make_prng.c44
-rw-r--r--src/ltc/prngs/sober128.c23
-rw-r--r--src/ltc/prngs/yarrow.c21
29 files changed, 691 insertions, 278 deletions
diff --git a/CryptX.xs b/CryptX.xs
index 41f21358..ebca25b9 100644
--- a/CryptX.xs
+++ b/CryptX.xs
@@ -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