diff options
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 = ∈ 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> |