aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/cli/cli.h2
-rw-r--r--src/cli/speed.cpp14
-rw-r--r--src/lib/rng/auto_rng/auto_rng.h2
-rw-r--r--src/lib/stream/chacha/chacha.cpp25
-rw-r--r--src/lib/stream/chacha/chacha.h15
-rw-r--r--src/lib/stream/stream_cipher.cpp2
-rwxr-xr-xsrc/python/botan.py15
-rw-r--r--src/tests/data/stream/chacha.vec17
-rw-r--r--src/tests/test_entropy.cpp6
9 files changed, 74 insertions, 24 deletions
diff --git a/src/cli/cli.h b/src/cli/cli.h
index c2609bc55..11cc8add7 100644
--- a/src/cli/cli.h
+++ b/src/cli/cli.h
@@ -443,7 +443,7 @@ class Command
while(in.good())
{
in.read(reinterpret_cast<char*>(buf.data()), buf.size());
- consumer_fn(buf.data(), in.gcount());
+ consumer_fn(buf.data(), static_cast<size_t>(in.gcount()));
}
}
diff --git a/src/cli/speed.cpp b/src/cli/speed.cpp
index ffe10844e..c767b2a55 100644
--- a/src/cli/speed.cpp
+++ b/src/cli/speed.cpp
@@ -597,13 +597,14 @@ class Speed final : public Command
for(auto src : srcs.enabled_sources())
{
- size_t entropy_bits = 0, samples = 0;
+ double entropy_bits = 0.0;
+ size_t samples = 0;
std::vector<size_t> entropy;
Botan::Entropy_Accumulator accum(
- [&](const uint8_t buf[], size_t buf_len, size_t buf_entropy) -> bool {
- entropy.insert(entropy.end(), buf, buf + buf_len);
- entropy_bits += buf_entropy;
+ [&](const uint8_t buf[], size_t buf_len, double buf_entropy) -> bool {
+ entropy.insert(entropy.end(), buf, buf + buf_len);
+ entropy_bits += buf_entropy;
samples += 1;
return (samples > 1024 || entropy_bits > 1024 || clock::now() > deadline);
});
@@ -623,8 +624,9 @@ class Speed final : public Command
}
#endif
- output() << "Entropy source " << src << " output " << entropy.size()
- << " bytes in " << timer.milliseconds() << " ms";
+ output() << "Entropy source " << src << " output " << entropy.size() << " bytes"
+ << " estimated entropy " << entropy_bits
+ << " in " << timer.milliseconds() << " ms";
#if defined(BOTAN_HAS_COMPRESSION)
if(compressed.size() > 0)
diff --git a/src/lib/rng/auto_rng/auto_rng.h b/src/lib/rng/auto_rng/auto_rng.h
index ce0c5a7d2..72ea88d3e 100644
--- a/src/lib/rng/auto_rng/auto_rng.h
+++ b/src/lib/rng/auto_rng/auto_rng.h
@@ -13,7 +13,7 @@
namespace Botan {
-class BOTAN_DLL AutoSeeded_RNG : public RandomNumberGenerator
+class AutoSeeded_RNG : public RandomNumberGenerator
{
public:
void randomize(byte out[], size_t len) override
diff --git a/src/lib/stream/chacha/chacha.cpp b/src/lib/stream/chacha/chacha.cpp
index 0a32c720b..ac81fd70d 100644
--- a/src/lib/stream/chacha/chacha.cpp
+++ b/src/lib/stream/chacha/chacha.cpp
@@ -10,8 +10,18 @@
namespace Botan {
-void ChaCha::chacha(byte output[64], const u32bit input[16])
+ChaCha::ChaCha(size_t rounds) : m_rounds(rounds)
{
+ if(m_rounds != 12 && m_rounds != 20)
+ throw Invalid_Argument("ChaCha only supports 12 or 20 rounds");
+ }
+
+namespace {
+
+void chacha(byte output[64], const u32bit input[16], size_t rounds)
+ {
+ BOTAN_ASSERT(rounds % 2 == 0, "Valid rounds");
+
u32bit x00 = input[ 0], x01 = input[ 1], x02 = input[ 2], x03 = input[ 3],
x04 = input[ 4], x05 = input[ 5], x06 = input[ 6], x07 = input[ 7],
x08 = input[ 8], x09 = input[ 9], x10 = input[10], x11 = input[11],
@@ -25,7 +35,7 @@ void ChaCha::chacha(byte output[64], const u32bit input[16])
c += d; b ^= c; b = rotate_left(b, 7); \
} while(0)
- for(size_t i = 0; i != 10; ++i)
+ for(size_t i = 0; i != rounds / 2; ++i)
{
CHACHA_QUARTER_ROUND(x00, x04, x08, x12);
CHACHA_QUARTER_ROUND(x01, x05, x09, x13);
@@ -58,6 +68,8 @@ void ChaCha::chacha(byte output[64], const u32bit input[16])
store_le(x15 + input[15], output + 4 * 15);
}
+}
+
/*
* Combine cipher stream with message
*/
@@ -69,7 +81,7 @@ void ChaCha::cipher(const byte in[], byte out[], size_t length)
length -= (m_buffer.size() - m_position);
in += (m_buffer.size() - m_position);
out += (m_buffer.size() - m_position);
- chacha(m_buffer.data(), m_state.data());
+ chacha(m_buffer.data(), m_state.data(), m_rounds);
++m_state[12];
m_state[13] += (m_state[12] == 0);
@@ -142,7 +154,7 @@ void ChaCha::set_iv(const byte iv[], size_t length)
m_state[15] = load_le<u32bit>(iv, 2);
}
- chacha(m_buffer.data(), m_state.data());
+ chacha(m_buffer.data(), m_state.data(), m_rounds);
++m_state[12];
m_state[13] += (m_state[12] == 0);
@@ -156,4 +168,9 @@ void ChaCha::clear()
m_position = 0;
}
+std::string ChaCha::name() const
+ {
+ return "ChaCha(" + std::to_string(m_rounds) + ")";
+ }
+
}
diff --git a/src/lib/stream/chacha/chacha.h b/src/lib/stream/chacha/chacha.h
index 92f8ef035..ba93d6260 100644
--- a/src/lib/stream/chacha/chacha.h
+++ b/src/lib/stream/chacha/chacha.h
@@ -18,6 +18,14 @@ namespace Botan {
class BOTAN_DLL ChaCha final : public StreamCipher
{
public:
+ StreamCipher* clone() const override { return new ChaCha(m_rounds); }
+
+ /**
+ * Currently only 12 or 20 rounds are supported, all others
+ * will throw an exception
+ */
+ ChaCha(size_t rounds);
+
void cipher(const byte in[], byte out[], size_t length) override;
void set_iv(const byte iv[], size_t iv_len) override;
@@ -31,14 +39,13 @@ class BOTAN_DLL ChaCha final : public StreamCipher
}
void clear() override;
- std::string name() const override { return "ChaCha"; }
- StreamCipher* clone() const override { return new ChaCha; }
- protected:
- virtual void chacha(byte output[64], const u32bit input[16]);
+ std::string name() const override;
+
private:
void key_schedule(const byte key[], size_t key_len) override;
+ size_t m_rounds;
secure_vector<u32bit> m_state;
secure_vector<byte> m_buffer;
size_t m_position = 0;
diff --git a/src/lib/stream/stream_cipher.cpp b/src/lib/stream/stream_cipher.cpp
index 03ef5e329..6f98df1fb 100644
--- a/src/lib/stream/stream_cipher.cpp
+++ b/src/lib/stream/stream_cipher.cpp
@@ -51,7 +51,7 @@ void StreamCipher::set_iv(const byte[], size_t iv_len)
}
#if defined(BOTAN_HAS_CHACHA)
-BOTAN_REGISTER_T_NOARGS(StreamCipher, ChaCha);
+BOTAN_REGISTER_T_1LEN(StreamCipher, ChaCha, 20);
#endif
#if defined(BOTAN_HAS_SALSA20)
diff --git a/src/python/botan.py b/src/python/botan.py
index 1cb141ef5..6e5f457b3 100755
--- a/src/python/botan.py
+++ b/src/python/botan.py
@@ -310,16 +310,16 @@ def bcrypt(passwd, rng, work_factor = 10):
out_len = c_size_t(64)
out = create_string_buffer(out_len.value)
flags = c_uint32(0)
- rc = botan.botan_bcrypt_generate(out, byref(out_len), passwd, rng.rng, c_size_t(work_factor), flags)
+ rc = botan.botan_bcrypt_generate(out, byref(out_len), _ctype_str(passwd), rng.rng, c_size_t(work_factor), flags)
if rc != 0:
raise Exception('botan bcrypt failed, error %s' % (rc))
- b = out.raw[0:out_len.value]
+ b = out.raw[0:out_len.value-1]
if b[-1] == '\x00':
b = b[:-1]
return b
def check_bcrypt(passwd, bcrypt):
- rc = botan.botan_bcrypt_is_valid(passwd, bcrypt)
+ rc = botan.botan_bcrypt_is_valid(_ctype_str(passwd), bcrypt)
return (rc == 0)
"""
@@ -715,6 +715,14 @@ def test():
print('x %s' % hex_encode(psk))
print('y %s\n' % (hex_encode(pbkdf('PBKDF2(SHA-256)', 'xyz', 32, iterations, salt)[2])))
+ def test_bcrypt():
+ print("Testing Bcrypt...")
+ r = rng()
+ phash = bcrypt('testing', r)
+ print("bcrypt returned %s (%d bytes)" % (hex_encode(phash), len(phash)))
+ print("validating the hash produced: %r" % (check_bcrypt('testing', phash)))
+ print("\n")
+
def test_hmac():
hmac = message_authentication_code('HMAC(SHA-256)')
@@ -907,6 +915,7 @@ def test():
test_version()
test_kdf()
test_pbkdf()
+ test_bcrypt()
test_hmac()
test_rng()
test_hash()
diff --git a/src/tests/data/stream/chacha.vec b/src/tests/data/stream/chacha.vec
index e4386cbd5..1c3c18c7c 100644
--- a/src/tests/data/stream/chacha.vec
+++ b/src/tests/data/stream/chacha.vec
@@ -1,5 +1,20 @@
-[ChaCha]
+[ChaCha(12)]
+
+# ChaCha(12) test vectors from
+# https://github.com/Yawning/sphincs256/blob/master/chacha/chacha_test.go
+
+Key = 80000000000000000000000000000000
+Nonce = 0000000000000000
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 36CF0D56E9F7FBF287BC5460D95FBA94AA6CBF17D74E7C784DDCF7E0E882DDAE3B5A58243EF32B79A04575A8E2C2B73DC64A52AA15B9F88305A8F0CA0B5A1A25
+
+Key = 0F62B5085BAE0154A7FA4DA0F34699EC3F92E5388BDE3184D72A7DD02376C91C
+Nonce = 288FF65DC42B92F9
+In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
+Out = 49FD8FBF19EDCF3A198F5226AA480B97D9F16BA71A693C4ECB90C276094585DFA4FA259E1EC34DE444C92879BFE7F641EEAC480168DC8969A9C033151B1E9229
+
+[ChaCha(20)]
Key = 00000000000000000000000000000000
Nonce = 0000000000000000
In = 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000
diff --git a/src/tests/test_entropy.cpp b/src/tests/test_entropy.cpp
index 201dd02b5..406dc7c41 100644
--- a/src/tests/test_entropy.cpp
+++ b/src/tests/test_entropy.cpp
@@ -40,10 +40,10 @@ class Entropy_Source_Tests : public Test
{
std::vector<uint8_t> entropy;
size_t samples = 0;
- size_t entropy_estimate = 0;
+ double entropy_estimate = 0.0;
Botan::Entropy_Accumulator accum(
- [&](const uint8_t buf[], size_t buf_len, size_t buf_entropy) -> bool {
+ [&](const uint8_t buf[], size_t buf_len, double buf_entropy) -> bool {
entropy.insert(entropy.end(), buf, buf + buf_len);
entropy_estimate += buf_entropy;
++samples;
@@ -93,7 +93,7 @@ class Entropy_Source_Tests : public Test
comp1_size = compressed.size();
result.test_gte(comp_algo + " compressed entropy better than advertised",
- compressed.size() * 8, entropy_estimate);
+ compressed.size() * 8, static_cast<size_t>(entropy_estimate));
}
catch(std::exception& e)
{