diff --git a/libtomcrypt_VS2008.vcproj b/libtomcrypt_VS2008.vcproj
index 70d25ceae..0fe6b46b6 100644
--- a/libtomcrypt_VS2008.vcproj
+++ b/libtomcrypt_VS2008.vcproj
@@ -1571,6 +1571,18 @@
>
+
+
+
+
+
+
diff --git a/makefile.mingw b/makefile.mingw
index ed5cdb01a..088ccae44 100644
--- a/makefile.mingw
+++ b/makefile.mingw
@@ -110,29 +110,29 @@ src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \
src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
-src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
-src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
-src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
-src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
-src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
-src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
-src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
-src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
-src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
-src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
-src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \
-src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
-src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
-src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
-src/modes/ofb/ofb_start.o src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o \
-src/modes/xts/xts_encrypt.o src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o \
-src/modes/xts/xts_test.o src/pk/asn1/der/bit/der_decode_bit_string.o \
-src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \
-src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
-src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \
-src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \
-src/pk/asn1/der/custom_type/der_decode_custom_type.o \
+src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs12/pkcs12_kdf.o \
+src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o \
+src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
+src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
+src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
+src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \
+src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \
+src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \
+src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \
+src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \
+src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \
+src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \
+src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \
+src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \
+src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \
+src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \
+src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \
+src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_decode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_encode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \
+src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \
+src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/custom_type/der_decode_custom_type.o \
src/pk/asn1/der/custom_type/der_encode_custom_type.o \
src/pk/asn1/der/custom_type/der_length_custom_type.o src/pk/asn1/der/general/der_asn1_maps.o \
src/pk/asn1/der/general/der_decode_asn1_identifier.o src/pk/asn1/der/general/der_decode_asn1_length.o \
diff --git a/makefile.msvc b/makefile.msvc
index 289696140..0b1eb2ce5 100644
--- a/makefile.msvc
+++ b/makefile.msvc
@@ -103,29 +103,29 @@ src/misc/crypt/crypt_register_prng.obj src/misc/crypt/crypt_sizes.obj \
src/misc/crypt/crypt_unregister_cipher.obj src/misc/crypt/crypt_unregister_hash.obj \
src/misc/crypt/crypt_unregister_prng.obj src/misc/error_to_string.obj src/misc/hkdf/hkdf.obj \
src/misc/hkdf/hkdf_test.obj src/misc/mem_neq.obj src/misc/padding/padding_depad.obj \
-src/misc/padding/padding_pad.obj src/misc/pk_get_oid.obj src/misc/pk_oid_str.obj src/misc/pkcs5/pkcs_5_1.obj \
-src/misc/pkcs5/pkcs_5_2.obj src/misc/pkcs5/pkcs_5_test.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj \
-src/modes/cbc/cbc_done.obj src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj \
-src/modes/cbc/cbc_setiv.obj src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj \
-src/modes/cfb/cfb_done.obj src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj \
-src/modes/cfb/cfb_setiv.obj src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj \
-src/modes/ctr/ctr_done.obj src/modes/ctr/ctr_encrypt.obj src/modes/ctr/ctr_getiv.obj \
-src/modes/ctr/ctr_setiv.obj src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj \
-src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj src/modes/ecb/ecb_encrypt.obj \
-src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj src/modes/f8/f8_encrypt.obj \
-src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj src/modes/f8/f8_test_mode.obj \
-src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj src/modes/lrw/lrw_encrypt.obj \
-src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj src/modes/lrw/lrw_setiv.obj \
-src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj \
-src/modes/ofb/ofb_encrypt.obj src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj \
-src/modes/ofb/ofb_start.obj src/modes/xts/xts_decrypt.obj src/modes/xts/xts_done.obj \
-src/modes/xts/xts_encrypt.obj src/modes/xts/xts_init.obj src/modes/xts/xts_mult_x.obj \
-src/modes/xts/xts_test.obj src/pk/asn1/der/bit/der_decode_bit_string.obj \
-src/pk/asn1/der/bit/der_decode_raw_bit_string.obj src/pk/asn1/der/bit/der_encode_bit_string.obj \
-src/pk/asn1/der/bit/der_encode_raw_bit_string.obj src/pk/asn1/der/bit/der_length_bit_string.obj \
-src/pk/asn1/der/boolean/der_decode_boolean.obj src/pk/asn1/der/boolean/der_encode_boolean.obj \
-src/pk/asn1/der/boolean/der_length_boolean.obj src/pk/asn1/der/choice/der_decode_choice.obj \
-src/pk/asn1/der/custom_type/der_decode_custom_type.obj \
+src/misc/padding/padding_pad.obj src/misc/pk_get_oid.obj src/misc/pk_oid_str.obj src/misc/pkcs12/pkcs12_kdf.obj \
+src/misc/pkcs12/pkcs12_utf8_to_utf16.obj src/misc/pkcs5/pkcs_5_1.obj src/misc/pkcs5/pkcs_5_2.obj \
+src/misc/pkcs5/pkcs_5_test.obj src/misc/zeromem.obj src/modes/cbc/cbc_decrypt.obj src/modes/cbc/cbc_done.obj \
+src/modes/cbc/cbc_encrypt.obj src/modes/cbc/cbc_getiv.obj src/modes/cbc/cbc_setiv.obj \
+src/modes/cbc/cbc_start.obj src/modes/cfb/cfb_decrypt.obj src/modes/cfb/cfb_done.obj \
+src/modes/cfb/cfb_encrypt.obj src/modes/cfb/cfb_getiv.obj src/modes/cfb/cfb_setiv.obj \
+src/modes/cfb/cfb_start.obj src/modes/ctr/ctr_decrypt.obj src/modes/ctr/ctr_done.obj \
+src/modes/ctr/ctr_encrypt.obj src/modes/ctr/ctr_getiv.obj src/modes/ctr/ctr_setiv.obj \
+src/modes/ctr/ctr_start.obj src/modes/ctr/ctr_test.obj src/modes/ecb/ecb_decrypt.obj src/modes/ecb/ecb_done.obj \
+src/modes/ecb/ecb_encrypt.obj src/modes/ecb/ecb_start.obj src/modes/f8/f8_decrypt.obj src/modes/f8/f8_done.obj \
+src/modes/f8/f8_encrypt.obj src/modes/f8/f8_getiv.obj src/modes/f8/f8_setiv.obj src/modes/f8/f8_start.obj \
+src/modes/f8/f8_test_mode.obj src/modes/lrw/lrw_decrypt.obj src/modes/lrw/lrw_done.obj \
+src/modes/lrw/lrw_encrypt.obj src/modes/lrw/lrw_getiv.obj src/modes/lrw/lrw_process.obj \
+src/modes/lrw/lrw_setiv.obj src/modes/lrw/lrw_start.obj src/modes/lrw/lrw_test.obj \
+src/modes/ofb/ofb_decrypt.obj src/modes/ofb/ofb_done.obj src/modes/ofb/ofb_encrypt.obj \
+src/modes/ofb/ofb_getiv.obj src/modes/ofb/ofb_setiv.obj src/modes/ofb/ofb_start.obj \
+src/modes/xts/xts_decrypt.obj src/modes/xts/xts_done.obj src/modes/xts/xts_encrypt.obj \
+src/modes/xts/xts_init.obj src/modes/xts/xts_mult_x.obj src/modes/xts/xts_test.obj \
+src/pk/asn1/der/bit/der_decode_bit_string.obj src/pk/asn1/der/bit/der_decode_raw_bit_string.obj \
+src/pk/asn1/der/bit/der_encode_bit_string.obj src/pk/asn1/der/bit/der_encode_raw_bit_string.obj \
+src/pk/asn1/der/bit/der_length_bit_string.obj src/pk/asn1/der/boolean/der_decode_boolean.obj \
+src/pk/asn1/der/boolean/der_encode_boolean.obj src/pk/asn1/der/boolean/der_length_boolean.obj \
+src/pk/asn1/der/choice/der_decode_choice.obj src/pk/asn1/der/custom_type/der_decode_custom_type.obj \
src/pk/asn1/der/custom_type/der_encode_custom_type.obj \
src/pk/asn1/der/custom_type/der_length_custom_type.obj src/pk/asn1/der/general/der_asn1_maps.obj \
src/pk/asn1/der/general/der_decode_asn1_identifier.obj src/pk/asn1/der/general/der_decode_asn1_length.obj \
diff --git a/makefile.unix b/makefile.unix
index 5df15c7cc..fdd639938 100644
--- a/makefile.unix
+++ b/makefile.unix
@@ -120,29 +120,29 @@ src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \
src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
-src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
-src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
-src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
-src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
-src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
-src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
-src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
-src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
-src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
-src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
-src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \
-src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
-src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
-src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
-src/modes/ofb/ofb_start.o src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o \
-src/modes/xts/xts_encrypt.o src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o \
-src/modes/xts/xts_test.o src/pk/asn1/der/bit/der_decode_bit_string.o \
-src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \
-src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
-src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \
-src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \
-src/pk/asn1/der/custom_type/der_decode_custom_type.o \
+src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs12/pkcs12_kdf.o \
+src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o \
+src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
+src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
+src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
+src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \
+src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \
+src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \
+src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \
+src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \
+src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \
+src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \
+src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \
+src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \
+src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \
+src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \
+src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \
+src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_decode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_encode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \
+src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \
+src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/custom_type/der_decode_custom_type.o \
src/pk/asn1/der/custom_type/der_encode_custom_type.o \
src/pk/asn1/der/custom_type/der_length_custom_type.o src/pk/asn1/der/general/der_asn1_maps.o \
src/pk/asn1/der/general/der_decode_asn1_identifier.o src/pk/asn1/der/general/der_decode_asn1_length.o \
diff --git a/makefile_include.mk b/makefile_include.mk
index a9810e633..7724a74fb 100644
--- a/makefile_include.mk
+++ b/makefile_include.mk
@@ -280,29 +280,29 @@ src/misc/crypt/crypt_register_prng.o src/misc/crypt/crypt_sizes.o \
src/misc/crypt/crypt_unregister_cipher.o src/misc/crypt/crypt_unregister_hash.o \
src/misc/crypt/crypt_unregister_prng.o src/misc/error_to_string.o src/misc/hkdf/hkdf.o \
src/misc/hkdf/hkdf_test.o src/misc/mem_neq.o src/misc/padding/padding_depad.o \
-src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs5/pkcs_5_1.o \
-src/misc/pkcs5/pkcs_5_2.o src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o \
-src/modes/cbc/cbc_done.o src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o \
-src/modes/cbc/cbc_setiv.o src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o \
-src/modes/cfb/cfb_done.o src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o \
-src/modes/cfb/cfb_setiv.o src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o \
-src/modes/ctr/ctr_done.o src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o \
-src/modes/ctr/ctr_setiv.o src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o \
-src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o src/modes/ecb/ecb_encrypt.o \
-src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o src/modes/f8/f8_encrypt.o \
-src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o src/modes/f8/f8_test_mode.o \
-src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o src/modes/lrw/lrw_encrypt.o \
-src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o src/modes/lrw/lrw_setiv.o \
-src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o \
-src/modes/ofb/ofb_encrypt.o src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o \
-src/modes/ofb/ofb_start.o src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o \
-src/modes/xts/xts_encrypt.o src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o \
-src/modes/xts/xts_test.o src/pk/asn1/der/bit/der_decode_bit_string.o \
-src/pk/asn1/der/bit/der_decode_raw_bit_string.o src/pk/asn1/der/bit/der_encode_bit_string.o \
-src/pk/asn1/der/bit/der_encode_raw_bit_string.o src/pk/asn1/der/bit/der_length_bit_string.o \
-src/pk/asn1/der/boolean/der_decode_boolean.o src/pk/asn1/der/boolean/der_encode_boolean.o \
-src/pk/asn1/der/boolean/der_length_boolean.o src/pk/asn1/der/choice/der_decode_choice.o \
-src/pk/asn1/der/custom_type/der_decode_custom_type.o \
+src/misc/padding/padding_pad.o src/misc/pk_get_oid.o src/misc/pk_oid_str.o src/misc/pkcs12/pkcs12_kdf.o \
+src/misc/pkcs12/pkcs12_utf8_to_utf16.o src/misc/pkcs5/pkcs_5_1.o src/misc/pkcs5/pkcs_5_2.o \
+src/misc/pkcs5/pkcs_5_test.o src/misc/zeromem.o src/modes/cbc/cbc_decrypt.o src/modes/cbc/cbc_done.o \
+src/modes/cbc/cbc_encrypt.o src/modes/cbc/cbc_getiv.o src/modes/cbc/cbc_setiv.o \
+src/modes/cbc/cbc_start.o src/modes/cfb/cfb_decrypt.o src/modes/cfb/cfb_done.o \
+src/modes/cfb/cfb_encrypt.o src/modes/cfb/cfb_getiv.o src/modes/cfb/cfb_setiv.o \
+src/modes/cfb/cfb_start.o src/modes/ctr/ctr_decrypt.o src/modes/ctr/ctr_done.o \
+src/modes/ctr/ctr_encrypt.o src/modes/ctr/ctr_getiv.o src/modes/ctr/ctr_setiv.o \
+src/modes/ctr/ctr_start.o src/modes/ctr/ctr_test.o src/modes/ecb/ecb_decrypt.o src/modes/ecb/ecb_done.o \
+src/modes/ecb/ecb_encrypt.o src/modes/ecb/ecb_start.o src/modes/f8/f8_decrypt.o src/modes/f8/f8_done.o \
+src/modes/f8/f8_encrypt.o src/modes/f8/f8_getiv.o src/modes/f8/f8_setiv.o src/modes/f8/f8_start.o \
+src/modes/f8/f8_test_mode.o src/modes/lrw/lrw_decrypt.o src/modes/lrw/lrw_done.o \
+src/modes/lrw/lrw_encrypt.o src/modes/lrw/lrw_getiv.o src/modes/lrw/lrw_process.o \
+src/modes/lrw/lrw_setiv.o src/modes/lrw/lrw_start.o src/modes/lrw/lrw_test.o \
+src/modes/ofb/ofb_decrypt.o src/modes/ofb/ofb_done.o src/modes/ofb/ofb_encrypt.o \
+src/modes/ofb/ofb_getiv.o src/modes/ofb/ofb_setiv.o src/modes/ofb/ofb_start.o \
+src/modes/xts/xts_decrypt.o src/modes/xts/xts_done.o src/modes/xts/xts_encrypt.o \
+src/modes/xts/xts_init.o src/modes/xts/xts_mult_x.o src/modes/xts/xts_test.o \
+src/pk/asn1/der/bit/der_decode_bit_string.o src/pk/asn1/der/bit/der_decode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_encode_bit_string.o src/pk/asn1/der/bit/der_encode_raw_bit_string.o \
+src/pk/asn1/der/bit/der_length_bit_string.o src/pk/asn1/der/boolean/der_decode_boolean.o \
+src/pk/asn1/der/boolean/der_encode_boolean.o src/pk/asn1/der/boolean/der_length_boolean.o \
+src/pk/asn1/der/choice/der_decode_choice.o src/pk/asn1/der/custom_type/der_decode_custom_type.o \
src/pk/asn1/der/custom_type/der_encode_custom_type.o \
src/pk/asn1/der/custom_type/der_length_custom_type.o src/pk/asn1/der/general/der_asn1_maps.o \
src/pk/asn1/der/general/der_decode_asn1_identifier.o src/pk/asn1/der/general/der_decode_asn1_length.o \
diff --git a/src/headers/tomcrypt_custom.h b/src/headers/tomcrypt_custom.h
index 7c375d9f0..a151187f2 100644
--- a/src/headers/tomcrypt_custom.h
+++ b/src/headers/tomcrypt_custom.h
@@ -463,6 +463,7 @@
#define LTC_PKCS_1
#define LTC_PKCS_5
+#define LTC_PKCS_12
/* Include ASN.1 DER (required by DSA/RSA) */
#define LTC_DER
diff --git a/src/headers/tomcrypt_pkcs.h b/src/headers/tomcrypt_pkcs.h
index 247e5387d..0c99f7c3e 100644
--- a/src/headers/tomcrypt_pkcs.h
+++ b/src/headers/tomcrypt_pkcs.h
@@ -103,6 +103,7 @@ int pkcs_5_alg2(const unsigned char *password, unsigned long password_len,
int pkcs_5_test (void);
#endif /* LTC_PKCS_5 */
+
/* ref: $Format:%D$ */
/* git commit: $Format:%H$ */
/* commit time: $Format:%ai$ */
diff --git a/src/headers/tomcrypt_private.h b/src/headers/tomcrypt_private.h
index 20ad563c1..7fe4b014c 100644
--- a/src/headers/tomcrypt_private.h
+++ b/src/headers/tomcrypt_private.h
@@ -305,6 +305,21 @@ int x509_decode_subject_public_key_info(const unsigned char *in, unsigned long i
#endif /* LTC_DER */
+/* tomcrypt_pkcs.h */
+
+#ifdef LTC_PKCS_12
+
+int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
+ unsigned char *out, unsigned long *outlen);
+
+int pkcs12_kdf( int hash_id,
+ const unsigned char *pw, unsigned long pwlen,
+ const unsigned char *salt, unsigned long saltlen,
+ unsigned int iterations, unsigned char purpose,
+ unsigned char *out, unsigned long outlen);
+
+#endif /* LTC_PKCS_12 */
+
/* tomcrypt_prng.h */
#define _LTC_PRNG_EXPORT(which) \
diff --git a/src/misc/crypt/crypt.c b/src/misc/crypt/crypt.c
index 1f76662e6..0b4912c4a 100644
--- a/src/misc/crypt/crypt.c
+++ b/src/misc/crypt/crypt.c
@@ -436,6 +436,9 @@ const char *crypt_build_settings =
#if defined(LTC_PKCS_5)
" PKCS#5 "
#endif
+#if defined(LTC_PKCS_12)
+ " PKCS#12 "
+#endif
#if defined(LTC_PADDING)
" PADDING "
#endif
diff --git a/src/misc/pkcs12/pkcs12_kdf.c b/src/misc/pkcs12/pkcs12_kdf.c
new file mode 100644
index 000000000..d097e8a9f
--- /dev/null
+++ b/src/misc/pkcs12/pkcs12_kdf.c
@@ -0,0 +1,92 @@
+/* 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_private.h"
+
+#ifdef LTC_PKCS_12
+
+int pkcs12_kdf( int hash_id,
+ const unsigned char *pw, unsigned long pwlen,
+ const unsigned char *salt, unsigned long saltlen,
+ unsigned int iterations, unsigned char purpose,
+ unsigned char *out, unsigned long outlen)
+{
+ unsigned long u = hash_descriptor[hash_id].hashsize;
+ unsigned long v = hash_descriptor[hash_id].blocksize;
+ unsigned long c = (outlen + u - 1) / u;
+ unsigned long Slen = ((saltlen + v - 1) / v) * v;
+ unsigned long Plen = ((pwlen + v - 1) / v) * v;
+ unsigned long k = (Plen + Slen) / v;
+ unsigned long Alen, keylen = 0;
+ unsigned int tmp, i, j, n;
+ unsigned char ch;
+ unsigned char D[MAXBLOCKSIZE], A[MAXBLOCKSIZE], B[MAXBLOCKSIZE];
+ unsigned char *I = NULL, *key = NULL;
+ int err = CRYPT_ERROR;
+
+ LTC_ARGCHK(pw != NULL);
+ LTC_ARGCHK(salt != NULL);
+ LTC_ARGCHK(out != NULL);
+
+ key = XMALLOC(u * c);
+ I = XMALLOC(Plen + Slen);
+ if (key == NULL || I == NULL) goto DONE;
+ zeromem(key, u * c);
+
+ for (i = 0; i < v; i++) D[i] = purpose; /* D - diversifier */
+ for (i = 0; i < Slen; i++) I[i] = salt[i % saltlen];
+ for (i = 0; i < Plen; i++) I[Slen + i] = pw[i % pwlen]; /* I = Salt || Pass */
+
+ for (i = 0; i < c; i++) {
+ Alen = sizeof(A);
+ err = hash_memory_multi(hash_id, A, &Alen, D, v, I, Slen + Plen, NULL); /* A = HASH(D || I) */
+ if (err != CRYPT_OK) goto DONE;
+ for (j = 1; j < iterations; j++) {
+ err = hash_memory(hash_id, A, Alen, A, &Alen); /* A = HASH(A) */
+ if (err != CRYPT_OK) goto DONE;
+ }
+ /* fill buffer B with A */
+ for (j = 0; j < v; j++) B[j] = A[j % Alen];
+ /* B += 1 */
+ for (j = v; j > 0; j--) {
+ if (++B[j - 1] != 0) break;
+ }
+ /* I_n += B */
+ for (n = 0; n < k; n++) {
+ ch = 0;
+ for (j = v; j > 0; j--) {
+ tmp = I[n * v + j - 1] + B[j - 1] + ch;
+ ch = (unsigned char)((tmp >> 8) & 0xFF);
+ I[n * v + j - 1] = (unsigned char)(tmp & 0xFF);
+ }
+ }
+ /* store derived key block */
+ XMEMCPY(&key[keylen], A, Alen);
+ keylen += Alen;
+ }
+
+ XMEMCPY(out, key, outlen);
+ err = CRYPT_OK;
+DONE:
+ if (I) {
+ zeromem(I, Plen + Slen);
+ XFREE(I);
+ }
+ if (key) {
+ zeromem(key, u * c);
+ XFREE(key);
+ }
+ return err;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */
diff --git a/src/misc/pkcs12/pkcs12_utf8_to_utf16.c b/src/misc/pkcs12/pkcs12_utf8_to_utf16.c
new file mode 100644
index 000000000..5175a1528
--- /dev/null
+++ b/src/misc/pkcs12/pkcs12_utf8_to_utf16.c
@@ -0,0 +1,69 @@
+/* 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_private.h"
+
+#ifdef LTC_PKCS_12
+
+int pkcs12_utf8_to_utf16(const unsigned char *in, unsigned long inlen,
+ unsigned char *out, unsigned long *outlen) {
+ unsigned long len = 0;
+ const unsigned char* in_end = in + inlen;
+ const ulong32 offset[6] = {
+ 0x00000000UL, 0x00003080UL, 0x000E2080UL,
+ 0x03C82080UL, 0xFA082080UL, 0x82082080UL
+ };
+ int err = CRYPT_ERROR;
+
+ LTC_ARGCHK(in != NULL);
+ LTC_ARGCHK(out != NULL);
+ LTC_ARGCHK(outlen != NULL);
+
+ while (in < in_end) {
+ ulong32 ch = 0;
+ unsigned short extra = 0; /* 0 */
+ if (*in >= 192) extra++; /* 1 */
+ if (*in >= 224) extra++; /* 2 */
+ if (*in >= 240) extra++; /* 3 */
+ if (*in >= 248) extra++; /* 4 */
+ if (*in >= 252) extra++; /* 5 */
+ if (in + extra >= in_end) goto ERROR;
+ switch (extra) {
+ case 5: ch += *in++; ch <<= 6;
+ /* FALLTHROUGH */
+ case 4: ch += *in++; ch <<= 6;
+ /* FALLTHROUGH */
+ case 3: ch += *in++; ch <<= 6;
+ /* FALLTHROUGH */
+ case 2: ch += *in++; ch <<= 6;
+ /* FALLTHROUGH */
+ case 1: ch += *in++; ch <<= 6;
+ /* FALLTHROUGH */
+ case 0: ch += *in++;
+ }
+ ch -= offset[extra];
+ if (ch > 0xFFFF) goto ERROR;
+ if (*outlen >= len + 2) {
+ out[len] = (unsigned short)((ch >> 8) & 0xFF);
+ out[len + 1] = (unsigned char)(ch & 0xFF);
+ }
+ len += 2;
+ }
+
+ err = len > *outlen ? CRYPT_BUFFER_OVERFLOW : CRYPT_OK;
+ *outlen = len;
+ERROR:
+ return err;
+}
+
+#endif
+
+/* ref: $Format:%D$ */
+/* git commit: $Format:%H$ */
+/* commit time: $Format:%ai$ */