aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Cogliani <[email protected]>2016-07-30 14:43:55 +0200
committerSimon Cogliani <[email protected]>2016-07-30 14:43:55 +0200
commit8c305d9969ed0690d5603b75fd151cb7a33138f0 (patch)
treecb040976f029793af05f4bde8ca40eaa89252fc0
parentc006e97219dc93dd2d8dcaca5c325296e1ce3d55 (diff)
parent17677f9981005b68201653b45de42c5958f32b70 (diff)
Merge branch 'master' into frp256v1
-rw-r--r--src/lib/pk_pad/eme_oaep/oaep.cpp4
-rw-r--r--src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp20
-rw-r--r--src/lib/pk_pad/hash_id/hash_id.cpp8
-rw-r--r--src/lib/pubkey/dh/dh.cpp9
-rw-r--r--src/lib/utils/simd/simd_32.h2
-rw-r--r--src/tests/data/charset.vec41
-rw-r--r--src/tests/test_bigint.cpp9
-rw-r--r--src/tests/test_block.cpp6
-rw-r--r--src/tests/test_dh.cpp34
-rw-r--r--src/tests/test_pubkey.cpp25
-rw-r--r--src/tests/test_utils.cpp125
11 files changed, 263 insertions, 20 deletions
diff --git a/src/lib/pk_pad/eme_oaep/oaep.cpp b/src/lib/pk_pad/eme_oaep/oaep.cpp
index 0ae0d8554..1ae1068a7 100644
--- a/src/lib/pk_pad/eme_oaep/oaep.cpp
+++ b/src/lib/pk_pad/eme_oaep/oaep.cpp
@@ -35,8 +35,10 @@ secure_vector<byte> OAEP::pad(const byte in[], size_t in_length,
{
key_length /= 8;
- if(key_length < in_length + 2*m_Phash.size() + 1)
+ if(in_length > maximum_input_size(key_length * 8))
+ {
throw Invalid_Argument("OAEP: Input is too large");
+ }
secure_vector<byte> out(key_length);
diff --git a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
index 8148b7bc9..9bab8eb95 100644
--- a/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
+++ b/src/lib/pk_pad/eme_pkcs1/eme_pkcs.cpp
@@ -14,22 +14,22 @@ namespace Botan {
* PKCS1 Pad Operation
*/
secure_vector<byte> EME_PKCS1v15::pad(const byte in[], size_t inlen,
- size_t olen,
+ size_t key_length,
RandomNumberGenerator& rng) const
{
- olen /= 8;
+ key_length /= 8;
- if(olen < 10)
- throw Encoding_Error("PKCS1: Output space too small");
- if(inlen > olen - 10)
- throw Encoding_Error("PKCS1: Input is too large");
+ if(inlen > maximum_input_size(key_length * 8))
+ {
+ throw Invalid_Argument("PKCS1: Input is too large");
+ }
- secure_vector<byte> out(olen);
+ secure_vector<byte> out(key_length);
out[0] = 0x02;
- rng.randomize(out.data() + 1, (olen - inlen - 2));
+ rng.randomize(out.data() + 1, (key_length - inlen - 2));
- for(size_t j = 1; j != olen - inlen - 1; ++j)
+ for(size_t j = 1; j != key_length - inlen - 1; ++j)
{
if(out[j] == 0)
{
@@ -37,7 +37,7 @@ secure_vector<byte> EME_PKCS1v15::pad(const byte in[], size_t inlen,
}
}
- buffer_insert(out, olen - inlen, in, inlen);
+ buffer_insert(out, key_length - inlen, in, inlen);
return out;
}
diff --git a/src/lib/pk_pad/hash_id/hash_id.cpp b/src/lib/pk_pad/hash_id/hash_id.cpp
index 28bbea346..882c30a4c 100644
--- a/src/lib/pk_pad/hash_id/hash_id.cpp
+++ b/src/lib/pk_pad/hash_id/hash_id.cpp
@@ -48,6 +48,10 @@ const byte SHA_512_PKCS_ID[] = {
0x30, 0x51, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
0x65, 0x03, 0x04, 0x02, 0x03, 0x05, 0x00, 0x04, 0x40 };
+const byte SHA_512_256_PKCS_ID[] = {
+0x30, 0x31, 0x30, 0x0D, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
+0x65, 0x03, 0x04, 0x02, 0x06, 0x05, 0x00, 0x04, 0x20 };
+
const byte TIGER_PKCS_ID[] = {
0x30, 0x29, 0x30, 0x0D, 0x06, 0x09, 0x2B, 0x06, 0x01, 0x04,
0x01, 0xDA, 0x47, 0x0C, 0x02, 0x05, 0x00, 0x04, 0x18 };
@@ -99,6 +103,10 @@ std::vector<byte> pkcs_hash_id(const std::string& name)
return std::vector<byte>(SHA_512_PKCS_ID,
SHA_512_PKCS_ID + sizeof(SHA_512_PKCS_ID));
+ if(name == "SHA-512-256")
+ return std::vector<byte>(SHA_512_256_PKCS_ID,
+ SHA_512_256_PKCS_ID + sizeof(SHA_512_256_PKCS_ID));
+
if(name == "Tiger(24,3)")
return std::vector<byte>(TIGER_PKCS_ID,
TIGER_PKCS_ID + sizeof(TIGER_PKCS_ID));
diff --git a/src/lib/pubkey/dh/dh.cpp b/src/lib/pubkey/dh/dh.cpp
index 9eb4e5cd0..8ed79aa3d 100644
--- a/src/lib/pubkey/dh/dh.cpp
+++ b/src/lib/pubkey/dh/dh.cpp
@@ -37,6 +37,7 @@ DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng,
const DL_Group& grp,
const BigInt& x_arg)
{
+ const bool generate = (x_arg == 0) ? true : false;
m_group = grp;
m_x = x_arg;
@@ -47,12 +48,18 @@ DH_PrivateKey::DH_PrivateKey(RandomNumberGenerator& rng,
}
if(m_y == 0)
+ {
m_y = power_mod(group_g(), m_x, group_p());
+ }
- if(m_x == 0)
+ if(generate)
+ {
gen_check(rng);
+ }
else
+ {
load_check(rng);
+ }
}
/*
diff --git a/src/lib/utils/simd/simd_32.h b/src/lib/utils/simd/simd_32.h
index 351146f22..0b4ca8f03 100644
--- a/src/lib/utils/simd/simd_32.h
+++ b/src/lib/utils/simd/simd_32.h
@@ -12,7 +12,7 @@
#include <botan/loadstor.h>
#include <botan/bswap.h>
-#if defined(BOTAN_TARGET_SUPPORTS_SSE2) && 0
+#if defined(BOTAN_TARGET_SUPPORTS_SSE2)
#include <emmintrin.h>
#define BOTAN_SIMD_USE_SSE2
diff --git a/src/tests/data/charset.vec b/src/tests/data/charset.vec
new file mode 100644
index 000000000..dd64ac6e3
--- /dev/null
+++ b/src/tests/data/charset.vec
@@ -0,0 +1,41 @@
+[UTF16-LATIN1]
+
+# Botan
+In = 0042006F00740061006E
+Out = 426F74616E
+
+# Heizölrückstoßabdämpfung
+In = 004800650069007A00F6006C007200FC0063006B00730074006F00DF00610062006400E4006D007000660075006E0067
+Out = 4865697AF66C72FC636B73746FDF616264E46D7066756E67
+
+# ÿ@Ðé¿ã!ð
+In = 00FF004000D000E900BF00E3002100F0
+Out = FF40D0E9BFE321F0
+
+[UTF8-LATIN1]
+
+# Botan
+In = 426F74616E
+Out = 426F74616E
+
+# Heizölrückstoßabdämpfung
+In = 4865697AC3B66C72C3BC636B73746FC39F616264C3A46D7066756E67
+Out = 4865697AF66C72FC636B73746FDF616264E46D7066756E67
+
+# ÿ@Ðé¿ã!ð
+In = C3BF40C390C3A9C2BFC3A321C3B0
+Out = FF40D0E9BFE321F0
+
+[LATIN1-UTF8]
+
+# Botan
+In = 426F74616E
+Out = 426F74616E
+
+# Heizölrückstoßabdämpfung
+In = 4865697AF66C72FC636B73746FDF616264E46D7066756E67
+Out = 4865697AC3B66C72C3BC636B73746FC39F616264C3A46D7066756E67
+
+# ÿ@Ðé¿ã!ð
+In = FF40D0E9BFE321F0
+Out = C3BF40C390C3A9C2BFC3A321C3B0 \ No newline at end of file
diff --git a/src/tests/test_bigint.cpp b/src/tests/test_bigint.cpp
index a7e00498f..6f3d603db 100644
--- a/src/tests/test_bigint.cpp
+++ b/src/tests/test_bigint.cpp
@@ -303,6 +303,15 @@ class BigInt_Mod_Test : public Text_Based_Test
e %= b;
result.test_eq("a %= b", e, c);
+ // if b fits into a Botan::word test %= operator for words
+ if(b.bytes() <= sizeof(Botan::word))
+ {
+ Botan::word b_word = b.word_at( 0 );
+ e = a;
+ e %= b_word;
+ result.test_eq("a %= b (as word)", e, c);
+ }
+
return result;
}
};
diff --git a/src/tests/test_block.cpp b/src/tests/test_block.cpp
index 75a460bc7..0863cb891 100644
--- a/src/tests/test_block.cpp
+++ b/src/tests/test_block.cpp
@@ -45,6 +45,12 @@ class Block_Cipher_Tests : public Text_Based_Test
result.test_gte(provider, cipher->block_size(), 8);
result.test_gte(provider, cipher->parallel_bytes(), cipher->block_size() * cipher->parallelism());
+ // Test to make sure clear() resets what we need it to
+ cipher->set_key(Test::rng().random_vec(cipher->key_spec().minimum_keylength()));
+ Botan::secure_vector<byte> garbage = Test::rng().random_vec(cipher->block_size());
+ cipher->encrypt(garbage);
+ cipher->clear();
+
cipher->set_key(key);
std::vector<uint8_t> buf = input;
diff --git a/src/tests/test_dh.cpp b/src/tests/test_dh.cpp
index 4414d2c75..e82ce522a 100644
--- a/src/tests/test_dh.cpp
+++ b/src/tests/test_dh.cpp
@@ -52,8 +52,41 @@ class Diffie_Hellman_KAT_Tests : public PK_Key_Agreement_Test
Botan::DH_PublicKey key(grp, y);
return key.public_value();
}
+
+ std::vector<Test::Result> run_final_tests() override
+ {
+ using namespace Botan;
+
+ Test::Result result("DH negative tests");
+
+ const BigInt g("2");
+ const BigInt p("58458002095536094658683755258523362961421200751439456159756164191494576279467");
+ const DL_Group grp(p, g);
+
+ const Botan::BigInt x("46205663093589612668746163860870963912226379131190812163519349848291472898748");
+ std::unique_ptr<Private_Key> privkey(new DH_PrivateKey(Test::rng(), grp, x));
+
+ std::unique_ptr<PK_Key_Agreement> kas(new PK_Key_Agreement(*privkey, "Raw"));
+
+ result.test_throws("agreement input too big", [&kas]()
+ {
+ const BigInt too_big("584580020955360946586837552585233629614212007514394561597561641914945762794672");
+ kas->derive_key(16, BigInt::encode(too_big));
+ });
+
+ result.test_throws("agreement input too small", [&kas]()
+ {
+ const BigInt too_small("1");
+ kas->derive_key(16, BigInt::encode(too_small));
+ });
+
+ return{result};
+ }
+
};
+BOTAN_REGISTER_TEST("dh_kat", Diffie_Hellman_KAT_Tests);
+
class Diffie_Hellman_Keygen_Tests : public PK_Key_Generation_Test
{
public:
@@ -69,7 +102,6 @@ class Diffie_Hellman_Keygen_Tests : public PK_Key_Generation_Test
};
-BOTAN_REGISTER_TEST("dh_kat", Diffie_Hellman_KAT_Tests);
BOTAN_REGISTER_TEST("dh_keygen", Diffie_Hellman_Keygen_Tests);
#endif
diff --git a/src/tests/test_pubkey.cpp b/src/tests/test_pubkey.cpp
index cdd0c99b0..c7bd8f932 100644
--- a/src/tests/test_pubkey.cpp
+++ b/src/tests/test_pubkey.cpp
@@ -197,6 +197,19 @@ PK_Encryption_Decryption_Test::run_one_test(const std::string&, const VarMap& va
//std::unique_ptr<Botan::Public_Key> pubkey(Botan::X509::load_key(Botan::X509::BER_encode(*privkey)));
Botan::Public_Key* pubkey = privkey.get();
+ // test EME::maximum_input_size()
+ std::unique_ptr<Botan::EME> eme(Botan::get_eme(padding));
+
+ if(eme)
+ {
+ size_t max_input_size = eme->maximum_input_size(1);
+ result.test_eq("maximum input size( 1 ) should always return 0", max_input_size, 0);
+
+ size_t keybits = pubkey->max_input_bits();
+ max_input_size = eme->maximum_input_size(keybits);
+ result.test_gte("maximum input size( keybits ) > 0", max_input_size, 1);
+ }
+
for(auto&& enc_provider : possible_pk_providers())
{
std::unique_ptr<Botan::PK_Encryptor> encryptor;
@@ -370,7 +383,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
Botan::DataSource_Memory data_src(Botan::X509::PEM_encode(key));
std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src));
- result.test_eq("recovered public key from private", loaded.get(), true);
+ result.confirm("recovered public key from private", loaded.get() != nullptr);
result.test_eq("public key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true);
}
@@ -384,7 +397,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
Botan::DataSource_Memory data_src(Botan::X509::BER_encode(key));
std::unique_ptr<Botan::Public_Key> loaded(Botan::X509::load_key(data_src));
- result.test_eq("recovered public key from private", loaded.get(), true);
+ result.confirm("recovered public key from private", loaded.get() != nullptr);
result.test_eq("public key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true);
}
@@ -399,7 +412,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
std::unique_ptr<Botan::Private_Key> loaded(
Botan::PKCS8::load_key(data_src, Test::rng()));
- result.test_eq("recovered private key from PEM blob", loaded.get(), true);
+ result.confirm("recovered private key from PEM blob", loaded.get() != nullptr);
result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true);
}
@@ -413,7 +426,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
Botan::DataSource_Memory data_src(Botan::PKCS8::BER_encode(key));
std::unique_ptr<Botan::Public_Key> loaded(Botan::PKCS8::load_key(data_src, Test::rng()));
- result.test_eq("recovered public key from private", loaded.get(), true);
+ result.confirm("recovered public key from private", loaded.get() != nullptr);
result.test_eq("public key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("public key passes checks", loaded->check_key(Test::rng(), false), true);
}
@@ -433,7 +446,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
std::unique_ptr<Botan::Private_Key> loaded(
Botan::PKCS8::load_key(data_src, Test::rng(), passphrase));
- result.test_eq("recovered private key from encrypted blob", loaded.get(), true);
+ result.confirm("recovered private key from encrypted blob", loaded.get() != nullptr);
result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true);
}
@@ -451,7 +464,7 @@ PK_Key_Generation_Test::test_key(const std::string& algo, const Botan::Private_K
std::unique_ptr<Botan::Private_Key> loaded(
Botan::PKCS8::load_key(data_src, Test::rng(), passphrase));
- result.test_eq("recovered private key from BER blob", loaded.get(), true);
+ result.confirm("recovered private key from BER blob", loaded.get() != nullptr);
result.test_eq("reloaded key has same type", loaded->algo_name(), key.algo_name());
result.test_eq("private key passes checks", loaded->check_key(Test::rng(), false), true);
}
diff --git a/src/tests/test_utils.cpp b/src/tests/test_utils.cpp
index 47f740a17..04d1092d8 100644
--- a/src/tests/test_utils.cpp
+++ b/src/tests/test_utils.cpp
@@ -1,5 +1,6 @@
/*
* (C) 2015 Jack Lloyd
+* (C) 2016 Daniel Neus, Rohde & Schwarz Cybersecurity
*
* Botan is released under the Simplified BSD License (see license.txt)
*/
@@ -9,6 +10,7 @@
#include <botan/loadstor.h>
#include <botan/calendar.h>
#include <botan/internal/rounding.h>
+#include <botan/charset.h>
#if defined(BOTAN_HAS_BASE64_CODEC)
#include <botan/base64.h>
@@ -326,6 +328,129 @@ BOTAN_REGISTER_TEST("base64", Base64_Tests);
#endif
+class Charset_Tests : public Text_Based_Test
+ {
+ public:
+ Charset_Tests() : Text_Based_Test("charset.vec",
+ { "In","Out" })
+ {}
+
+ Test::Result run_one_test(const std::string& type, const VarMap& vars) override
+ {
+ using namespace Botan;
+
+ Test::Result result("Charset");
+
+ const std::vector<byte> in = get_req_bin(vars, "In");
+ const std::vector<byte> expected = get_req_bin(vars, "Out");
+
+ std::string converted;
+ if(type == "UTF16-LATIN1")
+ {
+ converted = Charset::transcode(std::string(in.begin(), in.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UCS2_CHARSET);
+ }
+ else if(type == "UTF8-LATIN1")
+ {
+ converted = Charset::transcode(std::string(in.begin(), in.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UTF8_CHARSET);
+ }
+ else if(type == "LATIN1-UTF8")
+ {
+ converted = Charset::transcode(std::string(in.begin(), in.end()),
+ Character_Set::UTF8_CHARSET, Character_Set::LATIN1_CHARSET);
+ }
+ else
+ {
+ throw Test_Error("Unexpected header '" + type + "' in charset tests");
+ }
+
+ result.test_eq("string converted successfully", std::vector<byte>(converted.begin(), converted.end()), expected);
+
+ return result;
+ }
+
+ Test::Result utf16_to_latin1_negative_tests()
+ {
+ using namespace Botan;
+
+ Test::Result result("Charset negative tests");
+
+ result.test_throws("conversion fails for non-Latin1 characters", []()
+ {
+ // "abcdef�abcdef"
+ std::vector<byte> input = { 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66, 0x01,
+ 0x78, 0x00, 0x61, 0x00, 0x62, 0x00, 0x63, 0x00, 0x64, 0x00, 0x65, 0x00, 0x66
+ };
+
+ Charset::transcode(std::string(input.begin(), input.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UCS2_CHARSET);
+ });
+
+ result.test_throws("conversion fails for UTF16 string with odd number of bytes", []()
+ {
+ std::vector<byte> input = { 0x00, 0x61, 0x00 };
+
+ Charset::transcode(std::string(input.begin(), input.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UCS2_CHARSET);
+ });
+
+ return result;
+ }
+
+ Test::Result utf8_to_latin1_negative_tests()
+ {
+ using namespace Botan;
+
+ Test::Result result("Charset negative tests");
+
+ result.test_throws("conversion fails for non-Latin1 characters", []()
+ {
+ // "abcdef�abcdef"
+ std::vector<byte> input = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xC5,
+ 0xB8, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66
+ };
+
+ Charset::transcode(std::string(input.begin(), input.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UTF8_CHARSET);
+ });
+
+ result.test_throws("invalid utf-8 string", []()
+ {
+ // sequence truncated
+ std::vector<byte> input = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xC5 };
+
+ Charset::transcode(std::string(input.begin(), input.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UTF8_CHARSET);
+ });
+
+ result.test_throws("invalid utf-8 string", []()
+ {
+ std::vector<byte> input = { 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0xC8, 0xB8, 0x61 };
+
+ Charset::transcode(std::string(input.begin(), input.end()),
+ Character_Set::LATIN1_CHARSET, Character_Set::UTF8_CHARSET);
+ });
+
+ return result;
+ }
+
+ std::vector<Test::Result> run_final_tests() override
+ {
+ using namespace Botan;
+
+ Test::Result result("Charset negative tests");
+
+ result.merge(utf16_to_latin1_negative_tests());
+ result.merge(utf8_to_latin1_negative_tests());
+
+ return{ result };
+ }
+
+ };
+
+BOTAN_REGISTER_TEST("charset", Charset_Tests);
+
}
}