diff options
Diffstat (limited to 'src/lib')
-rw-r--r-- | src/lib/engine/core_engine/lookup_mac.cpp | 10 | ||||
-rw-r--r-- | src/lib/mac/siphash/info.txt | 1 | ||||
-rw-r--r-- | src/lib/mac/siphash/siphash.cpp | 123 | ||||
-rw-r--r-- | src/lib/mac/siphash/siphash.h | 45 |
4 files changed, 179 insertions, 0 deletions
diff --git a/src/lib/engine/core_engine/lookup_mac.cpp b/src/lib/engine/core_engine/lookup_mac.cpp index ba5cd69c6..d5e16cf44 100644 --- a/src/lib/engine/core_engine/lookup_mac.cpp +++ b/src/lib/engine/core_engine/lookup_mac.cpp @@ -25,6 +25,10 @@ #include <botan/poly1305.h> #endif +#if defined(BOTAN_HAS_SIPHASH) + #include <botan/siphash.h> +#endif + #if defined(BOTAN_HAS_ANSI_X919_MAC) #include <botan/x919_mac.h> #endif @@ -53,6 +57,12 @@ Core_Engine::find_mac(const SCAN_Name& request, return new Poly1305; #endif +#if defined(BOTAN_HAS_SIPHASH) + if(request.algo_name() == "SipHash") + return new SipHash(request.arg_as_integer(0, 2), + request.arg_as_integer(1, 4)); +#endif + #if defined(BOTAN_HAS_CBC_MAC) if(request.algo_name() == "CBC-MAC" && request.arg_count() == 1) return new CBC_MAC(af.make_block_cipher(request.arg(0))); diff --git a/src/lib/mac/siphash/info.txt b/src/lib/mac/siphash/info.txt new file mode 100644 index 000000000..98c4d0986 --- /dev/null +++ b/src/lib/mac/siphash/info.txt @@ -0,0 +1 @@ +define SIPHASH 20150110 diff --git a/src/lib/mac/siphash/siphash.cpp b/src/lib/mac/siphash/siphash.cpp new file mode 100644 index 000000000..bc242d4ac --- /dev/null +++ b/src/lib/mac/siphash/siphash.cpp @@ -0,0 +1,123 @@ +/* +* SipHash +* (C) 2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#include <botan/siphash.h> +#include <botan/rotate.h> +#include <botan/loadstor.h> +#include <botan/internal/xor_buf.h> + +namespace Botan { + +namespace { + +void SipRounds(u64bit M, secure_vector<u64bit>& V, size_t r) + { + u64bit V0 = V[0], V1 = V[1], V2 = V[2], V3 = V[3]; + + V3 ^= M; + for(size_t i = 0; i != r; ++i) + { + V0 += V1; V2 += V3; + V1 = rotate_left(V1, 13); + V3 = rotate_left(V3, 16); + V1 ^= V0; V3 ^= V2; + V0 = rotate_left(V0, 32); + + V2 += V1; V0 += V3; + V1 = rotate_left(V1, 17); + V3 = rotate_left(V3, 21); + V1 ^= V2; V3 ^= V0; + V2 = rotate_left(V2, 32); + } + V0 ^= M; + + V[0] = V0; V[1] = V1; V[2] = V2; V[3] = V3; + } + +} + +void SipHash::add_data(const byte input[], size_t length) + { + m_words += length; + + if(m_mbuf_pos) + { + while(length && m_mbuf_pos != 8) + { + m_mbuf = (m_mbuf >> 8) | (static_cast<u64bit>(input[0]) << 56); + ++m_mbuf_pos; + ++input; + length--; + } + + if(m_mbuf_pos == 8) + { + SipRounds(m_mbuf, m_V, m_C); + m_mbuf_pos = 0; + m_mbuf = 0; + } + } + + while(length >= 8) + { + SipRounds(load_le<u64bit>(input, 0), m_V, m_C); + input += 8; + length -= 8; + } + + for(size_t i = 0; i != length; ++i) + { + m_mbuf = (m_mbuf >> 8) | (static_cast<u64bit>(input[i]) << 56); + m_mbuf_pos++; + } + } + +void SipHash::final_result(byte mac[]) + { + m_mbuf = (m_mbuf >> (64-m_mbuf_pos*8)) | (static_cast<u64bit>(m_words) << 56); + SipRounds(m_mbuf, m_V, m_C); + + m_V[2] ^= 0xFF; + SipRounds(0, m_V, m_D); + + const u64bit X = m_V[0] ^ m_V[1] ^ m_V[2] ^ m_V[3]; + + store_le(X, mac); + + m_mbuf = 0; + m_mbuf_pos = 0; + m_words = 0; + } + +void SipHash::key_schedule(const byte key[], size_t) + { + const u64bit K0 = load_le<u64bit>(key, 0); + const u64bit K1 = load_le<u64bit>(key, 1); + + m_V.resize(4); + m_V[0] = K0 ^ 0x736F6D6570736575; + m_V[1] = K1 ^ 0x646F72616E646F6D; + m_V[2] = K0 ^ 0x6C7967656E657261; + m_V[3] = K1 ^ 0x7465646279746573; + } + +void SipHash::clear() + { + m_V.clear(); + } + +std::string SipHash::name() const + { + return "SipHash(" + std::to_string(m_C) + "," + std::to_string(m_D) + ")"; + } + +MessageAuthenticationCode* SipHash::clone() const + { + return new SipHash(m_C, m_D); + } + +} diff --git a/src/lib/mac/siphash/siphash.h b/src/lib/mac/siphash/siphash.h new file mode 100644 index 000000000..ec57864eb --- /dev/null +++ b/src/lib/mac/siphash/siphash.h @@ -0,0 +1,45 @@ +/* +* SipHash +* (C) 2014,2015 Jack Lloyd +* +* Botan is released under the Simplified BSD License (see license.txt) +*/ + +#ifndef BOTAN_SIPHASH_H__ +#define BOTAN_SIPHASH_H__ + +#include <botan/mac.h> + +namespace Botan { + +class BOTAN_DLL SipHash : public MessageAuthenticationCode + { + public: + SipHash(size_t c = 2, size_t d = 4) : m_C(c), m_D(d) {} + + void clear(); + std::string name() const; + + MessageAuthenticationCode* clone() const; + + size_t output_length() const { return 8; } + + Key_Length_Specification key_spec() const + { + return Key_Length_Specification(16); + } + private: + void add_data(const byte[], size_t); + void final_result(byte[]); + void key_schedule(const byte[], size_t); + + const size_t m_C, m_D; + secure_vector<u64bit> m_V; + u64bit m_mbuf = 0; + size_t m_mbuf_pos = 0; + byte m_words = 0; + }; + +} + +#endif |