aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--checks/bench.cpp1
-rw-r--r--checks/common.h6
-rw-r--r--checks/dolook.cpp8
-rw-r--r--checks/ec_tests.cpp108
-rw-r--r--checks/ecdsa.cpp16
-rw-r--r--checks/misc.cpp27
-rw-r--r--checks/pk.cpp55
-rw-r--r--checks/pk_valid.dat30
-rw-r--r--checks/validate.cpp16
-rw-r--r--checks/validate.dat29
-rwxr-xr-xconfigure.py15
-rw-r--r--doc/examples/rsa_kgen.cpp2
-rw-r--r--doc/log.txt16
-rwxr-xr-xdoc/scripts/print_deps.py2
-rwxr-xr-xdoc/scripts/update_deps.py2
-rw-r--r--src/alloc/secmem.h10
-rw-r--r--src/block/aes/aes.cpp77
-rw-r--r--src/build-data/arch/ia32.txt1
-rw-r--r--src/build-data/cc/gcc.txt1
-rw-r--r--src/build-data/os/windows.txt1
-rw-r--r--src/codec/hex/hex.cpp180
-rw-r--r--src/codec/hex/hex.h108
-rw-r--r--src/codec/hex/info.txt1
-rw-r--r--src/constructs/passhash/passhash9.cpp33
-rw-r--r--src/constructs/passhash/passhash9.h16
-rw-r--r--src/constructs/tss/tss.cpp8
-rw-r--r--src/filters/data_snk.cpp29
-rw-r--r--src/filters/data_snk.h6
-rw-r--r--src/filters/data_src.cpp51
-rw-r--r--src/filters/data_src.h7
-rw-r--r--src/filters/filters.h4
-rw-r--r--src/filters/hex/hex_char.cpp48
-rw-r--r--src/filters/hex_filt/hex_filt.cpp (renamed from src/filters/hex/hex.cpp)104
-rw-r--r--src/filters/hex_filt/hex_filt.h (renamed from src/filters/hex/hex.h)36
-rw-r--r--src/filters/hex_filt/info.txt (renamed from src/filters/hex/info.txt)2
-rw-r--r--src/libstate/get_enc.cpp8
-rw-r--r--src/mac/hmac/hmac.cpp2
-rw-r--r--src/math/bigint/big_code.cpp32
-rw-r--r--src/math/bigint/bigint.h6
-rw-r--r--src/math/bigint/info.txt2
-rw-r--r--src/math/bigint/mp_msvc64/info.txt (renamed from src/math/bigint/mp_amd64_msvc/info.txt)0
-rw-r--r--src/math/bigint/mp_msvc64/mp_asm.h (renamed from src/math/bigint/mp_amd64_msvc/mp_asm.h)2
-rw-r--r--src/pbkdf/pbkdf.h5
-rw-r--r--src/pbkdf/pbkdf2/pbkdf2.cpp15
-rw-r--r--src/pbkdf/pbkdf2/pbkdf2.h4
-rw-r--r--src/ssl/info.txt20
-rw-r--r--src/sym_algo/symkey.cpp19
-rw-r--r--src/utils/datastor/datastor.cpp19
-rw-r--r--src/utils/datastor/info.txt1
-rw-r--r--src/utils/dyn_load/dyn_load.cpp34
-rw-r--r--src/utils/dyn_load/dyn_load.h5
-rw-r--r--src/wrap/perl-xs/Botan.xs2
52 files changed, 789 insertions, 443 deletions
diff --git a/checks/bench.cpp b/checks/bench.cpp
index 4f1d43a4a..20a1e9fa5 100644
--- a/checks/bench.cpp
+++ b/checks/bench.cpp
@@ -14,6 +14,7 @@
#include <botan/engine.h>
#include <botan/parsing.h>
#include <botan/symkey.h>
+#include <botan/hex.h>
#include <chrono>
diff --git a/checks/common.h b/checks/common.h
index 1b1e89bbf..493e2fc74 100644
--- a/checks/common.h
+++ b/checks/common.h
@@ -11,6 +11,7 @@
#include <botan/secmem.h>
#include <botan/filter.h>
#include <botan/rng.h>
+#include <botan/hex.h>
using Botan::byte;
using Botan::u32bit;
@@ -21,9 +22,6 @@ void strip_newlines(std::string& line);
void strip(std::string& line);
std::vector<std::string> parse(const std::string& line);
-std::string hex_encode(const byte in[], u32bit len);
-Botan::SecureVector<byte> decode_hex(const std::string&);
-
Botan::Filter* lookup(const std::string& algname,
const std::vector<std::string>& params);
@@ -75,7 +73,7 @@ class Fixed_Output_RNG : public Botan::RandomNumberGenerator
}
Fixed_Output_RNG(const std::string& in_str)
{
- Botan::SecureVector<byte> in = decode_hex(in_str);
+ Botan::SecureVector<byte> in = Botan::hex_decode(in_str);
buf.insert(buf.end(), in.begin(), in.begin() + in.size());
}
diff --git a/checks/dolook.cpp b/checks/dolook.cpp
index 71bb65725..92f7381c2 100644
--- a/checks/dolook.cpp
+++ b/checks/dolook.cpp
@@ -175,19 +175,19 @@ Filter* lookup_rng(const std::string& algname,
#if defined(BOTAN_HAS_DES)
if(algname == "X9.31-RNG(TripleDES)")
prng = new ANSI_X931_RNG(new TripleDES,
- new Fixed_Output_RNG(decode_hex(key)));
+ new Fixed_Output_RNG(hex_decode(key)));
#endif
#if defined(BOTAN_HAS_AES)
if(algname == "X9.31-RNG(AES-128)")
prng = new ANSI_X931_RNG(new AES_128,
- new Fixed_Output_RNG(decode_hex(key)));
+ new Fixed_Output_RNG(hex_decode(key)));
else if(algname == "X9.31-RNG(AES-192)")
prng = new ANSI_X931_RNG(new AES_192,
- new Fixed_Output_RNG(decode_hex(key)));
+ new Fixed_Output_RNG(hex_decode(key)));
else if(algname == "X9.31-RNG(AES-256)")
prng = new ANSI_X931_RNG(new AES_256,
- new Fixed_Output_RNG(decode_hex(key)));
+ new Fixed_Output_RNG(hex_decode(key)));
#endif
#endif
diff --git a/checks/ec_tests.cpp b/checks/ec_tests.cpp
index 3d7b3a8b0..b3eac8d8e 100644
--- a/checks/ec_tests.cpp
+++ b/checks/ec_tests.cpp
@@ -71,10 +71,10 @@ void test_point_turn_on_sp_red_mul()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex(p_secp);
- SecureVector<byte> sv_a_secp = decode_hex(a_secp);
- SecureVector<byte> sv_b_secp = decode_hex(b_secp);
- SecureVector<byte> sv_G_secp_comp = decode_hex(G_secp_comp);
+ SecureVector<byte> sv_p_secp = hex_decode(p_secp);
+ SecureVector<byte> sv_a_secp = hex_decode(a_secp);
+ SecureVector<byte> sv_b_secp = hex_decode(b_secp);
+ SecureVector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
BigInt bi_p_secp = BigInt::decode(sv_p_secp.begin(), sv_p_secp.size());
BigInt bi_a_secp = BigInt::decode(sv_a_secp.begin(), sv_a_secp.size());
BigInt bi_b_secp = BigInt::decode(sv_b_secp.begin(), sv_b_secp.size());
@@ -134,10 +134,10 @@ void test_coordinates()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -191,7 +191,7 @@ void test_point_mult ()
const CurveGFp& curve = secp160r1.get_curve();
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_G_secp_comp = decode_hex(G_secp_comp);
+ SecureVector<byte> sv_G_secp_comp = hex_decode(G_secp_comp);
PointGFp p_G = OS2ECP(sv_G_secp_comp, curve);
BigInt d_U("0xaa374ffc3ce144e6b073307972cb6d57b2a4e982");
@@ -210,10 +210,10 @@ void test_point_negative()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
BigInt bi_b_secp = BigInt::decode ( sv_b_secp.begin(), sv_b_secp.size() );
@@ -237,7 +237,7 @@ void test_zeropoint()
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
@@ -286,7 +286,7 @@ void test_calc_with_zeropoint()
std::cout << "." << std::flush;
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp("0xffffffffffffffffffffffffffffffff7fffffff");
BigInt bi_a_secp("0xffffffffffffffffffffffffffffffff7ffffffc");
BigInt bi_b_secp("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
@@ -322,10 +322,10 @@ void test_add_point()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
BigInt bi_b_secp = BigInt::decode ( sv_b_secp.begin(), sv_b_secp.size() );
@@ -358,10 +358,10 @@ void test_sub_point()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
BigInt bi_b_secp = BigInt::decode ( sv_b_secp.begin(), sv_b_secp.size() );
@@ -393,10 +393,10 @@ void test_mult_point()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
BigInt bi_b_secp = BigInt::decode ( sv_b_secp.begin(), sv_b_secp.size() );
@@ -422,10 +422,10 @@ void test_basic_operations()
std::string a_secp = "ffffffffffffffffffffffffffffffff7ffffffc";
std::string b_secp = "1c97befc54bd7a8b65acf89f81d4d4adc565fa45";
std::string G_secp_comp = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
BigInt bi_b_secp = BigInt::decode ( sv_b_secp.begin(), sv_b_secp.size() );
@@ -485,10 +485,10 @@ void test_enc_dec_compressed_160()
std::string G_secp_comp = "024A96B5688EF573284664698968C38BB913CBFC82";
std::string G_order_secp_comp = "0100000000000000000001F4C8F927AED3CA752257";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -514,10 +514,10 @@ void test_enc_dec_compressed_256()
std::string G_secp_comp = "036B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296";
std::string G_order_secp_comp = "ffffffff00000000ffffffffffffffffBCE6FAADA7179E84F3B9CAC2FC632551";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -545,10 +545,10 @@ void test_enc_dec_uncompressed_112()
std::string G_secp_uncomp = "044BA30AB5E892B4E1649DD0928643ADCD46F5882E3747DEF36E956E97";
std::string G_order_secp_uncomp = "36DF0AAFD8B8D7597CA10520D04B";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_uncomp = decode_hex ( G_secp_uncomp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -574,10 +574,10 @@ void test_enc_dec_uncompressed_521()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_uncomp = decode_hex ( G_secp_uncomp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -606,10 +606,10 @@ void test_enc_dec_uncompressed_521_prime_too_large()
std::string G_secp_uncomp = "0400C6858E06B70404E9CD9E3ECB662395B4429C648139053FB521F828AF606B4D3DBAA14B5E77EFE75928FE1DC127A2ffA8DE3348B3C1856A429BF97E7E31C2E5BD66011839296A789A3BC0045C8A5FB42C7D1BD998F54449579B446817AFBD17273E662C97EE72995EF42640C550B9013FAD0761353C7086A272C24088BE94769FD16650";
std::string G_order_secp_uncomp = "01ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffFA51868783BF2F966B7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409";
- SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_uncomp = decode_hex ( G_secp_uncomp );
+ SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_uncomp = hex_decode ( G_secp_uncomp );
BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_a_secp = BigInt::decode ( sv_a_secp.begin(), sv_a_secp.size() );
@@ -647,7 +647,7 @@ void test_gfp_store_restore()
std::string storrage = hex_encode(sv_mes, sv_mes.size());
// restore point (from std::string)
- SecureVector<byte> sv_new_point = decode_hex(storrage);
+ SecureVector<byte> sv_new_point = hex_decode(storrage);
PointGFp new_p = OS2ECP(sv_new_point, dom_pars.get_curve());
CHECK_MESSAGE( p == new_p, "original and restored point are different!");
@@ -661,7 +661,7 @@ void test_cdc_curve_33()
std::string G_secp_uncomp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
- SecureVector<byte> sv_G_uncomp = decode_hex ( G_secp_uncomp );
+ SecureVector<byte> sv_G_uncomp = hex_decode ( G_secp_uncomp );
BigInt bi_p_secp = BigInt("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
BigInt bi_a_secp("0xa377dede6b523333d36c78e9b0eaa3bf48ce93041f6d4fc34014d08f6833807498deedd4290101c5866e8dfb589485d13357b9e78c2d7fbe9fe");
@@ -688,7 +688,7 @@ void test_more_zeropoint()
// by Falko
std::string G = "024a96b5688ef573284664698968c38bb913cbfc82";
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G );
BigInt bi_p("0xffffffffffffffffffffffffffffffff7fffffff");
BigInt bi_a("0xffffffffffffffffffffffffffffffff7ffffffc");
BigInt bi_b("0x1c97befc54bd7a8b65acf89f81d4d4adc565fa45");
diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp
index 277239e72..48502721f 100644
--- a/checks/ecdsa.cpp
+++ b/checks/ecdsa.cpp
@@ -164,7 +164,7 @@ void test_sign_then_ver(RandomNumberGenerator& rng)
PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
- SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> msg = hex_decode("12345678901234567890abcdef12");
SecureVector<byte> sig = signer.sign_message(msg, rng);
PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
@@ -289,11 +289,11 @@ void test_create_and_verify(RandomNumberGenerator& rng)
std::string G_secp_comp = "04081523d03d4f12cd02879dea4bf6a4f3a7df26ed888f10c5b2235a1274c386a2f218300dee6ed217841164533bcdc903f07a096f9fbf4ee95bac098a111f296f5830fe5c35b3e344d5df3a2256985f64fbe6d0edcc4c61d18bef681dd399df3d0194c5a4315e012e0245ecea56365baa9e8be1f7";
std::string order_g = "0e1a16196e6000000000bc7f1618d867b15bb86474418f";
- // ::SecureVector<byte> sv_p_secp = decode_hex ( p_secp );
- SecureVector<byte> sv_a_secp = decode_hex ( a_secp );
- SecureVector<byte> sv_b_secp = decode_hex ( b_secp );
- SecureVector<byte> sv_G_secp_comp = decode_hex ( G_secp_comp );
- SecureVector<byte> sv_order_g = decode_hex ( order_g );
+ // ::SecureVector<byte> sv_p_secp = hex_decode ( p_secp );
+ SecureVector<byte> sv_a_secp = hex_decode ( a_secp );
+ SecureVector<byte> sv_b_secp = hex_decode ( b_secp );
+ SecureVector<byte> sv_G_secp_comp = hex_decode ( G_secp_comp );
+ SecureVector<byte> sv_order_g = hex_decode ( order_g );
// BigInt bi_p_secp = BigInt::decode ( sv_p_secp.begin(), sv_p_secp.size() );
BigInt bi_p_secp("2117607112719756483104013348936480976596328609518055062007450442679169492999007105354629105748524349829824407773719892437896937279095106809");
@@ -365,7 +365,7 @@ void test_curve_registry(RandomNumberGenerator& rng)
PK_Signer signer(ecdsa, "EMSA1(SHA-1)");
PK_Verifier verifier(ecdsa, "EMSA1(SHA-1)");
- SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> msg = hex_decode("12345678901234567890abcdef12");
SecureVector<byte> sig = signer.sign_message(msg, rng);
if(!verifier.verify_message(msg, sig))
@@ -383,7 +383,7 @@ void test_read_pkcs8(RandomNumberGenerator& rng)
{
std::cout << "." << std::flush;
- SecureVector<byte> msg = decode_hex("12345678901234567890abcdef12");
+ SecureVector<byte> msg = hex_decode("12345678901234567890abcdef12");
try
{
diff --git a/checks/misc.cpp b/checks/misc.cpp
index ff95ed10f..31bc60435 100644
--- a/checks/misc.cpp
+++ b/checks/misc.cpp
@@ -8,10 +8,6 @@
#include <vector>
#include <string>
-#include <botan/pipe.h>
-#include <botan/hex.h>
-using namespace Botan;
-
#include "common.h"
void strip_comments(std::string& line)
@@ -40,29 +36,6 @@ void strip(std::string& line)
line = line.erase(line.find('\t'), 1);
}
-SecureVector<byte> decode_hex(const std::string& in)
- {
- SecureVector<byte> result;
-
- try {
- Botan::Pipe pipe(new Botan::Hex_Decoder);
- pipe.process_msg(in);
- result = pipe.read_all();
- }
- catch(std::exception)
- {
- result.destroy();
- }
- return result;
- }
-
-std::string hex_encode(const byte in[], u32bit len)
- {
- Botan::Pipe pipe(new Botan::Hex_Encoder);
- pipe.process_msg(in, len);
- return pipe.read_all_as_string();
- }
-
std::vector<std::string> parse(const std::string& line)
{
const char DELIMITER = ':';
diff --git a/checks/pk.cpp b/checks/pk.cpp
index 834e0031d..fe8df10b3 100644
--- a/checks/pk.cpp
+++ b/checks/pk.cpp
@@ -64,10 +64,19 @@ using namespace Botan;
namespace {
-BigInt to_bigint(const std::string& h)
+BigInt to_bigint(std::string input)
{
- return BigInt::decode(reinterpret_cast<const byte*>(h.data()),
- h.length(), BigInt::Hexadecimal);
+ while(input.find(' ') != std::string::npos)
+ input = input.erase(input.find(' '), 1);
+
+ while(input.find('\t') != std::string::npos)
+ input = input.erase(input.find('\t'), 1);
+
+ while(input.find('\n') != std::string::npos)
+ input = input.erase(input.find('\n'), 1);
+
+ return BigInt::decode(reinterpret_cast<const byte*>(input.data()),
+ input.length(), BigInt::Hexadecimal);
}
void dump_data(const SecureVector<byte>& out,
@@ -145,9 +154,9 @@ void validate_encryption(PK_Encryptor& e, PK_Decryptor& d,
const std::string& random, const std::string& exp,
bool& failure)
{
- SecureVector<byte> message = decode_hex(input);
- SecureVector<byte> expected = decode_hex(exp);
- Fixed_Output_RNG rng(decode_hex(random));
+ SecureVector<byte> message = hex_decode(input);
+ SecureVector<byte> expected = hex_decode(exp);
+ Fixed_Output_RNG rng(hex_decode(random));
SecureVector<byte> out = e.encrypt(message, rng);
if(out != expected)
@@ -165,9 +174,9 @@ void validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo,
RandomNumberGenerator& rng,
const std::string& exp, bool& failure)
{
- SecureVector<byte> message = decode_hex(input);
+ SecureVector<byte> message = hex_decode(input);
- SecureVector<byte> expected = decode_hex(exp);
+ SecureVector<byte> expected = hex_decode(exp);
SecureVector<byte> sig = s.sign_message(message, message.size(), rng);
@@ -199,7 +208,7 @@ void validate_signature(PK_Verifier& v, PK_Signer& s, const std::string& algo,
const std::string& random,
const std::string& exp, bool& failure)
{
- Fixed_Output_RNG rng(decode_hex(random));
+ Fixed_Output_RNG rng(hex_decode(random));
validate_signature(v, s, algo, input, rng, exp, failure);
}
@@ -208,7 +217,7 @@ void validate_kas(PK_Key_Agreement& kas, const std::string& algo,
const SecureVector<byte>& pubkey, const std::string& output,
u32bit keylen, bool& failure)
{
- SecureVector<byte> expected = decode_hex(output);
+ SecureVector<byte> expected = hex_decode(output);
SecureVector<byte> got = kas.derive_key(keylen,
pubkey, pubkey.size()).bits_of();
@@ -310,8 +319,8 @@ u32bit validate_elg_enc(const std::string& algo,
validate_encryption(e, d, algo, str[4], str[5], str[6], failure);
}
else
- validate_decryption(d, algo, decode_hex(str[5]),
- decode_hex(str[4]), failure);
+ validate_decryption(d, algo, hex_decode(str[5]),
+ hex_decode(str[4]), failure);
return (failure ? 1 : 0);
#endif
@@ -358,8 +367,8 @@ u32bit validate_rsa_ver(const std::string& algo,
PK_Verifier v(key, emsa);
- SecureVector<byte> msg = decode_hex(str[2]);
- SecureVector<byte> sig = decode_hex(str[3]);
+ SecureVector<byte> msg = hex_decode(str[2]);
+ SecureVector<byte> sig = hex_decode(str[3]);
bool passed = true;
passed = v.verify_message(msg, msg.size(), sig, sig.size());
@@ -390,8 +399,8 @@ u32bit validate_rsa_ver_x509(const std::string& algo,
PK_Verifier v(*rsakey, emsa);
- SecureVector<byte> msg = decode_hex(str[1]);
- SecureVector<byte> sig = decode_hex(str[2]);
+ SecureVector<byte> msg = hex_decode(str[1]);
+ SecureVector<byte> sig = hex_decode(str[2]);
bool passed = v.verify_message(msg, msg.size(), sig, sig.size());
return (passed ? 0 : 1);
@@ -414,8 +423,8 @@ u32bit validate_rw_ver(const std::string& algo,
PK_Verifier v(key, emsa);
- SecureVector<byte> msg = decode_hex(str[2]);
- SecureVector<byte> sig = decode_hex(str[3]);
+ SecureVector<byte> msg = hex_decode(str[2]);
+ SecureVector<byte> sig = hex_decode(str[3]);
bool passed = true;
passed = v.verify_message(msg, msg.size(), sig, sig.size());
@@ -522,7 +531,7 @@ u32bit validate_gost_ver(const std::string& algo,
EC_Domain_Params group(OIDS::lookup(str[0]));
- PointGFp public_point = OS2ECP(decode_hex(str[1]), group.get_curve());
+ PointGFp public_point = OS2ECP(hex_decode(str[1]), group.get_curve());
GOST_3410_PublicKey gost(group, public_point);
@@ -530,8 +539,8 @@ u32bit validate_gost_ver(const std::string& algo,
PK_Verifier v(gost, emsa);
- SecureVector<byte> msg = decode_hex(str[2]);
- SecureVector<byte> sig = decode_hex(str[3]);
+ SecureVector<byte> msg = hex_decode(str[2]);
+ SecureVector<byte> sig = hex_decode(str[3]);
bool passed = v.verify_message(msg, msg.size(), sig, sig.size());
return (passed ? 0 : 1);
@@ -562,8 +571,8 @@ u32bit validate_dsa_ver(const std::string& algo,
PK_Verifier v(*dsakey, emsa);
- SecureVector<byte> msg = decode_hex(str[1]);
- SecureVector<byte> sig = decode_hex(str[2]);
+ SecureVector<byte> msg = hex_decode(str[1]);
+ SecureVector<byte> sig = hex_decode(str[2]);
v.set_input_format(DER_SEQUENCE);
bool passed = v.verify_message(msg, msg.size(), sig, sig.size());
diff --git a/checks/pk_valid.dat b/checks/pk_valid.dat
index 45a2cea2b..3220ba29e 100644
--- a/checks/pk_valid.dat
+++ b/checks/pk_valid.dat
@@ -1705,7 +1705,9 @@ FBB75326D3DC76F89BB46C6D66A8CE0F0E2167309750D5CA6158BF7306DA8C6ED2D0E9D62524\
D92E794F850892F13B6CBBCE1C67E1C670ACF8DCF8DEEA2DF958529C1CF5D89E30D5D05787A2\
5602AAFFA5B5007800B3:\
7072696F6E636F7270::\
-0EEA6057C2FE9892BE77B7A7E38E00EF2537D4E8EE7F2B856CBD4B29C7B5E38299D02B2A845991C2A8F4AC6BFA5E58A34139716B20CDD27471F549037D07DB76A02C3372AE2FAFDA3BF1414E9BFF71C0DFA03AA0409D62CC9D5FEEAA7B42D52A
+0EEA6057C2FE9892BE77B7A7E38E00EF2537D4E8EE7F2B856CBD4B29C7B5E38299D02B2A8459\
+91C2A8F4AC6BFA5E58A34139716B20CDD27471F549037D07DB76A02C3372AE2FAFDA3BF1414E\
+9BFF71C0DFA03AA0409D62CC9D5FEEAA7B42D52A
10001:\
D620C17FD01B4B8986B2C4934F2B78CF9EA43B862D70AB88763E2B133D7398E4E6633D8DD408\
@@ -1713,7 +1715,10 @@ D620C17FD01B4B8986B2C4934F2B78CF9EA43B862D70AB88763E2B133D7398E4E6633D8DD408\
E0B20464041EC9EC74FE86CC00D7191A1F6730E05C80ECE6B7714CE158ED72BDF3215D96E3E8\
ADDB4D8123B6006509362BE8B2EFC853C959AAB0D21C09A2B835:\
7072696F6E636F7270::\
-A10AD2439FA7F9638298CAD2E8BD18830A580555F0D0A71CB2DAAB2392ED61FB6C3659FA706D434C7F373761165580D9E3B4B72423AE3C27F71C53DE3DD812BB064C3F52A86C2C5E42BA10BAF4C90E2064D988B56C59186B48D16B151FFDA0859FE41C585D388884EBF6B2E570A69F5EF5B5D96E005BF353076662F7697DEA3A
+A10AD2439FA7F9638298CAD2E8BD18830A580555F0D0A71CB2DAAB2392ED61FB6C3659FA706D\
+434C7F373761165580D9E3B4B72423AE3C27F71C53DE3DD812BB064C3F52A86C2C5E42BA10BA\
+F4C90E2064D988B56C59186B48D16B151FFDA0859FE41C585D388884EBF6B2E570A69F5EF5B5\
+D96E005BF353076662F7697DEA3A
10001:\
E3BAAE58893F9DEE6CFF0F0551AE0C95B1E8EC0F3F7C9E271C6DB3D84A24EB37FF785425FE90\
@@ -1721,7 +1726,10 @@ E3BAAE58893F9DEE6CFF0F0551AE0C95B1E8EC0F3F7C9E271C6DB3D84A24EB37FF785425FE90\
CEE7816F245FE20C99EB54A067340ED98A2003958186E78E2F9BAC8242E6F894FAA2726374E8\
86CB3B718399BF5DA67B2558E086993897BEF2F6C580C7E04201:\
7072696F6E636F7270::\
-85EFECF3B1EEB4386A61AA4AB0D0A4335F64C56C24C258AECEE4CA8547638F52858FFB7842EA399E3EC97C882891E9B52A76D3A4B76BBB843D6165EF06181BC887B342900C0EDFD42EC355967AD052A76A760EF2130499A24FD9A059C79C334C586AB44C400278C5DEA17BFA9CC5127CBF392DC74B65458627A34437A8AE9FDE
+85EFECF3B1EEB4386A61AA4AB0D0A4335F64C56C24C258AECEE4CA8547638F52858FFB7842EA\
+399E3EC97C882891E9B52A76D3A4B76BBB843D6165EF06181BC887B342900C0EDFD42EC35596\
+7AD052A76A760EF2130499A24FD9A059C79C334C586AB44C400278C5DEA17BFA9CC5127CBF39\
+2DC74B65458627A34437A8AE9FDE
10001:\
FA1CAC0BF58B08369A927D3B2FDE1C1F926A2EA31F26C2AA49EBA42DFBB8661E79660928D476\
@@ -1812,7 +1820,10 @@ F74FAFF1F8533804A2ED81EA92E9872505551954DF623503615B558EFCA368D32C7CC10B39679\
BBB2824D01BF3A3820C349D77CB6761081590767A8BD5753AAF71893C9220080ADF01D89D5217\
FE714FCAD68AFEAD388F103DA7273AE2A67414198CE7022DD29:\
7072696F6E636F7270::\
-858691CD4D14CD74841AEA3CF1564734D939CB7D8B4341BA1F74D88FDA993761AA5D850B258BDBEB228BECCC0F6B6C0EF96A3DEDC43A7078BF05D9FF4EA0224184572DEB43D77F0C9162CE69192EE3E50402579317B56838AEAC091369F216F19D271E7141149F1A5760071A65F08515D7226336C9C5EA6CF35691B1C92451C4
+858691CD4D14CD74841AEA3CF1564734D939CB7D8B4341BA1F74D88FDA993761AA5D850B258BD\
+BEB228BECCC0F6B6C0EF96A3DEDC43A7078BF05D9FF4EA0224184572DEB43D77F0C9162CE6919\
+2EE3E50402579317B56838AEAC091369F216F19D271E7141149F1A5760071A65F08515D722633\
+6C9C5EA6CF35691B1C92451C4
10001:\
F6B23AAC1C0FD29065D68C3DE26B5868E7ECEB7CCB2AA9A2DAD4497678E77547AD8BA78BFED51\
@@ -2030,8 +2041,10 @@ BC0E019934742993FCAA113DB15F6B24B74AA134600E127C8F7:\
AE13AF7CAE023450D65731DE8
10001:\
-1C136DA3E140F55A5F07C1F314FBE3D97E4A69DF7456E95E4E06405375071405426D81261E4D1D089754D50C4C4AF42BF4D:\
-1F7303CD6DC61CC6833563E83C3AF5706E20BC7651257C0F890F2C8B1CB78554EE43715EBC1D026908CD78F56B489B33F03:\
+1C136DA3E140F55A5F07C1F314FBE3D97E4A69DF7456E95E4E06405375071405\
+426D81261E4D1D089754D50C4C4AF42BF4D:\
+1F7303CD6DC61CC6833563E83C3AF5706E20BC7651257C0F890F2C8B1CB78554\
+EE43715EBC1D026908CD78F56B489B33F03:\
3021300906052B0E03021A05000414C26EDACE80B947FCFF75EC4CEC1AF0D1872674A9::\
01E6EF82D25EE46471883D373869C553A54E0C256968958FBAC41D79C571940E523B96494360E\
EEEC45DA943F94CE44DDBDFBF141E8F7B251E44EC47B64DDEEE2873C4B78A849242F3377F135E\
@@ -2522,7 +2535,10 @@ DAA28E8CB6CCBF9A4EA5884AF7C791DC08BAEFEAB75F23EADE53A7D29D26B35CBE806C65886C\
776972656C65737320636F6D6D756E69636174696F6E732C20656D6265646465642073797374\
656D732C206D6963726F6B65726E656C20617263686974656374757265732C206D7574616E74\
732C206379626F726765722E0A0A776520646F6E277420746F79::\
-23223B652D5D0A17866DE55C77ECDA94A3B69ABB8CE335E5ACC03FE33A7D2D8257FF4227036DCAAD05820C135E2E5F332A01D77BE4FB3013529F6B1B9255669FFB64C134DBF01995CBF24C1735AE0028381B40A657E5C28D983478632C7975CD0C776CD8CFC3796DE7D8FDA86A0112ECE359361B35EB6DBDC7F5E44D469AED13
+23223B652D5D0A17866DE55C77ECDA94A3B69ABB8CE335E5ACC03FE33A7D2D8257FF4227036D\
+CAAD05820C135E2E5F332A01D77BE4FB3013529F6B1B9255669FFB64C134DBF01995CBF24C17\
+35AE0028381B40A657E5C28D983478632C7975CD0C776CD8CFC3796DE7D8FDA86A0112ECE359\
+361B35EB6DBDC7F5E44D469AED13
10001:\
D3B065134310F6A02A68E78829DBE58C5AFB148D95B30C7E54D8F463F0A66DFD3A78E2A15A26\
diff --git a/checks/validate.cpp b/checks/validate.cpp
index 68035f293..e1d5117a5 100644
--- a/checks/validate.cpp
+++ b/checks/validate.cpp
@@ -71,12 +71,17 @@ bool test_passhash(RandomNumberGenerator& rng)
std::cout << "." << std::flush;
- std::string gen_hash = generate_passhash9(input, rng, 5);
+ for(byte alg_id = 0; alg_id <= 2; ++alg_id)
+ {
+ std::string gen_hash = generate_passhash9(input, alg_id, rng, 1);
- if(!check_passhash9(input, gen_hash))
- return false;
+ if(!check_passhash9(input, gen_hash))
+ return false;
+
+ std::cout << "." << std::flush;
+ }
- std::cout << "." << std::endl;;
+ std::cout << std::endl;
#endif
@@ -91,7 +96,6 @@ bool failed_test(const std::string&, std::vector<std::string>, bool, bool,
std::vector<std::string> parse(const std::string&);
void strip(std::string&);
-Botan::SecureVector<byte> decode_hex(const std::string&);
u32bit do_validation_tests(const std::string& filename,
RandomNumberGenerator& rng,
@@ -295,7 +299,7 @@ bool failed_test(const std::string& algo,
pipe.append(test);
pipe.append(new Botan::Hex_Encoder);
- Botan::SecureVector<byte> data = decode_hex(in);
+ Botan::SecureVector<byte> data = Botan::hex_decode(in);
const byte* data_ptr = data;
// this can help catch errors with buffering, etc
diff --git a/checks/validate.dat b/checks/validate.dat
index cea1f18fc..fc82276a1 100644
--- a/checks/validate.dat
+++ b/checks/validate.dat
@@ -59316,6 +59316,14 @@ D988CE60222F674894349F1B4B89C13C6248468CE9B088CC62A52AE3A8A80D5A\
48CEEB6308B87D46E95D656112CDF18D97915F9765658957
4142434445464748494A4B4C4D4E4F505152535455565758595A6162636465666768696A6B6\
+C6D6E6F707172737475767778797A303132333435363738392B2D:\
+F71C8583902AFB879EDFE610F82C0D4786A3A534504486B5
+
+4142434445464748494A4B4C4D4E4F505152535455565758595A3D6162636465\
+666768696A6B6C6D6E6F707172737475767778797A2B30313233343536373839:\
+48CEEB6308B87D46E95D656112CDF18D97915F9765658957
+
+4142434445464748494A4B4C4D4E4F505152535455565758595A6162636465666768696A6B6\
C6D6E6F707172737475767778797A303132333435363738392B2D4142434445464748494A4B\
4C4D4E4F505152535455565758595A6162636465666768696A6B6C6D6E6F707172737475767\
778797A303132333435363738392B2D:\
@@ -59325,6 +59333,18 @@ C54034E5B43EB8005848A7E0AE6AAC76E4FF590AE715FD25
2C20627920526F737320416E646572736F6E20616E6420456C6920426968616D:\
8A866829040A410C729AD23F5ADA711603B3CDD357E4C15E
+5469676572202D20412046617374204E657720486173682046756E6374696F6E\
+2C20627920526F737320416E646572736F6E20616E6420456C6920426968616D\
+2C2070726F63656564696E6773206F66204661737420536F6674776172652045\
+6E6372797074696F6E20332C2043616D6272696467652E:\
+CE55A6AFD591F5EBAC547FF84F89227F9331DAB0B611C889
+
+5469676572202D20412046617374204E657720486173682046756E6374696F6E\
+2C20627920526F737320416E646572736F6E20616E6420456C6920426968616D\
+2C2070726F63656564696E6773206F66204661737420536F6674776172652045\
+6E6372797074696F6E20332C2043616D6272696467652C20313939362E:\
+631ABDD103EB9A3D245B6DFD4D77B257FC7439501D1568DD
+
[Whirlpool]
:19FA61D75522A4669B44E39C1D2E1726C530232130D407F89AFEE0964997F7A7\
3E83BE698B288FEBCF88E3E03C4F0757EA8964E59B63D93708B138CC42A66EB3
@@ -60624,6 +60644,10 @@ CCFC44C09339040E55D3F7F76CA6EF838FDE928717241DEB9AC1A4EF45A27711:20:2001
BC8BC53D4604977C3ADB1D19C15E87B77A84C2F6:14:10000
[PBKDF2(SHA-1)]
+:\
+59B2B1143B4CB1059EC58D9722FB1C72471E0D85C6F7543BA5228526375B0127:\
+0001020304050607:32:10000
+
6A79756571677872736367676C707864796B6366:\
DF6D9D72872404BF73E708CF3B7D:\
9B56E55328A4C97A250738F8DBA1B992E8A1B508:14:10000
@@ -60660,6 +60684,11 @@ C9A0B2622F13916036E29E7462E206E8BA5B50CE9212752EB8EA2A4AA7B40A4CC1BF:\
350381FADEAEB560DC447AFC68A6B47E6EA1E7412F6CF7B2D82342FCCD11D3B4:\
A39B76C6EEC8374A11493AD08C246A3E40DFAE5064F4EE3489C273646178:64:1000
+[PBKDF2(CMAC(Blowfish))]
+7871796668727865686965646C6865776E76626A:\
+43734BADB91F5D89DB20B469CD2EF376CAABC226EE3952872050428EFB5E3026:\
+24A1A50B17D63EE8394B69FC70887F4F94883D68:32:5
+
# MARKER: Encoders/Decoders
# Format is input:output
diff --git a/configure.py b/configure.py
index 2f5689f9f..7077aff3a 100755
--- a/configure.py
+++ b/configure.py
@@ -160,7 +160,7 @@ def process_command_line(args):
dest='unaligned_mem', action='store_false',
help=SUPPRESS_HELP)
- for isa_extn_name in ['SSE2', 'SSSE3', 'AltiVec', 'AES-NI']:
+ for isa_extn_name in ['SSE2', 'SSSE3', 'AltiVec', 'AES-NI', 'movbe']:
isa_extn = isa_extn_name.lower()
target_group.add_option('--enable-%s' % (isa_extn),
@@ -344,9 +344,10 @@ def process_command_line(args):
options.disable_isa_extns.append(isa)
for isa in options.enable_isa_extns:
- for dep in isa_deps.get(isa, '').split(','):
- if not enabled_or_disabled_isa(dep):
- options.enable_isa_extns.append(dep)
+ if isa in isa_deps:
+ for dep in isa_deps.get(isa, '').split(','):
+ if not enabled_or_disabled_isa(dep):
+ options.enable_isa_extns.append(dep)
return options
@@ -596,10 +597,8 @@ class ArchInfo(object):
if self.basename != options.cpu:
macros.append('TARGET_CPU_IS_%s' % (form_macro(options.cpu)))
- enabled_isas = set(flatten(
- [self.isa_extensions_in(options.cpu),
- options.enable_isa_extns]))
-
+ enabled_isas = set(self.isa_extensions_in(options.cpu) +
+ options.enable_isa_extns)
disabled_isas = set(options.disable_isa_extns)
isa_extensions = sorted(enabled_isas - disabled_isas)
diff --git a/doc/examples/rsa_kgen.cpp b/doc/examples/rsa_kgen.cpp
index 1108b46db..f4566263b 100644
--- a/doc/examples/rsa_kgen.cpp
+++ b/doc/examples/rsa_kgen.cpp
@@ -30,7 +30,7 @@ int main(int argc, char* argv[])
}
u32bit bits = std::atoi(argv[1]);
- if(bits < 1024 || bits > 4096)
+ if(bits < 1024 || bits > 16384)
{
std::cout << "Invalid argument for bitsize" << std::endl;
return 1;
diff --git a/doc/log.txt b/doc/log.txt
index f9092da21..f35bd9b8f 100644
--- a/doc/log.txt
+++ b/doc/log.txt
@@ -1,6 +1,22 @@
* 1.9.11-dev, ????-??-??
- Switch default PKCS #8 encryption algorithm from AES-128 to AES-256
+ - Use smaller tables in the first round of AES
+ - Add hex encoding/decoding functions that can be used without a Pipe
+ - Add new function MemoryRegion::truncate
+ - Allow using PBKDF2 with empty passphrases
+ - Support use of HMAC(SHA-256) and CMAC(Blowfish) in passhash9
+ - Support dynamic loading on Windows
+ - Improve support for Intel Atom processors
+
+* 1.8.10, 2010-08-31
+ - Switch default PKCS #8 encryption algorithm from 3DES to AES-256
+ - Increase default hash iterations from 2048 to 10000 in PBES1 and PBES2
+ - Use small tables in the first round of AES
+ - Add PBKDF typedef and get_pbkdf for better compatability with 1.9
+ - Add version of S2K::derive_key taking salt and iteration count
+ - Enable the /proc-walking entropy source on NetBSD
+ - Fix the doxygen makefile target
* 1.9.10, 2010-08-12
- Add a constant time AES implementation using SSSE3
diff --git a/doc/scripts/print_deps.py b/doc/scripts/print_deps.py
index b92c43310..c68fa2617 100755
--- a/doc/scripts/print_deps.py
+++ b/doc/scripts/print_deps.py
@@ -20,7 +20,7 @@ def find_deps_in(filename):
for line in open(filename).readlines():
match = regexp.match(line)
if match != None:
- yield match.group(1)
+ yield match.group(1).replace('internal/', '')
def get_dependencies(dirname):
all_dirdeps = {}
diff --git a/doc/scripts/update_deps.py b/doc/scripts/update_deps.py
index 61aa887cc..ac19885e0 100755
--- a/doc/scripts/update_deps.py
+++ b/doc/scripts/update_deps.py
@@ -14,7 +14,7 @@ def update_requires(dir, deps):
while lines.pop(start) != '</requires>':
pass
- while lines[-1] == '':
+ while len(lines) > 0 and lines[-1] == '':
lines = lines[:-1]
if len(deps) > 0:
diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h
index 13d2bfdce..f14e2a9db 100644
--- a/src/alloc/secmem.h
+++ b/src/alloc/secmem.h
@@ -162,6 +162,16 @@ class MemoryRegion
{ append(other.begin(), other.size()); }
/**
+ * Truncate the buffer to at most n elements
+ * @param n the length of the resulting buffer
+ */
+ void truncate(u32bit n)
+ {
+ if(n < used)
+ used = n;
+ }
+
+ /**
* Zeroise the bytes of this buffer. The length remains unchanged.
*/
void clear() { clear_mem(buf, allocated); }
diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp
index bf9a4198b..8783f13a0 100644
--- a/src/block/aes/aes.cpp
+++ b/src/block/aes/aes.cpp
@@ -426,15 +426,33 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
u32bit T2 = load_be<u32bit>(in, 2) ^ EK[2];
u32bit T3 = load_be<u32bit>(in, 3) ^ EK[3];
- u32bit B0, B1, B2, B3;
- B0 = TE0[get_byte(0, T0)] ^ TE1[get_byte(1, T1)] ^
- TE2[get_byte(2, T2)] ^ TE3[get_byte(3, T3)] ^ EK[4];
- B1 = TE0[get_byte(0, T1)] ^ TE1[get_byte(1, T2)] ^
- TE2[get_byte(2, T3)] ^ TE3[get_byte(3, T0)] ^ EK[5];
- B2 = TE0[get_byte(0, T2)] ^ TE1[get_byte(1, T3)] ^
- TE2[get_byte(2, T0)] ^ TE3[get_byte(3, T1)] ^ EK[6];
- B3 = TE0[get_byte(0, T3)] ^ TE1[get_byte(1, T0)] ^
- TE2[get_byte(2, T1)] ^ TE3[get_byte(3, T2)] ^ EK[7];
+ /* Use only the first 256 entries of the TE table and do the
+ * rotations directly in the code. This reduces the number of
+ * cache lines potentially used in the first round from 64 to 16
+ * (assuming a typical 64 byte cache line), which makes timing
+ * attacks a little harder; the first round is particularly
+ * vulnerable.
+ */
+
+ u32bit B0 = TE[get_byte(0, T0)] ^
+ rotate_right(TE[get_byte(1, T1)], 8) ^
+ rotate_right(TE[get_byte(2, T2)], 16) ^
+ rotate_right(TE[get_byte(3, T3)], 24) ^ EK[4];
+
+ u32bit B1 = TE[get_byte(0, T1)] ^
+ rotate_right(TE[get_byte(1, T2)], 8) ^
+ rotate_right(TE[get_byte(2, T3)], 16) ^
+ rotate_right(TE[get_byte(3, T0)], 24) ^ EK[5];
+
+ u32bit B2 = TE[get_byte(0, T2)] ^
+ rotate_right(TE[get_byte(1, T3)], 8) ^
+ rotate_right(TE[get_byte(2, T0)], 16) ^
+ rotate_right(TE[get_byte(3, T1)], 24) ^ EK[6];
+
+ u32bit B3 = TE[get_byte(0, T3)] ^
+ rotate_right(TE[get_byte(1, T0)], 8) ^
+ rotate_right(TE[get_byte(2, T1)], 16) ^
+ rotate_right(TE[get_byte(3, T2)], 24) ^ EK[7];
for(u32bit j = 2; j != ROUNDS; j += 2)
{
@@ -468,10 +486,14 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
}
/*
- Joseph Bonneau and Ilya Mironov's paper
- <a href = "http://icme2007.org/users/mironov/papers/aes-timing.pdf">
- Cache-Collision Timing Attacks Against AES</a> describes an attack
- that can recover AES keys with as few as 2<sup>13</sup> samples.
+ Joseph Bonneau and Ilya Mironov's paper "Cache-Collision Timing
+ Attacks Against AES" describes an attack that can recover AES
+ keys with as few as 2**13 samples.
+
+ http://citeseerx.ist.psu.edu/viewdoc/summary?doi=10.1.1.88.4753
+
+ They recommend using a byte-wide table, which still allows an attack
+ but increases the samples required from 2**13 to 2**25:
"""In addition to OpenSSL v. 0.9.8.(a), which was used in our
experiments, the AES implementations of Crypto++ 5.2.1 and
@@ -481,6 +503,7 @@ void AES::encrypt_n(const byte in[], byte out[], u32bit blocks) const
use a smaller byte-wide final table which lessens the effectiveness
of the attacks."""
*/
+
out[ 0] = SE[get_byte(0, B0)] ^ ME[0];
out[ 1] = SE[get_byte(1, B1)] ^ ME[1];
out[ 2] = SE[get_byte(2, B2)] ^ ME[2];
@@ -520,15 +543,25 @@ void AES::decrypt_n(const byte in[], byte out[], u32bit blocks) const
u32bit T2 = load_be<u32bit>(in, 2) ^ DK[2];
u32bit T3 = load_be<u32bit>(in, 3) ^ DK[3];
- u32bit B0, B1, B2, B3;
- B0 = TD0[get_byte(0, T0)] ^ TD1[get_byte(1, T3)] ^
- TD2[get_byte(2, T2)] ^ TD3[get_byte(3, T1)] ^ DK[4];
- B1 = TD0[get_byte(0, T1)] ^ TD1[get_byte(1, T0)] ^
- TD2[get_byte(2, T3)] ^ TD3[get_byte(3, T2)] ^ DK[5];
- B2 = TD0[get_byte(0, T2)] ^ TD1[get_byte(1, T1)] ^
- TD2[get_byte(2, T0)] ^ TD3[get_byte(3, T3)] ^ DK[6];
- B3 = TD0[get_byte(0, T3)] ^ TD1[get_byte(1, T2)] ^
- TD2[get_byte(2, T1)] ^ TD3[get_byte(3, T0)] ^ DK[7];
+ u32bit B0 = TD[get_byte(0, T0)] ^
+ rotate_right(TD[get_byte(1, T3)], 8) ^
+ rotate_right(TD[get_byte(2, T2)], 16) ^
+ rotate_right(TD[get_byte(3, T1)], 24) ^ DK[4];
+
+ u32bit B1 = TD[get_byte(0, T1)] ^
+ rotate_right(TD[get_byte(1, T0)], 8) ^
+ rotate_right(TD[get_byte(2, T3)], 16) ^
+ rotate_right(TD[get_byte(3, T2)], 24) ^ DK[5];
+
+ u32bit B2 = TD[get_byte(0, T2)] ^
+ rotate_right(TD[get_byte(1, T1)], 8) ^
+ rotate_right(TD[get_byte(2, T0)], 16) ^
+ rotate_right(TD[get_byte(3, T3)], 24) ^ DK[6];
+
+ u32bit B3 = TD[get_byte(0, T3)] ^
+ rotate_right(TD[get_byte(1, T2)], 8) ^
+ rotate_right(TD[get_byte(2, T1)], 16) ^
+ rotate_right(TD[get_byte(3, T0)], 24) ^ DK[7];
for(u32bit j = 2; j != ROUNDS; j += 2)
{
diff --git a/src/build-data/arch/ia32.txt b/src/build-data/arch/ia32.txt
index d9b09746d..c2d4d1769 100644
--- a/src/build-data/arch/ia32.txt
+++ b/src/build-data/arch/ia32.txt
@@ -61,4 +61,5 @@ intelcput2700 -> prescott
<isa_extn>
sse2:pentium4,prescott,pentium-m,atom
ssse3:atom
+movbe:atom
</isa_extn>
diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt
index ed8a2abe6..6eeb837ed 100644
--- a/src/build-data/cc/gcc.txt
+++ b/src/build-data/cc/gcc.txt
@@ -45,6 +45,7 @@ ppc601 -> "-mpowerpc -mcpu=601"
# Until GCC gets -march support for these models
nehalem -> "-march=core2 -msse4.1 -msse4.2"
westmere -> "-march=core2 -maes -msse4.1 -msse4.2"
+atom -> "-march=i686 -msse2 -mssse3"
cellppu -> ""
alpha-ev68 -> "-mcpu=ev6"
alpha-ev7 -> "-mcpu=ev6"
diff --git a/src/build-data/os/windows.txt b/src/build-data/os/windows.txt
index 2d435535c..30a6b77f8 100644
--- a/src/build-data/os/windows.txt
+++ b/src/build-data/os/windows.txt
@@ -12,6 +12,7 @@ install_cmd_exec "copy"
<target_features>
gmtime_s
+loadlibrary
win32_get_systemtime
win32_query_perf_counter
win32_virtual_lock
diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp
new file mode 100644
index 000000000..70e819906
--- /dev/null
+++ b/src/codec/hex/hex.cpp
@@ -0,0 +1,180 @@
+/*
+* Hex Encoding and Decoding
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#include <botan/hex.h>
+#include <botan/mem_ops.h>
+#include <stdexcept>
+
+namespace Botan {
+
+void hex_encode(char output[],
+ const byte input[],
+ u32bit input_length,
+ bool uppercase)
+ {
+ static const byte BIN_TO_HEX_UPPER[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'A', 'B', 'C', 'D', 'E', 'F' };
+
+ static const byte BIN_TO_HEX_LOWER[16] = {
+ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
+ 'a', 'b', 'c', 'd', 'e', 'f' };
+
+ const byte* tbl = uppercase ? BIN_TO_HEX_UPPER : BIN_TO_HEX_LOWER;
+
+ for(u32bit i = 0; i != input_length; ++i)
+ {
+ byte x = input[i];
+ output[2*i ] = tbl[(x >> 4) & 0x0F];
+ output[2*i+1] = tbl[(x ) & 0x0F];
+ }
+ }
+
+std::string hex_encode(const byte input[],
+ u32bit input_length,
+ bool uppercase)
+ {
+ std::string output(2 * input_length, 0);
+ hex_encode(&output[0], input, input_length, uppercase);
+ return output;
+ }
+
+u32bit hex_decode(byte output[],
+ const char input[],
+ u32bit input_length,
+ u32bit& input_consumed,
+ bool ignore_ws)
+ {
+ /*
+ * Mapping of hex characters to either their binary equivalent
+ * or to an error code.
+ * If valid hex (0-9 A-F a-f), the value.
+ * If whitespace, then 0x80
+ * Otherwise 0xFF
+ * Warning: this table assumes ASCII character encodings
+ */
+
+ static const byte HEX_TO_BIN[256] = {
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80,
+ 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0x80, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x00, 0x01,
+ 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E,
+ 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x0A, 0x0B, 0x0C,
+ 0x0D, 0x0E, 0x0F, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
+
+ byte* out_ptr = output;
+ bool top_nibble = true;
+
+ clear_mem(output, input_length / 2);
+
+ for(u32bit i = 0; i != input_length; ++i)
+ {
+ const byte bin = HEX_TO_BIN[(byte)input[i]];
+
+ if(bin >= 0x10)
+ {
+ if(bin == 0x80 && ignore_ws)
+ continue;
+
+ std::string bad_char(1, input[i]);
+ if(bad_char == "\t")
+ bad_char = "\\t";
+ else if(bad_char == "\n")
+ bad_char = "\\n";
+
+ throw std::invalid_argument(
+ std::string("hex_decode: invalid hex character '") +
+ bad_char + "'");
+ }
+
+ *out_ptr |= bin << (top_nibble*4);
+
+ top_nibble = !top_nibble;
+ if(top_nibble)
+ ++out_ptr;
+ }
+
+ input_consumed = input_length;
+ u32bit written = (out_ptr - output);
+
+ /*
+ * We only got half of a byte at the end; zap the half-written
+ * output and mark it as unread
+ */
+ if(!top_nibble)
+ {
+ *out_ptr = 0;
+ input_consumed -= 1;
+ }
+
+ return written;
+ }
+
+u32bit hex_decode(byte output[],
+ const char input[],
+ u32bit input_length,
+ bool ignore_ws)
+ {
+ u32bit consumed = 0;
+ u32bit written = hex_decode(output, input, input_length,
+ consumed, ignore_ws);
+
+ if(consumed != input_length)
+ throw std::invalid_argument("hex_decode: input did not have full bytes");
+
+ return written;
+ }
+
+u32bit hex_decode(byte output[],
+ const std::string& input,
+ bool ignore_ws)
+ {
+ return hex_decode(output, &input[0], input.length(), ignore_ws);
+ }
+
+SecureVector<byte> hex_decode(const char input[],
+ u32bit input_length,
+ bool ignore_ws)
+ {
+ SecureVector<byte> bin(input_length / 2);
+
+ u32bit written = hex_decode(&bin[0],
+ input,
+ input_length,
+ ignore_ws);
+
+ bin.truncate(written);
+ return bin;
+ }
+
+SecureVector<byte> hex_decode(const std::string& input,
+ bool ignore_ws)
+ {
+ return hex_decode(&input[0], input.size(), ignore_ws);
+ }
+
+}
diff --git a/src/codec/hex/hex.h b/src/codec/hex/hex.h
new file mode 100644
index 000000000..91a743b45
--- /dev/null
+++ b/src/codec/hex/hex.h
@@ -0,0 +1,108 @@
+/*
+* Hex Encoding and Decoding
+* (C) 2010 Jack Lloyd
+*
+* Distributed under the terms of the Botan license
+*/
+
+#ifndef BOTAN_HEX_CODEC_H__
+#define BOTAN_HEX_CODEC_H__
+
+#include <botan/secmem.h>
+#include <string>
+
+namespace Botan {
+
+/**
+* Perform hex encoding
+* @param output an array of at least input_length*2 bytes
+* @param input is some binary data
+* @param input_length length of input in bytes
+* @param uppercase should output be upper or lower case?
+*/
+void BOTAN_DLL hex_encode(char output[],
+ const byte input[],
+ u32bit input_length,
+ bool uppercase = true);
+
+/**
+* Perform hex encoding
+* @param input some input
+* @param input_length length of input in bytes
+* @param uppercase should output be upper or lower case?
+* @return hexadecimal representation of input
+*/
+std::string BOTAN_DLL hex_encode(const byte input[],
+ u32bit input_length,
+ bool uppercase = true);
+
+/**
+* Perform hex decoding
+* @param output an array of at least input_length/2 bytes
+* @param input some hex input
+* @param input_length length of input in bytes
+* @param input_consumed is an output parameter which says how many
+* bytes of input were actually consumed. If less than
+* input_length, then the range input[consumed:length]
+* should be passed in later along with more input.
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+u32bit BOTAN_DLL hex_decode(byte output[],
+ const char input[],
+ u32bit input_length,
+ u32bit& input_consumed,
+ bool ignore_ws = true);
+
+/**
+* Perform hex decoding
+* @param output an array of at least input_length/2 bytes
+* @param input some hex input
+* @param input_length length of input in bytes
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+u32bit BOTAN_DLL hex_decode(byte output[],
+ const char input[],
+ u32bit input_length,
+ bool ignore_ws = true);
+
+/**
+* Perform hex decoding
+* @param output an array of at least input_length/2 bytes
+* @param input some hex input
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return number of bytes written to output
+*/
+u32bit BOTAN_DLL hex_decode(byte output[],
+ const std::string& input,
+ bool ignore_ws = true);
+
+/**
+* Perform hex decoding
+* @param input some hex input
+* @param input_length the length of input in bytes
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return decoded hex output
+*/
+SecureVector<byte> BOTAN_DLL hex_decode(const char input[],
+ u32bit input_length,
+ bool ignore_ws = true);
+
+/**
+* Perform hex decoding
+* @param input some hex input
+* @param ignore_ws ignore whitespace on input; if false, throw an
+ exception if whitespace is encountered
+* @return decoded hex output
+*/
+SecureVector<byte> BOTAN_DLL hex_decode(const std::string& input,
+ bool ignore_ws = true);
+
+}
+
+#endif
diff --git a/src/codec/hex/info.txt b/src/codec/hex/info.txt
new file mode 100644
index 000000000..c9eb8fb73
--- /dev/null
+++ b/src/codec/hex/info.txt
@@ -0,0 +1 @@
+define HEX_CODEC
diff --git a/src/constructs/passhash/passhash9.cpp b/src/constructs/passhash/passhash9.cpp
index 920aafc4c..6618f36fa 100644
--- a/src/constructs/passhash/passhash9.cpp
+++ b/src/constructs/passhash/passhash9.cpp
@@ -23,6 +23,8 @@ const u32bit ALGID_BYTES = 1;
const u32bit SALT_BYTES = 12; // 96 bits of salt
const u32bit PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output
+const byte PASSHASH9_DEFAULT_ALGO = 0; // HMAC(SHA-1)
+
const u32bit WORK_FACTOR_SCALE = 10000;
MessageAuthenticationCode* get_pbkdf_prf(byte alg_id)
@@ -33,34 +35,37 @@ MessageAuthenticationCode* get_pbkdf_prf(byte alg_id)
{
if(alg_id == 0)
return af.make_mac("HMAC(SHA-1)");
+ else if(alg_id == 1)
+ return af.make_mac("HMAC(SHA-256)");
+ else if(alg_id == 2)
+ return af.make_mac("CMAC(Blowfish)");
}
catch(Algorithm_Not_Found) {}
return 0;
}
-std::pair<byte, MessageAuthenticationCode*> choose_pbkdf_prf()
- {
- for(byte alg_id = 0; alg_id != 255; ++alg_id)
- {
- MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id);
- if(prf)
- return std::make_pair(alg_id, prf);
- }
+}
- throw Internal_Error("Passhash9: No PRF available");
+std::string generate_passhash9(const std::string& pass,
+ RandomNumberGenerator& rng,
+ u16bit work_factor)
+ {
+ return generate_passhash9(pass, PASSHASH9_DEFAULT_ALGO, rng, work_factor);
}
-}
-
std::string generate_passhash9(const std::string& pass,
+ byte alg_id,
RandomNumberGenerator& rng,
u16bit work_factor)
{
- std::pair<byte, MessageAuthenticationCode*> prf = choose_pbkdf_prf();
- byte alg_id = prf.first;
+ MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id);
+
+ if(!prf)
+ throw Invalid_Argument("Passhash9: Algorithm id " + to_string(alg_id) +
+ " is not defined");
- PKCS5_PBKDF2 kdf(prf.second); // takes ownership of pointer
+ PKCS5_PBKDF2 kdf(prf); // takes ownership of pointer
SecureVector<byte> salt(SALT_BYTES);
rng.randomize(&salt[0], salt.size());
diff --git a/src/constructs/passhash/passhash9.h b/src/constructs/passhash/passhash9.h
index 8900d55d3..92cc391dc 100644
--- a/src/constructs/passhash/passhash9.h
+++ b/src/constructs/passhash/passhash9.h
@@ -23,6 +23,22 @@ std::string BOTAN_DLL generate_passhash9(const std::string& password,
u16bit work_factor = 10);
/**
+* Create a password hash using PBKDF2
+* @param password the password
+* @param alg_id specifies which PRF to use with PBKDF2
+* 0 is HMAC(SHA-1)
+* 1 is HMAC(SHA-256)
+* 2 is CMAC(Blowfish)
+* all other values are currently undefined
+* @param rng a random number generator
+* @param work_factor how much work to do to slow down guessing attacks
+*/
+std::string BOTAN_DLL generate_passhash9(const std::string& password,
+ byte alg_id,
+ RandomNumberGenerator& rng,
+ u16bit work_factor = 10);
+
+/**
* Check a previously created password hash
* @param password the password to check against
* @param hash the stored hash to check against
diff --git a/src/constructs/tss/tss.cpp b/src/constructs/tss/tss.cpp
index 101640f96..daad9f6bf 100644
--- a/src/constructs/tss/tss.cpp
+++ b/src/constructs/tss/tss.cpp
@@ -106,9 +106,7 @@ HashFunction* get_rtss_hash_by_id(byte id)
RTSS_Share::RTSS_Share(const std::string& hex_input)
{
- Pipe pipe(new Hex_Decoder);
- pipe.process_msg(hex_input);
- contents = pipe.read_all();
+ contents = hex_decode(hex_input);
}
byte RTSS_Share::share_id() const
@@ -121,9 +119,7 @@ byte RTSS_Share::share_id() const
std::string RTSS_Share::to_string() const
{
- Pipe pipe(new Hex_Encoder);
- pipe.process_msg(contents);
- return pipe.read_all_as_string();
+ return hex_encode(&contents[0], contents.size());
}
std::vector<RTSS_Share>
diff --git a/src/filters/data_snk.cpp b/src/filters/data_snk.cpp
index f8ee9f86e..d61fcc61f 100644
--- a/src/filters/data_snk.cpp
+++ b/src/filters/data_snk.cpp
@@ -17,8 +17,8 @@ namespace Botan {
*/
void DataSink_Stream::write(const byte out[], u32bit length)
{
- sink->write(reinterpret_cast<const char*>(out), length);
- if(!sink->good())
+ sink.write(reinterpret_cast<const char*>(out), length);
+ if(!sink.good())
throw Stream_IO_Error("DataSink_Stream: Failure writing to " +
identifier);
}
@@ -28,9 +28,10 @@ void DataSink_Stream::write(const byte out[], u32bit length)
*/
DataSink_Stream::DataSink_Stream(std::ostream& out,
const std::string& name) :
- identifier(name != "" ? name : "<std::ostream>"), owner(false)
+ identifier(name),
+ sink_p(0),
+ sink(out)
{
- sink = &out;
}
/*
@@ -38,15 +39,17 @@ DataSink_Stream::DataSink_Stream(std::ostream& out,
*/
DataSink_Stream::DataSink_Stream(const std::string& path,
bool use_binary) :
- identifier(path), owner(true)
+ identifier(path),
+ sink_p(use_binary ?
+ new std::ofstream(path.c_str(), std::ios::binary) :
+ new std::ofstream(path.c_str())),
+ sink(*sink_p)
{
- if(use_binary)
- sink = new std::ofstream(path.c_str(), std::ios::binary);
- else
- sink = new std::ofstream(path.c_str());
-
- if(!sink->good())
+ if(!sink.good())
+ {
+ delete sink_p;
throw Stream_IO_Error("DataSink_Stream: Failure opening " + path);
+ }
}
/*
@@ -54,9 +57,7 @@ DataSink_Stream::DataSink_Stream(const std::string& path,
*/
DataSink_Stream::~DataSink_Stream()
{
- if(owner)
- delete sink;
- sink = 0;
+ delete sink_p;
}
}
diff --git a/src/filters/data_snk.h b/src/filters/data_snk.h
index 8d7fac3e1..b6f44db7f 100644
--- a/src/filters/data_snk.h
+++ b/src/filters/data_snk.h
@@ -43,7 +43,7 @@ class BOTAN_DLL DataSink_Stream : public DataSink
* @param name identifier
*/
DataSink_Stream(std::ostream& stream,
- const std::string& name = "");
+ const std::string& name = "<std::ostream>");
/**
* Construct a DataSink_Stream from a stream.
@@ -57,9 +57,9 @@ class BOTAN_DLL DataSink_Stream : public DataSink
~DataSink_Stream();
private:
const std::string identifier;
- const bool owner;
- std::ostream* sink;
+ std::ostream* sink_p;
+ std::ostream& sink;
};
}
diff --git a/src/filters/data_src.cpp b/src/filters/data_src.cpp
index e6387c4ba..522ce09d0 100644
--- a/src/filters/data_src.cpp
+++ b/src/filters/data_src.cpp
@@ -8,7 +8,6 @@
#include <botan/data_src.h>
#include <botan/exceptn.h>
-
#include <fstream>
#include <algorithm>
@@ -107,11 +106,11 @@ DataSource_Memory::DataSource_Memory(const std::string& in)
*/
u32bit DataSource_Stream::read(byte out[], u32bit length)
{
- source->read(reinterpret_cast<char*>(out), length);
- if(source->bad())
+ source.read(reinterpret_cast<char*>(out), length);
+ if(source.bad())
throw Stream_IO_Error("DataSource_Stream::read: Source failure");
- u32bit got = source->gcount();
+ u32bit got = source.gcount();
total_read += got;
return got;
}
@@ -129,23 +128,23 @@ u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const
if(offset)
{
SecureVector<byte> buf(offset);
- source->read(reinterpret_cast<char*>(buf.begin()), buf.size());
- if(source->bad())
+ source.read(reinterpret_cast<char*>(buf.begin()), buf.size());
+ if(source.bad())
throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
- got = source->gcount();
+ got = source.gcount();
}
if(got == offset)
{
- source->read(reinterpret_cast<char*>(out), length);
- if(source->bad())
+ source.read(reinterpret_cast<char*>(out), length);
+ if(source.bad())
throw Stream_IO_Error("DataSource_Stream::peek: Source failure");
- got = source->gcount();
+ got = source.gcount();
}
- if(source->eof())
- source->clear();
- source->seekg(total_read, std::ios::beg);
+ if(source.eof())
+ source.clear();
+ source.seekg(total_read, std::ios::beg);
return got;
}
@@ -155,7 +154,7 @@ u32bit DataSource_Stream::peek(byte out[], u32bit length, u32bit offset) const
*/
bool DataSource_Stream::end_of_data() const
{
- return (!source->good());
+ return (!source.good());
}
/*
@@ -171,15 +170,17 @@ std::string DataSource_Stream::id() const
*/
DataSource_Stream::DataSource_Stream(const std::string& path,
bool use_binary) :
- identifier(path), owner(true)
+ identifier(path),
+ source_p(use_binary ?
+ new std::ifstream(path.c_str()) :
+ new std::ifstream(path.c_str(), std::ios::binary)),
+ source(*source_p)
{
- if(use_binary)
- source = new std::ifstream(path.c_str(), std::ios::binary);
- else
- source = new std::ifstream(path.c_str());
-
- if(!source->good())
+ if(!source.good())
+ {
+ delete source_p;
throw Stream_IO_Error("DataSource: Failure opening file " + path);
+ }
total_read = 0;
}
@@ -189,9 +190,10 @@ DataSource_Stream::DataSource_Stream(const std::string& path,
*/
DataSource_Stream::DataSource_Stream(std::istream& in,
const std::string& name) :
- identifier(name), owner(false)
+ identifier(name),
+ source_p(0),
+ source(in)
{
- source = &in;
total_read = 0;
}
@@ -200,8 +202,7 @@ DataSource_Stream::DataSource_Stream(std::istream& in,
*/
DataSource_Stream::~DataSource_Stream()
{
- if(owner)
- delete source;
+ delete source_p;
}
}
diff --git a/src/filters/data_src.h b/src/filters/data_src.h
index 016402b61..823b4a013 100644
--- a/src/filters/data_src.h
+++ b/src/filters/data_src.h
@@ -129,7 +129,8 @@ class BOTAN_DLL DataSource_Stream : public DataSource
bool end_of_data() const;
std::string id() const;
- DataSource_Stream(std::istream&, const std::string& id = "");
+ DataSource_Stream(std::istream&,
+ const std::string& id = "<std::istream>");
/**
* Construct a Stream-Based DataSource from file
@@ -141,9 +142,9 @@ class BOTAN_DLL DataSource_Stream : public DataSource
~DataSource_Stream();
private:
const std::string identifier;
- const bool owner;
- std::istream* source;
+ std::istream* source_p;
+ std::istream& source;
u32bit total_read;
};
diff --git a/src/filters/filters.h b/src/filters/filters.h
index e2c7cb5ec..51b4f00fe 100644
--- a/src/filters/filters.h
+++ b/src/filters/filters.h
@@ -24,8 +24,8 @@
#include <botan/base64.h>
#endif
-#if defined(BOTAN_HAS_HEX_CODEC)
- #include <botan/hex.h>
+#if defined(BOTAN_HAS_HEX_FILTER)
+ #include <botan/hex_filt.h>
#endif
namespace Botan {
diff --git a/src/filters/hex/hex_char.cpp b/src/filters/hex/hex_char.cpp
deleted file mode 100644
index c28efc5f7..000000000
--- a/src/filters/hex/hex_char.cpp
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
-* Hex Character Table
-* (C) 1999-2008 Jack Lloyd
-*
-* Distributed under the terms of the Botan license
-*/
-
-#include <botan/hex.h>
-
-namespace Botan {
-
-/*
-* Hex Encoder Lookup Tables
-*/
-const byte Hex_Encoder::BIN_TO_HEX_UPPER[16] = {
-0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43,
-0x44, 0x45, 0x46 };
-
-const byte Hex_Encoder::BIN_TO_HEX_LOWER[16] = {
-0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x61, 0x62, 0x63,
-0x64, 0x65, 0x66 };
-
-/*
-* Hex Decoder Lookup Table
-*/
-const byte Hex_Decoder::HEX_TO_BIN[256] = {
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x00, 0x01, 0x02, 0x03,
-0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80,
-0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80 };
-
-}
diff --git a/src/filters/hex/hex.cpp b/src/filters/hex_filt/hex_filt.cpp
index 430958ebd..0f3daa464 100644
--- a/src/filters/hex/hex.cpp
+++ b/src/filters/hex_filt/hex_filt.cpp
@@ -5,6 +5,7 @@
* Distributed under the terms of the Botan license
*/
+#include <botan/hex_filt.h>
#include <botan/hex.h>
#include <botan/parsing.h>
#include <botan/charset.h>
@@ -40,24 +41,13 @@ Hex_Encoder::Hex_Encoder(Case c) : casing(c), line_length(0)
}
/*
-* Hex Encoding Operation
-*/
-void Hex_Encoder::encode(byte in, byte out[2], Hex_Encoder::Case casing)
- {
- const byte* BIN_TO_HEX = ((casing == Uppercase) ? BIN_TO_HEX_UPPER :
- BIN_TO_HEX_LOWER);
-
- out[0] = BIN_TO_HEX[((in >> 4) & 0x0F)];
- out[1] = BIN_TO_HEX[((in ) & 0x0F)];
- }
-
-/*
* Encode and send a block
*/
void Hex_Encoder::encode_and_send(const byte block[], u32bit length)
{
- for(u32bit j = 0; j != length; ++j)
- encode(block[j], out + 2*j, casing);
+ hex_encode(reinterpret_cast<char*>(&out[0]),
+ block, length,
+ casing == Uppercase);
if(line_length == 0)
send(out, 2*length);
@@ -125,62 +115,35 @@ Hex_Decoder::Hex_Decoder(Decoder_Checking c) : checking(c)
}
/*
-* Check if a character is a valid hex char
-*/
-bool Hex_Decoder::is_valid(byte in)
- {
- return (HEX_TO_BIN[in] != 0x80);
- }
-
-/*
-* Handle processing an invalid character
-*/
-void Hex_Decoder::handle_bad_char(byte c)
- {
- if(checking == NONE)
- return;
-
- if((checking == IGNORE_WS) && Charset::is_space(c))
- return;
-
- throw Decoding_Error("Hex_Decoder: Invalid hex character: " +
- std::to_string(c));
- }
-
-/*
-* Hex Decoding Operation
-*/
-byte Hex_Decoder::decode(const byte hex[2])
- {
- return ((HEX_TO_BIN[hex[0]] << 4) | HEX_TO_BIN[hex[1]]);
- }
-
-/*
-* Decode and send a block
-*/
-void Hex_Decoder::decode_and_send(const byte block[], u32bit length)
- {
- for(u32bit j = 0; j != length / 2; ++j)
- out[j] = decode(block + 2*j);
- send(out, length / 2);
- }
-
-/*
* Convert some data from hex format
*/
void Hex_Decoder::write(const byte input[], u32bit length)
{
- for(u32bit j = 0; j != length; ++j)
+ while(length)
{
- if(is_valid(input[j]))
- in[position++] = input[j];
- else
- handle_bad_char(input[j]);
- if(position == in.size())
+ u32bit to_copy = std::min(length, in.size() - position);
+ copy_mem(&in[position], input, to_copy);
+ position += to_copy;
+
+ u32bit consumed = 0;
+ u32bit written = hex_decode(&out[0],
+ reinterpret_cast<const char*>(&in[0]),
+ position,
+ consumed,
+ checking != FULL_CHECK);
+
+ send(out, written);
+
+ if(consumed != position)
{
- decode_and_send(in, in.size());
- position = 0;
+ copy_mem(&in[0], &in[consumed], position - consumed);
+ position = position - consumed;
}
+ else
+ position = 0;
+
+ length -= to_copy;
+ input += to_copy;
}
}
@@ -189,8 +152,21 @@ void Hex_Decoder::write(const byte input[], u32bit length)
*/
void Hex_Decoder::end_msg()
{
- decode_and_send(in, position);
+ u32bit consumed = 0;
+ u32bit written = hex_decode(&out[0],
+ reinterpret_cast<const char*>(&in[0]),
+ position,
+ consumed,
+ checking != FULL_CHECK);
+
+ send(out, written);
+
+ const bool not_full_bytes = consumed != position;
+
position = 0;
+
+ if(not_full_bytes)
+ throw std::invalid_argument("Hex_Decoder: Input not full bytes");
}
}
diff --git a/src/filters/hex/hex.h b/src/filters/hex_filt/hex_filt.h
index 6698a61be..88bf35de8 100644
--- a/src/filters/hex/hex.h
+++ b/src/filters/hex_filt/hex_filt.h
@@ -1,19 +1,20 @@
/*
* Hex Encoder/Decoder
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
-#ifndef BOTAN_HEX_H__
-#define BOTAN_HEX_H__
+#ifndef BOTAN_HEX_FILTER_H__
+#define BOTAN_HEX_FILTER_H__
#include <botan/filter.h>
namespace Botan {
/**
-* This class represents a hex encoder. It encodes byte arrays to hex strings.
+* Converts arbitrary binary data to hex strings, optionally with
+* newlines inserted
*/
class BOTAN_DLL Hex_Encoder : public Filter
{
@@ -23,11 +24,6 @@ class BOTAN_DLL Hex_Encoder : public Filter
*/
enum Case { Uppercase, Lowercase };
- /**
- * Encode a single byte into two hex characters
- */
- static void encode(byte in, byte out[2], Case the_case = Uppercase);
-
std::string name() const { return "Hex_Encoder"; }
void write(const byte in[], u32bit length);
@@ -50,8 +46,6 @@ class BOTAN_DLL Hex_Encoder : public Filter
Case the_case = Uppercase);
private:
void encode_and_send(const byte[], u32bit);
- static const byte BIN_TO_HEX_UPPER[16];
- static const byte BIN_TO_HEX_LOWER[16];
const Case casing;
const u32bit line_length;
@@ -60,25 +54,11 @@ class BOTAN_DLL Hex_Encoder : public Filter
};
/**
-* This class represents a hex decoder. It converts hex strings to byte arrays.
+* Converts hex strings to bytes
*/
class BOTAN_DLL Hex_Decoder : public Filter
{
public:
- /**
- * Decode a pair of hex chars to a byte
- * @param in an array of two hex chars
- * @return byte formed by decoding in
- */
- static byte decode(const byte in[2]);
-
- /**
- * Check if this character is a valid hex input
- * @param c a single character
- * @return true iff c is a valid hex char
- */
- static bool is_valid(byte c);
-
std::string name() const { return "Hex_Decoder"; }
void write(const byte[], u32bit);
@@ -91,10 +71,6 @@ class BOTAN_DLL Hex_Decoder : public Filter
*/
Hex_Decoder(Decoder_Checking checking = NONE);
private:
- void decode_and_send(const byte[], u32bit);
- void handle_bad_char(byte);
- static const byte HEX_TO_BIN[256];
-
const Decoder_Checking checking;
SecureVector<byte> in, out;
u32bit position;
diff --git a/src/filters/hex/info.txt b/src/filters/hex_filt/info.txt
index 0a4205669..7f5f47fa1 100644
--- a/src/filters/hex/info.txt
+++ b/src/filters/hex_filt/info.txt
@@ -1,4 +1,4 @@
-define HEX_CODEC
+define HEX_FILTER
<requires>
filters
diff --git a/src/libstate/get_enc.cpp b/src/libstate/get_enc.cpp
index a825a5d24..1176061c2 100644
--- a/src/libstate/get_enc.cpp
+++ b/src/libstate/get_enc.cpp
@@ -15,7 +15,6 @@
#if defined(BOTAN_HAS_PBKDF2)
#include <botan/pbkdf2.h>
- #include <botan/hmac.h>
#endif
#if defined(BOTAN_HAS_PGPS2K)
@@ -96,7 +95,12 @@ PBKDF* get_pbkdf(const std::string& algo_spec)
#if defined(BOTAN_HAS_PBKDF2)
if(request.algo_name() == "PBKDF2" && request.arg_count() == 1)
- return new PKCS5_PBKDF2(new HMAC(af.make_hash_function(request.arg(0))));
+ {
+ if(const MessageAuthenticationCode* mac_proto = af.prototype_mac(request.arg(0)))
+ return new PKCS5_PBKDF2(mac_proto->clone());
+
+ return new PKCS5_PBKDF2(af.make_mac("HMAC(" + request.arg(0) + ")"));
+ }
#endif
#if defined(BOTAN_HAS_PGPS2K)
diff --git a/src/mac/hmac/hmac.cpp b/src/mac/hmac/hmac.cpp
index f69504c82..0d5c99702 100644
--- a/src/mac/hmac/hmac.cpp
+++ b/src/mac/hmac/hmac.cpp
@@ -86,7 +86,7 @@ MessageAuthenticationCode* HMAC::clone() const
*/
HMAC::HMAC(HashFunction* hash_in) :
MessageAuthenticationCode(hash_in->OUTPUT_LENGTH,
- 1, 2*hash_in->HASH_BLOCK_SIZE),
+ 0, 2*hash_in->HASH_BLOCK_SIZE),
hash(hash_in)
{
if(hash->HASH_BLOCK_SIZE == 0)
diff --git a/src/math/bigint/big_code.cpp b/src/math/bigint/big_code.cpp
index 74701e532..a8272390d 100644
--- a/src/math/bigint/big_code.cpp
+++ b/src/math/bigint/big_code.cpp
@@ -1,6 +1,6 @@
/*
* BigInt Encoding/Decoding
-* (C) 1999-2007 Jack Lloyd
+* (C) 1999-2010 Jack Lloyd
*
* Distributed under the terms of the Botan license
*/
@@ -23,8 +23,9 @@ void BigInt::encode(byte output[], const BigInt& n, Base base)
{
SecureVector<byte> binary(n.encoded_size(Binary));
n.binary_encode(binary);
- for(u32bit j = 0; j != binary.size(); ++j)
- Hex_Encoder::encode(binary[j], output + 2*j);
+
+ hex_encode(reinterpret_cast<char*>(output),
+ &binary[0], binary.size());
}
else if(base == Octal)
{
@@ -103,22 +104,23 @@ BigInt BigInt::decode(const byte buf[], u32bit length, Base base)
r.binary_decode(buf, length);
else if(base == Hexadecimal)
{
- SecureVector<byte> hex;
- for(u32bit j = 0; j != length; ++j)
- if(Hex_Decoder::is_valid(buf[j]))
- hex.append(buf[j]);
-
- u32bit offset = (hex.size() % 2);
- SecureVector<byte> binary(hex.size() / 2 + offset);
+ SecureVector<byte> binary;
- if(offset)
+ if(length % 2)
{
- byte temp[2] = { '0', hex[0] };
- binary[0] = Hex_Decoder::decode(temp);
+ // Handle lack of leading 0
+ const char buf0_with_leading_0[2] = { '0', buf[0] };
+ binary = hex_decode(buf0_with_leading_0, 2);
+
+ binary.append(hex_decode(reinterpret_cast<const char*>(&buf[1]),
+ length - 1,
+ false));
+
}
+ else
+ binary = hex_decode(reinterpret_cast<const char*>(buf),
+ length, false);
- for(u32bit j = offset; j != binary.size(); ++j)
- binary[j] = Hex_Decoder::decode(hex+2*j-offset);
r.binary_decode(binary, binary.size());
}
else if(base == Decimal || base == Octal)
diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h
index 2b95bfc90..aa2e4347e 100644
--- a/src/math/bigint/bigint.h
+++ b/src/math/bigint/bigint.h
@@ -545,7 +545,11 @@ BOTAN_DLL std::istream& operator>>(std::istream&, BigInt&);
namespace std {
-inline void swap(Botan::BigInt& a, Botan::BigInt& b) { a.swap(b); }
+template<>
+inline void swap(Botan::BigInt& x, Botan::BigInt& y)
+ {
+ x.swap(y);
+ }
}
diff --git a/src/math/bigint/info.txt b/src/math/bigint/info.txt
index 0511c2d8d..7892a6edf 100644
--- a/src/math/bigint/info.txt
+++ b/src/math/bigint/info.txt
@@ -30,7 +30,7 @@ mp_shift.cpp
<requires>
alloc
hex
-mp_amd64|mp_amd64_msvc|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic
+mp_amd64|mp_msvc64|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic
monty_generic
mulop_generic
rng
diff --git a/src/math/bigint/mp_amd64_msvc/info.txt b/src/math/bigint/mp_msvc64/info.txt
index 56ae05927..56ae05927 100644
--- a/src/math/bigint/mp_amd64_msvc/info.txt
+++ b/src/math/bigint/mp_msvc64/info.txt
diff --git a/src/math/bigint/mp_amd64_msvc/mp_asm.h b/src/math/bigint/mp_msvc64/mp_asm.h
index 3acbe11bb..8e4535c35 100644
--- a/src/math/bigint/mp_amd64_msvc/mp_asm.h
+++ b/src/math/bigint/mp_msvc64/mp_asm.h
@@ -12,7 +12,7 @@
#include <intrin.h>
#if (BOTAN_MP_WORD_BITS != 64)
- #error The mp_amd64_msvc module requires that BOTAN_MP_WORD_BITS == 64
+ #error The mp_msvc64 module requires that BOTAN_MP_WORD_BITS == 64
#endif
#pragma intrinsic(_umul128)
diff --git a/src/pbkdf/pbkdf.h b/src/pbkdf/pbkdf.h
index 7262a4d9f..14615103f 100644
--- a/src/pbkdf/pbkdf.h
+++ b/src/pbkdf/pbkdf.h
@@ -38,11 +38,10 @@ class BOTAN_DLL PBKDF
virtual void clear() {}
/**
- * Derive a key from a passphrase with this PBKDF object. It will use
- * the salt value and number of iterations configured in this object.
+ * Derive a key from a passphrase
* @param output_len the desired length of the key to produce
* @param passphrase the password to derive the key from
- * @param salt the randomly chosen salt
+ * @param salt a randomly chosen salt
* @param salt_len length of salt in bytes
* @param iterations the number of iterations to use (use 10K or more)
*/
diff --git a/src/pbkdf/pbkdf2/pbkdf2.cpp b/src/pbkdf/pbkdf2/pbkdf2.cpp
index e88a5749a..6f6a514f8 100644
--- a/src/pbkdf/pbkdf2/pbkdf2.cpp
+++ b/src/pbkdf/pbkdf2/pbkdf2.cpp
@@ -22,11 +22,16 @@ OctetString PKCS5_PBKDF2::derive_key(u32bit key_len,
if(iterations == 0)
throw Invalid_Argument("PKCS#5 PBKDF2: Invalid iteration count");
- if(passphrase.length() == 0)
- throw Invalid_Argument("PKCS#5 PBKDF2: Empty passphrase is invalid");
-
- mac->set_key(reinterpret_cast<const byte*>(passphrase.data()),
- passphrase.length());
+ try
+ {
+ mac->set_key(reinterpret_cast<const byte*>(passphrase.data()),
+ passphrase.length());
+ }
+ catch(Invalid_Key_Length)
+ {
+ throw Exception(name() + " cannot accept passphrases of length " +
+ to_string(passphrase.length()));
+ }
SecureVector<byte> key(key_len);
diff --git a/src/pbkdf/pbkdf2/pbkdf2.h b/src/pbkdf/pbkdf2/pbkdf2.h
index 2b25a7b1d..8b50b4a67 100644
--- a/src/pbkdf/pbkdf2/pbkdf2.h
+++ b/src/pbkdf/pbkdf2/pbkdf2.h
@@ -36,9 +36,9 @@ class BOTAN_DLL PKCS5_PBKDF2 : public PBKDF
/**
* Create a PKCS #5 instance using the specified message auth code
- * @param mac the MAC to use
+ * @param mac_fn the MAC to use
*/
- PKCS5_PBKDF2(MessageAuthenticationCode* m) : mac(m) {}
+ PKCS5_PBKDF2(MessageAuthenticationCode* mac_fn) : mac(mac_fn) {}
/**
* Destructor
diff --git a/src/ssl/info.txt b/src/ssl/info.txt
index 1d28cf4f8..f0867b3f1 100644
--- a/src/ssl/info.txt
+++ b/src/ssl/info.txt
@@ -38,3 +38,23 @@ tls_server.cpp
tls_session_key.cpp
tls_suites.cpp
</source>
+
+<requires>
+alloc
+asn1
+bigint
+dh
+dl_group
+dsa
+filters
+libstate
+md5
+pubkey
+rng
+rsa
+sha1
+ssl_prf
+sym_algo
+tls_prf
+x509
+</requires>
diff --git a/src/sym_algo/symkey.cpp b/src/sym_algo/symkey.cpp
index 97bd08819..bf2b705d3 100644
--- a/src/sym_algo/symkey.cpp
+++ b/src/sym_algo/symkey.cpp
@@ -29,16 +29,11 @@ OctetString::OctetString(RandomNumberGenerator& rng,
*/
void OctetString::change(const std::string& hex_string)
{
- SecureVector<byte> hex;
- for(u32bit j = 0; j != hex_string.length(); ++j)
- if(Hex_Decoder::is_valid(hex_string[j]))
- hex.append(hex_string[j]);
-
- if(hex.size() % 2 != 0)
- throw Invalid_Argument("OctetString: hex string must encode full bytes");
- bits.resize(hex.size() / 2);
- for(u32bit j = 0; j != bits.size(); ++j)
- bits[j] = Hex_Decoder::decode(hex.begin() + 2*j);
+ SecureVector<byte> decoded(hex_string.length() / 2);
+
+ u32bit written = hex_decode(&decoded[0], hex_string);
+
+ bits.set(&decoded[0], written);
}
/*
@@ -88,9 +83,7 @@ void OctetString::set_odd_parity()
*/
std::string OctetString::as_string() const
{
- Pipe pipe(new Hex_Encoder);
- pipe.process_msg(bits);
- return pipe.read_all_as_string();
+ return hex_encode(&bits[0], bits.size());
}
/*
diff --git a/src/utils/datastor/datastor.cpp b/src/utils/datastor/datastor.cpp
index 85b0f22ba..363136c69 100644
--- a/src/utils/datastor/datastor.cpp
+++ b/src/utils/datastor/datastor.cpp
@@ -8,8 +8,8 @@
#include <botan/datastor.h>
#include <botan/exceptn.h>
#include <botan/parsing.h>
+#include <botan/hex.h>
#include <botan/internal/stl_util.h>
-#include <botan/filters.h>
namespace Botan {
@@ -79,19 +79,14 @@ Data_Store::get1_memvec(const std::string& key) const
{
std::vector<std::string> vals = get(key);
+ if(vals.empty())
+ return MemoryVector<byte>();
+
if(vals.size() > 1)
throw Invalid_State("Data_Store::get1_memvec: Multiple values for " +
key);
- if(vals.empty())
- return MemoryVector<byte>();
-
- Pipe pipe(new Hex_Decoder(FULL_CHECK));
- pipe.start_msg();
- if(vals.size())
- pipe.write(vals[0]);
- pipe.end_msg();
- return pipe.read_all();
+ return hex_decode(vals[0]);
}
/*
@@ -132,9 +127,7 @@ void Data_Store::add(const std::string& key, u32bit val)
*/
void Data_Store::add(const std::string& key, const MemoryRegion<byte>& val)
{
- Pipe pipe(new Hex_Encoder);
- pipe.process_msg(val);
- add(key, pipe.read_all_as_string());
+ add(key, hex_encode(&val[0], val.size()));
}
/*
diff --git a/src/utils/datastor/info.txt b/src/utils/datastor/info.txt
index 93e938d78..b91fe5082 100644
--- a/src/utils/datastor/info.txt
+++ b/src/utils/datastor/info.txt
@@ -1,4 +1,3 @@
<requires>
alloc
-filters
</requires>
diff --git a/src/utils/dyn_load/dyn_load.cpp b/src/utils/dyn_load/dyn_load.cpp
index 6d359bc01..5f3814778 100644
--- a/src/utils/dyn_load/dyn_load.cpp
+++ b/src/utils/dyn_load/dyn_load.cpp
@@ -11,10 +11,23 @@
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
#include <dlfcn.h>
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ #include <windows.h>
#endif
namespace Botan {
+namespace {
+
+void raise_runtime_loader_exception(const std::string& lib_name,
+ const char* msg)
+ {
+ throw std::runtime_error("Failed to load " + lib_name + ": " +
+ (msg ? msg : "Unknown error"));
+ }
+
+}
+
Dynamically_Loaded_Library::Dynamically_Loaded_Library(
const std::string& library) :
lib_name(library), lib(0)
@@ -23,22 +36,25 @@ Dynamically_Loaded_Library::Dynamically_Loaded_Library(
lib = ::dlopen(lib_name.c_str(), RTLD_LAZY);
if(!lib)
- {
- const char* dl_err = dlerror();
- if(!dl_err)
- dl_err = "Unknown error";
-
- throw std::runtime_error("Failed to load engine " + lib_name + ": " +
- dl_err);
- }
+ raise_runtime_loader_exception(lib_name, dlerror());
+
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ lib = ::LoadLibrary(lib_name.c_str());
+
+ if(!lib)
+ raise_runtime_loader_exception(lib_name, "LoadLibrary failed");
#endif
+ if(!lib)
+ raise_runtime_loader_exception(lib_name, "Dynamic load not supported");
}
Dynamically_Loaded_Library::~Dynamically_Loaded_Library()
{
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
::dlclose(lib);
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ ::FreeLibrary(lib);
#endif
}
@@ -48,6 +64,8 @@ void* Dynamically_Loaded_Library::resolve_symbol(const std::string& symbol)
#if defined(BOTAN_TARGET_OS_HAS_DLOPEN)
addr = ::dlsym(lib, symbol.c_str());
+#elif defined(BOTAN_TARGET_OS_HAS_LOADLIBRARY)
+ addr = ::GetProcAddress(lib, symbol.c_str());
#endif
if(!addr)
diff --git a/src/utils/dyn_load/dyn_load.h b/src/utils/dyn_load/dyn_load.h
index 56277d3e4..c8fb31cf0 100644
--- a/src/utils/dyn_load/dyn_load.h
+++ b/src/utils/dyn_load/dyn_load.h
@@ -18,6 +18,11 @@ class Dynamically_Loaded_Library
/**
* Load a DLL (or fail with an exception)
* @param lib_name name or path to a library
+ *
+ * If you don't use a full path, the search order will be defined
+ * by whatever the system linker does by default. Always using fully
+ * qualified pathnames can help prevent code injection attacks (eg
+ * via manipulation of LD_LIBRARY_PATH on Linux)
*/
Dynamically_Loaded_Library(const std::string& lib_name);
diff --git a/src/wrap/perl-xs/Botan.xs b/src/wrap/perl-xs/Botan.xs
index ded129d2e..5268a96d1 100644
--- a/src/wrap/perl-xs/Botan.xs
+++ b/src/wrap/perl-xs/Botan.xs
@@ -14,7 +14,7 @@ extern "C" {
#include <botan/asn1_oid.h>
#include <botan/base64.h>
#include <botan/basefilt.h>
-#include <botan/hex.h>
+#include <botan/hex_filt.h>
#include <botan/init.h>
#include <botan/oids.h>
#include <botan/x509cert.h>