diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cli/cli.h | 2 | ||||
-rw-r--r-- | src/cli/speed.cpp | 14 | ||||
-rw-r--r-- | src/lib/rng/auto_rng/auto_rng.h | 2 | ||||
-rw-r--r-- | src/lib/stream/chacha/chacha.cpp | 25 | ||||
-rw-r--r-- | src/lib/stream/chacha/chacha.h | 15 | ||||
-rw-r--r-- | src/lib/stream/stream_cipher.cpp | 2 | ||||
-rwxr-xr-x | src/python/botan.py | 15 | ||||
-rw-r--r-- | src/tests/data/stream/chacha.vec | 17 | ||||
-rw-r--r-- | src/tests/test_entropy.cpp | 6 |
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) { |