diff options
Diffstat (limited to 'src')
204 files changed, 2379 insertions, 2267 deletions
diff --git a/src/alloc/alloc_mmap/mmap_mem.cpp b/src/alloc/alloc_mmap/mmap_mem.cpp index 78177bcdd..e4b602764 100644 --- a/src/alloc/alloc_mmap/mmap_mem.cpp +++ b/src/alloc/alloc_mmap/mmap_mem.cpp @@ -85,20 +85,22 @@ void* MemoryMapping_Allocator::alloc_block(size_t n) if(file.get_fd() == -1) throw MemoryMapping_Failed("Could not create file"); - std::vector<byte> zeros(n); + std::vector<byte> zeros(4096); - ssize_t remaining = n; + size_t remaining = n; while(remaining) { - ssize_t wrote_here = ::write(file.get_fd(), - &zeros[0], - remaining); + const size_t write_try = std::min(zeros.size(), remaining); - if(wrote_here == -1 && errno != EINTR) + ssize_t wrote_got = ::write(file.get_fd(), + &zeros[0], + write_try); + + if(wrote_got == -1 && errno != EINTR) throw MemoryMapping_Failed("Could not write to file"); - remaining -= wrote_here; + remaining -= wrote_got; } #ifndef MAP_NOSYNC diff --git a/src/alloc/secmem.h b/src/alloc/secmem.h index b06be0d55..80e8e59aa 100644 --- a/src/alloc/secmem.h +++ b/src/alloc/secmem.h @@ -34,7 +34,6 @@ class MemoryRegion */ bool empty() const { return (used == 0); } -#if 1 /** * Get a pointer to the first element in the buffer. * @return pointer to the first element in the buffer @@ -46,12 +45,6 @@ class MemoryRegion * @return constant pointer to the first element in the buffer */ operator const T* () const { return buf; } -#else - - T& operator[](size_t n) { return buf[n]; } - const T& operator[](size_t n) const { return buf[n]; } - -#endif /** * Get a pointer to the first element in the buffer. diff --git a/src/asn1/alg_id.cpp b/src/asn1/alg_id.cpp index b48db3e50..665e42fb3 100644 --- a/src/asn1/alg_id.cpp +++ b/src/asn1/alg_id.cpp @@ -41,8 +41,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const OID& alg_id, const byte DER_NULL[] = { 0x05, 0x00 }; oid = alg_id; + if(option == USE_NULL_PARAM) - parameters += std::make_pair(DER_NULL, sizeof(DER_NULL)); + { + parameters += std::make_pair<const byte*, size_t>( + DER_NULL, sizeof(DER_NULL)); + } } /* @@ -54,8 +58,12 @@ AlgorithmIdentifier::AlgorithmIdentifier(const std::string& alg_id, const byte DER_NULL[] = { 0x05, 0x00 }; oid = OIDS::lookup(alg_id); + if(option == USE_NULL_PARAM) - parameters += std::make_pair(DER_NULL, sizeof(DER_NULL)); + { + parameters += std::make_pair<const byte*, size_t>( + DER_NULL, sizeof(DER_NULL)); + } } /* diff --git a/src/block/aes/aes.cpp b/src/block/aes/aes.cpp index 9fb12cd11..5f47762a8 100644 --- a/src/block/aes/aes.cpp +++ b/src/block/aes/aes.cpp @@ -2,6 +2,8 @@ * AES * (C) 1999-2010 Jack Lloyd * +* Based on the public domain reference implemenation +* * Distributed under the terms of the Botan license */ diff --git a/src/block/aes_intel/aes_intel.cpp b/src/block/aes_ni/aes_ni.cpp index a2e660f2c..3ee0e608c 100644 --- a/src/block/aes_intel/aes_intel.cpp +++ b/src/block/aes_ni/aes_ni.cpp @@ -1,11 +1,11 @@ /* -* AES using Intel's AES-NI instructions +* AES using AES-NI instructions * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/aes_intel.h> +#include <botan/aes_ni.h> #include <botan/loadstor.h> #include <wmmintrin.h> @@ -103,7 +103,7 @@ __m128i aes_256_key_expansion(__m128i key, __m128i key2) /* * AES-128 Encryption */ -void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -179,7 +179,7 @@ void AES_128_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Decryption */ -void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_128_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -255,7 +255,7 @@ void AES_128_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-128 Key Schedule */ -void AES_128_Intel::key_schedule(const byte key[], size_t) +void AES_128_NI::key_schedule(const byte key[], size_t) { #define AES_128_key_exp(K, RCON) \ aes_128_key_expansion(K, _mm_aeskeygenassist_si128(K, RCON)) @@ -304,7 +304,7 @@ void AES_128_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_128_Intel::clear() +void AES_128_NI::clear() { zeroise(EK); zeroise(DK); @@ -313,7 +313,7 @@ void AES_128_Intel::clear() /* * AES-192 Encryption */ -void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -395,7 +395,7 @@ void AES_192_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Decryption */ -void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_192_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -477,7 +477,7 @@ void AES_192_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-192 Key Schedule */ -void AES_192_Intel::key_schedule(const byte key[], size_t) +void AES_192_NI::key_schedule(const byte key[], size_t) { __m128i K0 = _mm_loadu_si128((const __m128i*)(key)); __m128i K1 = _mm_loadu_si128((const __m128i*)(key + 8)); @@ -520,7 +520,7 @@ void AES_192_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_192_Intel::clear() +void AES_192_NI::clear() { zeroise(EK); zeroise(DK); @@ -529,7 +529,7 @@ void AES_192_Intel::clear() /* * AES-256 Encryption */ -void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256_NI::encrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -617,7 +617,7 @@ void AES_256_Intel::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Decryption */ -void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const +void AES_256_NI::decrypt_n(const byte in[], byte out[], size_t blocks) const { const __m128i* in_mm = (const __m128i*)in; __m128i* out_mm = (__m128i*)out; @@ -705,7 +705,7 @@ void AES_256_Intel::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * AES-256 Key Schedule */ -void AES_256_Intel::key_schedule(const byte key[], size_t) +void AES_256_NI::key_schedule(const byte key[], size_t) { __m128i K0 = _mm_loadu_si128((const __m128i*)(key)); __m128i K1 = _mm_loadu_si128((const __m128i*)(key + 16)); @@ -770,7 +770,7 @@ void AES_256_Intel::key_schedule(const byte key[], size_t) /* * Clear memory of sensitive data */ -void AES_256_Intel::clear() +void AES_256_NI::clear() { zeroise(EK); zeroise(DK); diff --git a/src/block/aes_intel/aes_intel.h b/src/block/aes_ni/aes_ni.h index a8e6b53e8..ae9e5b3f4 100644 --- a/src/block/aes_intel/aes_intel.h +++ b/src/block/aes_ni/aes_ni.h @@ -1,12 +1,12 @@ /* -* AES using Intel's AES-NI instructions +* AES using AES-NI instructions * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_AES_INTEL_H__ -#define BOTAN_AES_INTEL_H__ +#ifndef BOTAN_AES_NI_H__ +#define BOTAN_AES_NI_H__ #include <botan/block_cipher.h> @@ -15,7 +15,7 @@ namespace Botan { /** * AES-128 using AES-NI */ -class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> +class BOTAN_DLL AES_128_NI : public Block_Cipher_Fixed_Params<16, 16> { public: size_t parallelism() const { return 4; } @@ -25,9 +25,9 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> void clear(); std::string name() const { return "AES-128"; } - BlockCipher* clone() const { return new AES_128_Intel; } + BlockCipher* clone() const { return new AES_128_NI; } - AES_128_Intel() : EK(44), DK(44) { } + AES_128_NI() : EK(44), DK(44) { } private: void key_schedule(const byte[], size_t); @@ -37,7 +37,7 @@ class BOTAN_DLL AES_128_Intel : public Block_Cipher_Fixed_Params<16, 16> /** * AES-192 using AES-NI */ -class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> +class BOTAN_DLL AES_192_NI : public Block_Cipher_Fixed_Params<16, 24> { public: size_t parallelism() const { return 4; } @@ -47,9 +47,9 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> void clear(); std::string name() const { return "AES-192"; } - BlockCipher* clone() const { return new AES_192_Intel; } + BlockCipher* clone() const { return new AES_192_NI; } - AES_192_Intel() : EK(52), DK(52) { } + AES_192_NI() : EK(52), DK(52) { } private: void key_schedule(const byte[], size_t); @@ -59,7 +59,7 @@ class BOTAN_DLL AES_192_Intel : public Block_Cipher_Fixed_Params<16, 24> /** * AES-256 using AES-NI */ -class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32> +class BOTAN_DLL AES_256_NI : public Block_Cipher_Fixed_Params<16, 32> { public: size_t parallelism() const { return 4; } @@ -69,9 +69,9 @@ class BOTAN_DLL AES_256_Intel : public Block_Cipher_Fixed_Params<16, 32> void clear(); std::string name() const { return "AES-256"; } - BlockCipher* clone() const { return new AES_256_Intel; } + BlockCipher* clone() const { return new AES_256_NI; } - AES_256_Intel() : EK(60), DK(60) { } + AES_256_NI() : EK(60), DK(60) { } private: void key_schedule(const byte[], size_t); diff --git a/src/block/aes_intel/info.txt b/src/block/aes_ni/info.txt index 8bf0f07ee..597948fc3 100644 --- a/src/block/aes_intel/info.txt +++ b/src/block/aes_ni/info.txt @@ -1,4 +1,4 @@ -define AES_INTEL +define AES_NI load_on auto diff --git a/src/block/aes_ssse3/aes_ssse3.cpp b/src/block/aes_ssse3/aes_ssse3.cpp index c5869f899..774ccbabb 100644 --- a/src/block/aes_ssse3/aes_ssse3.cpp +++ b/src/block/aes_ssse3/aes_ssse3.cpp @@ -339,10 +339,10 @@ __m128i aes_ssse3_decrypt(__m128i B, const __m128i* keys, size_t rounds) */ void AES_128_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&EK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&EK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -356,10 +356,10 @@ void AES_128_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void AES_128_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&DK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&DK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -376,10 +376,10 @@ void AES_128_SSSE3::key_schedule(const byte keyb[], size_t) __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); - __m128i key = _mm_loadu_si128((const __m128i*)keyb); + __m128i key = _mm_loadu_si128(reinterpret_cast<const __m128i*>(keyb)); - __m128i* EK_mm = (__m128i*)&EK[0]; - __m128i* DK_mm = (__m128i*)&DK[0]; + __m128i* EK_mm = reinterpret_cast<__m128i*>(&EK[0]); + __m128i* DK_mm = reinterpret_cast<__m128i*>(&DK[0]); _mm_storeu_si128(DK_mm + 10, _mm_shuffle_epi8(key, sr[2])); @@ -408,10 +408,10 @@ void AES_128_SSSE3::key_schedule(const byte keyb[], size_t) */ void AES_192_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&EK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&EK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -425,10 +425,10 @@ void AES_192_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void AES_192_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&DK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&DK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -445,11 +445,11 @@ void AES_192_SSSE3::key_schedule(const byte keyb[], size_t) __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); - __m128i* EK_mm = (__m128i*)&EK[0]; - __m128i* DK_mm = (__m128i*)&DK[0]; + __m128i* EK_mm = reinterpret_cast<__m128i*>(&EK[0]); + __m128i* DK_mm = reinterpret_cast<__m128i*>(&DK[0]); - __m128i key1 = _mm_loadu_si128((const __m128i*)keyb); - __m128i key2 = _mm_loadu_si128((const __m128i*)(keyb + 8)); + __m128i key1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(keyb)); + __m128i key2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((keyb + 8))); _mm_storeu_si128(DK_mm + 12, _mm_shuffle_epi8(key1, sr[0])); @@ -507,10 +507,10 @@ void AES_192_SSSE3::key_schedule(const byte keyb[], size_t) */ void AES_256_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&EK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&EK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -524,10 +524,10 @@ void AES_256_SSSE3::encrypt_n(const byte in[], byte out[], size_t blocks) const */ void AES_256_SSSE3::decrypt_n(const byte in[], byte out[], size_t blocks) const { - const __m128i* in_mm = (const __m128i*)in; - __m128i* out_mm = (__m128i*)out; + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); - const __m128i* keys = (const __m128i*)&DK[0]; + const __m128i* keys = reinterpret_cast<const __m128i*>(&DK[0]); for(size_t i = 0; i != blocks; ++i) { @@ -544,11 +544,11 @@ void AES_256_SSSE3::key_schedule(const byte keyb[], size_t) __m128i rcon = _mm_set_epi32(0x702A9808, 0x4D7C7D81, 0x1F8391B9, 0xAF9DEEB6); - __m128i* EK_mm = (__m128i*)&EK[0]; - __m128i* DK_mm = (__m128i*)&DK[0]; + __m128i* EK_mm = reinterpret_cast<__m128i*>(&EK[0]); + __m128i* DK_mm = reinterpret_cast<__m128i*>(&DK[0]); - __m128i key1 = _mm_loadu_si128((const __m128i*)keyb); - __m128i key2 = _mm_loadu_si128((const __m128i*)(keyb + 16)); + __m128i key1 = _mm_loadu_si128(reinterpret_cast<const __m128i*>(keyb)); + __m128i key2 = _mm_loadu_si128(reinterpret_cast<const __m128i*>((keyb + 16))); _mm_storeu_si128(DK_mm + 14, _mm_shuffle_epi8(key1, sr[2])); diff --git a/src/block/des/des.cpp b/src/block/des/des.cpp index 739dfe87c..c500e9bab 100644 --- a/src/block/des/des.cpp +++ b/src/block/des/des.cpp @@ -2,6 +2,9 @@ * DES * (C) 1999-2008 Jack Lloyd * +* Based on a public domain implemenation by Phil Karn (who in turn +* credited Richard Outerbridge and Jim Gillogly) +* * Distributed under the terms of the Botan license */ diff --git a/src/block/idea_sse2/idea_sse2.cpp b/src/block/idea_sse2/idea_sse2.cpp index f2c770103..70698560d 100644 --- a/src/block/idea_sse2/idea_sse2.cpp +++ b/src/block/idea_sse2/idea_sse2.cpp @@ -16,7 +16,6 @@ inline __m128i mul(__m128i X, u16bit K_16) { const __m128i zeros = _mm_set1_epi16(0); const __m128i ones = _mm_set1_epi16(1); - const __m128i high_bit = _mm_set1_epi16(-32767); // 0x8000 const __m128i K = _mm_set1_epi16(K_16); @@ -29,10 +28,9 @@ inline __m128i mul(__m128i X, u16bit K_16) __m128i T = _mm_sub_epi16(mul_lo, mul_hi); // Unsigned compare; cmp = 1 if mul_lo < mul_hi else 0 - const __m128i cmp = _mm_srli_epi16(_mm_cmpgt_epi16( - _mm_add_epi16(mul_hi, high_bit), - _mm_add_epi16(mul_lo, high_bit)), - 15); + const __m128i subs = _mm_subs_epu16(mul_hi, mul_lo); + const __m128i cmp = _mm_min_epu8( + _mm_or_si128(subs, _mm_srli_epi16(subs, 8)), ones); T = _mm_add_epi16(T, cmp); @@ -131,10 +129,12 @@ void transpose_out(__m128i& B0, __m128i& B1, __m128i& B2, __m128i& B3) */ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) { - __m128i B0 = _mm_loadu_si128((const __m128i*)in); - __m128i B1 = _mm_loadu_si128((const __m128i*)in + 1); - __m128i B2 = _mm_loadu_si128((const __m128i*)in + 2); - __m128i B3 = _mm_loadu_si128((const __m128i*)in + 3); + const __m128i* in_mm = reinterpret_cast<const __m128i*>(in); + + __m128i B0 = _mm_loadu_si128(in_mm + 0); + __m128i B1 = _mm_loadu_si128(in_mm + 1); + __m128i B2 = _mm_loadu_si128(in_mm + 2); + __m128i B3 = _mm_loadu_si128(in_mm + 3); transpose_in(B0, B1, B2, B3); @@ -183,10 +183,12 @@ void idea_op_8(const byte in[64], byte out[64], const u16bit EK[52]) transpose_out(B0, B2, B1, B3); - _mm_storeu_si128((__m128i*)out, B0); - _mm_storeu_si128((__m128i*)out + 1, B2); - _mm_storeu_si128((__m128i*)out + 2, B1); - _mm_storeu_si128((__m128i*)out + 3, B3); + __m128i* out_mm = reinterpret_cast<__m128i*>(out); + + _mm_storeu_si128(out_mm + 0, B0); + _mm_storeu_si128(out_mm + 1, B2); + _mm_storeu_si128(out_mm + 2, B1); + _mm_storeu_si128(out_mm + 3, B3); } } diff --git a/src/block/noekeon_simd/info.txt b/src/block/noekeon_simd/info.txt index b73954cff..deac80702 100644 --- a/src/block/noekeon_simd/info.txt +++ b/src/block/noekeon_simd/info.txt @@ -2,6 +2,6 @@ define NOEKEON_SIMD <requires> noekeon -simd_32 +simd simd_engine </requires> diff --git a/src/block/noekeon_simd/noekeon_simd.cpp b/src/block/noekeon_simd/noekeon_simd.cpp index 97158593a..b2beafc82 100644 --- a/src/block/noekeon_simd/noekeon_simd.cpp +++ b/src/block/noekeon_simd/noekeon_simd.cpp @@ -16,7 +16,12 @@ namespace Botan { #define NOK_SIMD_THETA(A0, A1, A2, A3, K0, K1, K2, K3) \ do { \ SIMD_32 T = A0 ^ A2; \ - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); \ + SIMD_32 T_l8 = T; \ + SIMD_32 T_r8 = T; \ + T_l8.rotate_left(8); \ + T_r8.rotate_right(8); \ + T ^= T_l8; \ + T ^= T_r8; \ A1 ^= T; \ A3 ^= T; \ \ @@ -26,7 +31,12 @@ namespace Botan { A3 ^= K3; \ \ T = A1 ^ A3; \ - T ^= rotate_left(T, 8) ^ rotate_right(T, 8); \ + T_l8 = T; \ + T_r8 = T; \ + T_l8.rotate_left(8); \ + T_r8.rotate_right(8); \ + T ^= T_l8; \ + T ^= T_r8; \ A0 ^= T; \ A2 ^= T; \ } while(0) diff --git a/src/block/serpent/serpent.cpp b/src/block/serpent/serpent.cpp index 1d940cf39..b3cf0f6c9 100644 --- a/src/block/serpent/serpent.cpp +++ b/src/block/serpent/serpent.cpp @@ -2,6 +2,9 @@ * Serpent * (C) 1999-2007 Jack Lloyd * +* The sbox expressions used here were discovered by Dag Arne Osvik and +* are described in his paper "Speeding Up Serpent". +* * Distributed under the terms of the Botan license */ diff --git a/src/block/serpent_simd/info.txt b/src/block/serpent_simd/info.txt index b3bf34972..cd1a0dc7e 100644 --- a/src/block/serpent_simd/info.txt +++ b/src/block/serpent_simd/info.txt @@ -2,7 +2,7 @@ define SERPENT_SIMD <requires> serpent -simd_32 +simd simd_engine </requires> @@ -13,7 +13,3 @@ serp_simd.cpp <header:public> serp_simd.h </header:public> - -<header:internal> -serp_simd_sbox.h -</header:internal> diff --git a/src/block/serpent_simd/serp_simd.cpp b/src/block/serpent_simd/serp_simd.cpp index babe68d40..2b5e429fc 100644 --- a/src/block/serpent_simd/serp_simd.cpp +++ b/src/block/serpent_simd/serp_simd.cpp @@ -6,7 +6,6 @@ */ #include <botan/serp_simd.h> -#include <botan/internal/serp_simd_sbox.h> #include <botan/internal/simd_32.h> #include <botan/loadstor.h> @@ -14,6 +13,420 @@ namespace Botan { namespace { +#define SBoxE1(B0, B1, B2, B3) \ + do { \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B4 ^= B2; \ + B1 ^= B0; \ + B0 |= B3; \ + B0 ^= B4; \ + B4 ^= B3; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 ^= B4; \ + B4 = ~B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B1 ^= B4; \ + B3 |= B0; \ + B1 ^= B3; \ + B4 ^= B3; \ + B3 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE2(B0, B1, B2, B3) \ + do { \ + B0 = ~B0; \ + B2 = ~B2; \ + SIMD_32 B4 = B0; \ + B0 &= B1; \ + B2 ^= B0; \ + B0 |= B3; \ + B3 ^= B2; \ + B1 ^= B0; \ + B0 ^= B4; \ + B4 |= B1; \ + B1 ^= B3; \ + B2 |= B0; \ + B2 &= B4; \ + B0 ^= B1; \ + B1 &= B2; \ + B1 ^= B0; \ + B0 &= B2; \ + B4 ^= B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE3(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 &= B2; \ + B0 ^= B3; \ + B2 ^= B1; \ + B2 ^= B0; \ + B3 |= B4; \ + B3 ^= B1; \ + B4 ^= B2; \ + B1 = B3; \ + B3 |= B4; \ + B3 ^= B0; \ + B0 &= B1; \ + B4 ^= B0; \ + B1 ^= B3; \ + B1 ^= B4; \ + B0 = B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = ~B4; \ + } while(0); + +#define SBoxE4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B0; \ + B0 |= B3; \ + B3 ^= B1; \ + B1 &= B4; \ + B4 ^= B2; \ + B2 ^= B3; \ + B3 &= B0; \ + B4 |= B1; \ + B3 ^= B4; \ + B0 ^= B1; \ + B4 &= B0; \ + B1 ^= B3; \ + B4 ^= B2; \ + B1 |= B0; \ + B1 ^= B2; \ + B0 ^= B3; \ + B2 = B1; \ + B1 |= B3; \ + B0 ^= B1; \ + B1 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE5(B0, B1, B2, B3) \ + do { \ + B1 ^= B3; \ + B3 = ~B3; \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B1; \ + B1 &= B3; \ + B1 ^= B2; \ + B4 ^= B3; \ + B0 ^= B4; \ + B2 &= B4; \ + B2 ^= B0; \ + B0 &= B1; \ + B3 ^= B0; \ + B4 |= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B2 &= B3; \ + B0 = ~B0; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxE6(B0, B1, B2, B3) \ + do { \ + B0 ^= B1; \ + B1 ^= B3; \ + B3 = ~B3; \ + SIMD_32 B4 = B1; \ + B1 &= B0; \ + B2 ^= B3; \ + B1 ^= B2; \ + B2 |= B4; \ + B4 ^= B3; \ + B3 &= B1; \ + B3 ^= B0; \ + B4 ^= B1; \ + B4 ^= B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B2 = ~B2; \ + B0 ^= B4; \ + B4 |= B3; \ + B4 ^= B2; \ + B2 = B0; \ + B0 = B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxE7(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B3; \ + B3 &= B0; \ + B0 ^= B4; \ + B3 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B2 ^= B0; \ + B0 |= B1; \ + B2 ^= B1; \ + B4 ^= B0; \ + B0 |= B3; \ + B0 ^= B2; \ + B4 ^= B3; \ + B4 ^= B0; \ + B3 = ~B3; \ + B2 &= B4; \ + B3 ^= B2; \ + B2 = B4; \ + } while(0); + +#define SBoxE8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 |= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B2 ^= B1; \ + B3 |= B4; \ + B3 &= B0; \ + B4 ^= B2; \ + B3 ^= B1; \ + B1 |= B4; \ + B1 ^= B0; \ + B0 |= B4; \ + B0 ^= B2; \ + B1 ^= B4; \ + B2 ^= B1; \ + B1 &= B0; \ + B1 ^= B4; \ + B2 = ~B2; \ + B2 |= B0; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B3; \ + B3 = B0; \ + B0 = B4; \ + } while(0); + +#define SBoxD1(B0, B1, B2, B3) \ + do { \ + B2 = ~B2; \ + SIMD_32 B4 = B1; \ + B1 |= B0; \ + B4 = ~B4; \ + B1 ^= B2; \ + B2 |= B4; \ + B1 ^= B3; \ + B0 ^= B4; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 ^= B0; \ + B0 |= B1; \ + B0 ^= B2; \ + B3 ^= B4; \ + B2 ^= B1; \ + B3 ^= B0; \ + B3 ^= B1; \ + B2 &= B3; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD2(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B1; \ + B1 ^= B3; \ + B3 &= B1; \ + B4 ^= B2; \ + B3 ^= B0; \ + B0 |= B1; \ + B2 ^= B3; \ + B0 ^= B4; \ + B0 |= B2; \ + B1 ^= B3; \ + B0 ^= B1; \ + B1 |= B3; \ + B1 ^= B0; \ + B4 = ~B4; \ + B4 ^= B1; \ + B1 |= B0; \ + B1 ^= B0; \ + B1 |= B4; \ + B3 ^= B1; \ + B1 = B0; \ + B0 = B4; \ + B4 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD3(B0, B1, B2, B3) \ + do { \ + B2 ^= B3; \ + B3 ^= B0; \ + SIMD_32 B4 = B3; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 |= B2; \ + B1 ^= B4; \ + B4 &= B3; \ + B2 ^= B3; \ + B4 &= B0; \ + B4 ^= B2; \ + B2 &= B1; \ + B2 |= B0; \ + B3 = ~B3; \ + B2 ^= B3; \ + B0 ^= B3; \ + B0 &= B1; \ + B3 ^= B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + } while(0); + +#define SBoxD4(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B1; \ + B0 ^= B2; \ + B4 &= B2; \ + B4 ^= B0; \ + B0 &= B1; \ + B1 ^= B3; \ + B3 |= B4; \ + B2 ^= B3; \ + B0 ^= B3; \ + B1 ^= B4; \ + B3 &= B2; \ + B3 ^= B1; \ + B1 ^= B0; \ + B1 |= B2; \ + B0 ^= B3; \ + B1 ^= B4; \ + B0 ^= B1; \ + B4 = B0; \ + B0 = B2; \ + B2 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD5(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 &= B3; \ + B2 ^= B1; \ + B1 |= B3; \ + B1 &= B0; \ + B4 ^= B2; \ + B4 ^= B1; \ + B1 &= B2; \ + B0 = ~B0; \ + B3 ^= B4; \ + B1 ^= B3; \ + B3 &= B0; \ + B3 ^= B2; \ + B0 ^= B1; \ + B2 &= B0; \ + B3 ^= B0; \ + B2 ^= B4; \ + B2 |= B3; \ + B3 ^= B0; \ + B2 ^= B1; \ + B1 = B3; \ + B3 = B4; \ + } while(0); + +#define SBoxD6(B0, B1, B2, B3) \ + do { \ + B1 = ~B1; \ + SIMD_32 B4 = B3; \ + B2 ^= B1; \ + B3 |= B0; \ + B3 ^= B2; \ + B2 |= B1; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 ^= B4; \ + B4 |= B0; \ + B4 ^= B1; \ + B1 &= B2; \ + B1 ^= B3; \ + B4 ^= B2; \ + B3 &= B4; \ + B4 ^= B1; \ + B3 ^= B4; \ + B4 = ~B4; \ + B3 ^= B0; \ + B0 = B1; \ + B1 = B4; \ + B4 = B3; \ + B3 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD7(B0, B1, B2, B3) \ + do { \ + B0 ^= B2; \ + SIMD_32 B4 = B2; \ + B2 &= B0; \ + B4 ^= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B2 ^= B3; \ + B4 |= B0; \ + B0 ^= B2; \ + B3 ^= B4; \ + B4 ^= B1; \ + B1 &= B3; \ + B1 ^= B0; \ + B0 ^= B3; \ + B0 |= B2; \ + B3 ^= B1; \ + B4 ^= B0; \ + B0 = B1; \ + B1 = B2; \ + B2 = B4; \ + } while(0); + +#define SBoxD8(B0, B1, B2, B3) \ + do { \ + SIMD_32 B4 = B2; \ + B2 ^= B0; \ + B0 &= B3; \ + B4 |= B3; \ + B2 = ~B2; \ + B3 ^= B1; \ + B1 |= B0; \ + B0 ^= B2; \ + B2 &= B4; \ + B3 &= B4; \ + B1 ^= B2; \ + B2 ^= B0; \ + B0 |= B2; \ + B4 ^= B1; \ + B0 ^= B3; \ + B3 ^= B4; \ + B4 |= B0; \ + B3 ^= B2; \ + B4 ^= B2; \ + B2 = B1; \ + B1 = B0; \ + B0 = B3; \ + B3 = B4; \ + } while(0); + #define key_xor(round, B0, B1, B2, B3) \ do { \ B0 ^= SIMD_32(keys[4*round ]); \ @@ -175,6 +588,24 @@ void serpent_decrypt_4(const byte in[64], #undef transform #undef i_transform +#undef SBoxE1 +#undef SBoxE2 +#undef SBoxE3 +#undef SBoxE4 +#undef SBoxE5 +#undef SBoxE6 +#undef SBoxE7 +#undef SBoxE8 + +#undef SBoxD1 +#undef SBoxD2 +#undef SBoxD3 +#undef SBoxD4 +#undef SBoxD5 +#undef SBoxD6 +#undef SBoxD7 +#undef SBoxD8 + /* * Serpent Encryption */ diff --git a/src/block/serpent_simd/serp_simd_sbox.h b/src/block/serpent_simd/serp_simd_sbox.h deleted file mode 100644 index 71eca19e5..000000000 --- a/src/block/serpent_simd/serp_simd_sbox.h +++ /dev/null @@ -1,425 +0,0 @@ -/* -* Serpent Sboxes in SIMD form -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SERPENT_SIMD_SBOXES_H__ -#define BOTAN_SERPENT_SIMD_SBOXES_H__ - -#define SBoxE1(B0, B1, B2, B3) \ - do { \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B4 ^= B2; \ - B1 ^= B0; \ - B0 |= B3; \ - B0 ^= B4; \ - B4 ^= B3; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 ^= B4; \ - B4 = ~B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B1 ^= B4; \ - B3 |= B0; \ - B1 ^= B3; \ - B4 ^= B3; \ - B3 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE2(B0, B1, B2, B3) \ - do { \ - B0 = ~B0; \ - B2 = ~B2; \ - SIMD_32 B4 = B0; \ - B0 &= B1; \ - B2 ^= B0; \ - B0 |= B3; \ - B3 ^= B2; \ - B1 ^= B0; \ - B0 ^= B4; \ - B4 |= B1; \ - B1 ^= B3; \ - B2 |= B0; \ - B2 &= B4; \ - B0 ^= B1; \ - B1 &= B2; \ - B1 ^= B0; \ - B0 &= B2; \ - B4 ^= B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE3(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 &= B2; \ - B0 ^= B3; \ - B2 ^= B1; \ - B2 ^= B0; \ - B3 |= B4; \ - B3 ^= B1; \ - B4 ^= B2; \ - B1 = B3; \ - B3 |= B4; \ - B3 ^= B0; \ - B0 &= B1; \ - B4 ^= B0; \ - B1 ^= B3; \ - B1 ^= B4; \ - B0 = B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = ~B4; \ - } while(0); - -#define SBoxE4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B0; \ - B0 |= B3; \ - B3 ^= B1; \ - B1 &= B4; \ - B4 ^= B2; \ - B2 ^= B3; \ - B3 &= B0; \ - B4 |= B1; \ - B3 ^= B4; \ - B0 ^= B1; \ - B4 &= B0; \ - B1 ^= B3; \ - B4 ^= B2; \ - B1 |= B0; \ - B1 ^= B2; \ - B0 ^= B3; \ - B2 = B1; \ - B1 |= B3; \ - B0 ^= B1; \ - B1 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE5(B0, B1, B2, B3) \ - do { \ - B1 ^= B3; \ - B3 = ~B3; \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B1; \ - B1 &= B3; \ - B1 ^= B2; \ - B4 ^= B3; \ - B0 ^= B4; \ - B2 &= B4; \ - B2 ^= B0; \ - B0 &= B1; \ - B3 ^= B0; \ - B4 |= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B2 &= B3; \ - B0 = ~B0; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxE6(B0, B1, B2, B3) \ - do { \ - B0 ^= B1; \ - B1 ^= B3; \ - B3 = ~B3; \ - SIMD_32 B4 = B1; \ - B1 &= B0; \ - B2 ^= B3; \ - B1 ^= B2; \ - B2 |= B4; \ - B4 ^= B3; \ - B3 &= B1; \ - B3 ^= B0; \ - B4 ^= B1; \ - B4 ^= B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B2 = ~B2; \ - B0 ^= B4; \ - B4 |= B3; \ - B4 ^= B2; \ - B2 = B0; \ - B0 = B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxE7(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B3; \ - B3 &= B0; \ - B0 ^= B4; \ - B3 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B2 ^= B0; \ - B0 |= B1; \ - B2 ^= B1; \ - B4 ^= B0; \ - B0 |= B3; \ - B0 ^= B2; \ - B4 ^= B3; \ - B4 ^= B0; \ - B3 = ~B3; \ - B2 &= B4; \ - B3 ^= B2; \ - B2 = B4; \ - } while(0); - -#define SBoxE8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 |= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B2 ^= B1; \ - B3 |= B4; \ - B3 &= B0; \ - B4 ^= B2; \ - B3 ^= B1; \ - B1 |= B4; \ - B1 ^= B0; \ - B0 |= B4; \ - B0 ^= B2; \ - B1 ^= B4; \ - B2 ^= B1; \ - B1 &= B0; \ - B1 ^= B4; \ - B2 = ~B2; \ - B2 |= B0; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B3; \ - B3 = B0; \ - B0 = B4; \ - } while(0); - -#define SBoxD1(B0, B1, B2, B3) \ - do { \ - B2 = ~B2; \ - SIMD_32 B4 = B1; \ - B1 |= B0; \ - B4 = ~B4; \ - B1 ^= B2; \ - B2 |= B4; \ - B1 ^= B3; \ - B0 ^= B4; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 ^= B0; \ - B0 |= B1; \ - B0 ^= B2; \ - B3 ^= B4; \ - B2 ^= B1; \ - B3 ^= B0; \ - B3 ^= B1; \ - B2 &= B3; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD2(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B1; \ - B1 ^= B3; \ - B3 &= B1; \ - B4 ^= B2; \ - B3 ^= B0; \ - B0 |= B1; \ - B2 ^= B3; \ - B0 ^= B4; \ - B0 |= B2; \ - B1 ^= B3; \ - B0 ^= B1; \ - B1 |= B3; \ - B1 ^= B0; \ - B4 = ~B4; \ - B4 ^= B1; \ - B1 |= B0; \ - B1 ^= B0; \ - B1 |= B4; \ - B3 ^= B1; \ - B1 = B0; \ - B0 = B4; \ - B4 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD3(B0, B1, B2, B3) \ - do { \ - B2 ^= B3; \ - B3 ^= B0; \ - SIMD_32 B4 = B3; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 |= B2; \ - B1 ^= B4; \ - B4 &= B3; \ - B2 ^= B3; \ - B4 &= B0; \ - B4 ^= B2; \ - B2 &= B1; \ - B2 |= B0; \ - B3 = ~B3; \ - B2 ^= B3; \ - B0 ^= B3; \ - B0 &= B1; \ - B3 ^= B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - } while(0); - -#define SBoxD4(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B1; \ - B0 ^= B2; \ - B4 &= B2; \ - B4 ^= B0; \ - B0 &= B1; \ - B1 ^= B3; \ - B3 |= B4; \ - B2 ^= B3; \ - B0 ^= B3; \ - B1 ^= B4; \ - B3 &= B2; \ - B3 ^= B1; \ - B1 ^= B0; \ - B1 |= B2; \ - B0 ^= B3; \ - B1 ^= B4; \ - B0 ^= B1; \ - B4 = B0; \ - B0 = B2; \ - B2 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD5(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 &= B3; \ - B2 ^= B1; \ - B1 |= B3; \ - B1 &= B0; \ - B4 ^= B2; \ - B4 ^= B1; \ - B1 &= B2; \ - B0 = ~B0; \ - B3 ^= B4; \ - B1 ^= B3; \ - B3 &= B0; \ - B3 ^= B2; \ - B0 ^= B1; \ - B2 &= B0; \ - B3 ^= B0; \ - B2 ^= B4; \ - B2 |= B3; \ - B3 ^= B0; \ - B2 ^= B1; \ - B1 = B3; \ - B3 = B4; \ - } while(0); - -#define SBoxD6(B0, B1, B2, B3) \ - do { \ - B1 = ~B1; \ - SIMD_32 B4 = B3; \ - B2 ^= B1; \ - B3 |= B0; \ - B3 ^= B2; \ - B2 |= B1; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 ^= B4; \ - B4 |= B0; \ - B4 ^= B1; \ - B1 &= B2; \ - B1 ^= B3; \ - B4 ^= B2; \ - B3 &= B4; \ - B4 ^= B1; \ - B3 ^= B4; \ - B4 = ~B4; \ - B3 ^= B0; \ - B0 = B1; \ - B1 = B4; \ - B4 = B3; \ - B3 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD7(B0, B1, B2, B3) \ - do { \ - B0 ^= B2; \ - SIMD_32 B4 = B2; \ - B2 &= B0; \ - B4 ^= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B2 ^= B3; \ - B4 |= B0; \ - B0 ^= B2; \ - B3 ^= B4; \ - B4 ^= B1; \ - B1 &= B3; \ - B1 ^= B0; \ - B0 ^= B3; \ - B0 |= B2; \ - B3 ^= B1; \ - B4 ^= B0; \ - B0 = B1; \ - B1 = B2; \ - B2 = B4; \ - } while(0); - -#define SBoxD8(B0, B1, B2, B3) \ - do { \ - SIMD_32 B4 = B2; \ - B2 ^= B0; \ - B0 &= B3; \ - B4 |= B3; \ - B2 = ~B2; \ - B3 ^= B1; \ - B1 |= B0; \ - B0 ^= B2; \ - B2 &= B4; \ - B3 &= B4; \ - B1 ^= B2; \ - B2 ^= B0; \ - B0 |= B2; \ - B4 ^= B1; \ - B0 ^= B3; \ - B3 ^= B4; \ - B4 |= B0; \ - B3 ^= B2; \ - B4 ^= B2; \ - B2 = B1; \ - B1 = B0; \ - B0 = B3; \ - B3 = B4; \ - } while(0); - -#endif diff --git a/src/block/serpent_ia32/info.txt b/src/block/serpent_x86_32/info.txt index 3a1dd5919..b9c993546 100644 --- a/src/block/serpent_ia32/info.txt +++ b/src/block/serpent_x86_32/info.txt @@ -1,12 +1,12 @@ -define SERPENT_IA32 +define SERPENT_X86_32 load_on asm_ok <arch> -ia32 +x86_32 </arch> <requires> -asm_ia32 +asm_x86_32 serpent </requires> diff --git a/src/block/serpent_ia32/serp_ia32.cpp b/src/block/serpent_x86_32/serp_x86_32.cpp index d2f8adb62..4cefe1d65 100644 --- a/src/block/serpent_ia32/serp_ia32.cpp +++ b/src/block/serpent_x86_32/serp_x86_32.cpp @@ -1,11 +1,11 @@ /* -* IA-32 Serpent +* Serpent in x86-32 * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/serp_ia32.h> +#include <botan/serp_x86_32.h> #include <botan/loadstor.h> namespace Botan { @@ -18,7 +18,7 @@ extern "C" { * @param out the output block * @param ks the key schedule */ -void botan_serpent_ia32_encrypt(const byte in[16], +void botan_serpent_x86_32_encrypt(const byte in[16], byte out[16], const u32bit ks[132]); @@ -28,7 +28,7 @@ void botan_serpent_ia32_encrypt(const byte in[16], * @param out the output block * @param ks the key schedule */ -void botan_serpent_ia32_decrypt(const byte in[16], +void botan_serpent_x86_32_decrypt(const byte in[16], byte out[16], const u32bit ks[132]); @@ -37,18 +37,18 @@ void botan_serpent_ia32_decrypt(const byte in[16], * @param ks holds the initial working key (padded), and is set to the final key schedule */ -void botan_serpent_ia32_key_schedule(u32bit ks[140]); +void botan_serpent_x86_32_key_schedule(u32bit ks[140]); } /* * Serpent Encryption */ -void Serpent_IA32::encrypt_n(const byte in[], byte out[], size_t blocks) const +void Serpent_X86_32::encrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { - botan_serpent_ia32_encrypt(in, out, this->get_round_keys()); + botan_serpent_x86_32_encrypt(in, out, this->get_round_keys()); in += BLOCK_SIZE; out += BLOCK_SIZE; } @@ -57,11 +57,11 @@ void Serpent_IA32::encrypt_n(const byte in[], byte out[], size_t blocks) const /* * Serpent Decryption */ -void Serpent_IA32::decrypt_n(const byte in[], byte out[], size_t blocks) const +void Serpent_X86_32::decrypt_n(const byte in[], byte out[], size_t blocks) const { for(size_t i = 0; i != blocks; ++i) { - botan_serpent_ia32_decrypt(in, out, this->get_round_keys()); + botan_serpent_x86_32_decrypt(in, out, this->get_round_keys()); in += BLOCK_SIZE; out += BLOCK_SIZE; } @@ -70,14 +70,14 @@ void Serpent_IA32::decrypt_n(const byte in[], byte out[], size_t blocks) const /* * Serpent Key Schedule */ -void Serpent_IA32::key_schedule(const byte key[], size_t length) +void Serpent_X86_32::key_schedule(const byte key[], size_t length) { SecureVector<u32bit> W(140); for(size_t i = 0; i != length / 4; ++i) W[i] = load_le<u32bit>(key, i); W[length / 4] |= u32bit(1) << ((length%4)*8); - botan_serpent_ia32_key_schedule(W); + botan_serpent_x86_32_key_schedule(W); this->set_round_keys(W + 8); } diff --git a/src/block/serpent_ia32/serp_ia32.h b/src/block/serpent_x86_32/serp_x86_32.h index d7b5bedc7..f6c4d564a 100644 --- a/src/block/serpent_ia32/serp_ia32.h +++ b/src/block/serpent_x86_32/serp_x86_32.h @@ -1,27 +1,27 @@ /* -* Serpent (IA-32) +* Serpent in x86-32 asm * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_SERPENT_IA32_H__ -#define BOTAN_SERPENT_IA32_H__ +#ifndef BOTAN_SERPENT_X86_32_H__ +#define BOTAN_SERPENT_X86_32_H__ #include <botan/serpent.h> namespace Botan { /** -* Serpent implementation in x86 assembly +* Serpent implementation in x86-32 assembly */ -class BOTAN_DLL Serpent_IA32 : public Serpent +class BOTAN_DLL Serpent_X86_32 : public Serpent { public: void encrypt_n(const byte in[], byte out[], size_t blocks) const; void decrypt_n(const byte in[], byte out[], size_t blocks) const; - BlockCipher* clone() const { return new Serpent_IA32; } + BlockCipher* clone() const { return new Serpent_X86_32; } private: void key_schedule(const byte[], size_t); }; diff --git a/src/block/serpent_ia32/serp_ia32_imp.S b/src/block/serpent_x86_32/serp_x86_32_imp.S index 768192061..e2549a099 100644 --- a/src/block/serpent_ia32/serp_ia32_imp.S +++ b/src/block/serpent_x86_32/serp_x86_32_imp.S @@ -1,13 +1,13 @@ /* -* Serpent in IA-32 assembler +* Serpent in x86-32 assembler * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/internal/asm_macr_ia32.h> +#include <botan/internal/asm_x86_32.h> -START_LISTING(serp_ia32.S) +START_LISTING(serp_x86_32.S) #define SBOX_E1(A, B, C, D, T) \ XOR(D, A) ; \ @@ -441,7 +441,7 @@ START_LISTING(serp_ia32.S) /* * Serpent Encryption */ -START_FUNCTION(botan_serpent_ia32_encrypt) +START_FUNCTION(botan_serpent_x86_32_encrypt) SPILL_REGS() #define PUSHED 4 @@ -507,12 +507,12 @@ START_FUNCTION(botan_serpent_ia32_encrypt) RESTORE_REGS() #undef PUSHED -END_FUNCTION(botan_serpent_ia32_encrypt) +END_FUNCTION(botan_serpent_x86_32_encrypt) /* * Serpent Decryption */ -START_FUNCTION(botan_serpent_ia32_decrypt) +START_FUNCTION(botan_serpent_x86_32_decrypt) SPILL_REGS() #define PUSHED 4 @@ -578,12 +578,12 @@ START_FUNCTION(botan_serpent_ia32_decrypt) RESTORE_REGS() #undef PUSHED -END_FUNCTION(botan_serpent_ia32_decrypt) +END_FUNCTION(botan_serpent_x86_32_decrypt) /* * Serpent Key Schedule */ -START_FUNCTION(botan_serpent_ia32_key_schedule) +START_FUNCTION(botan_serpent_x86_32_key_schedule) SPILL_REGS() #define PUSHED 4 @@ -591,7 +591,7 @@ START_FUNCTION(botan_serpent_ia32_key_schedule) ASSIGN(ESI, IMM(8)) ADD_IMM(EDI, 32) -START_LOOP(.EXPANSION) +START_LOOP(.L_SERP_EXPANSION) ASSIGN(EAX, ARRAY4(EDI, -1)) ASSIGN(EBX, ARRAY4(EDI, -3)) ASSIGN(ECX, ARRAY4(EDI, -5)) @@ -611,7 +611,7 @@ START_LOOP(.EXPANSION) ADD_IMM(ESI, 1) ADD_IMM(EDI, 4) -LOOP_UNTIL_EQ(ESI, 140, .EXPANSION) +LOOP_UNTIL_EQ(ESI, 140, .L_SERP_EXPANSION) ASSIGN(EDI, ARG(1)) /* round keys */ @@ -666,4 +666,4 @@ LOOP_UNTIL_EQ(ESI, 140, .EXPANSION) RESTORE_REGS() #undef PUSHED -END_FUNCTION(botan_serpent_ia32_key_schedule) +END_FUNCTION(botan_serpent_x86_32_key_schedule) diff --git a/src/block/square/square.cpp b/src/block/square/square.cpp index b1517b990..cd1865582 100644 --- a/src/block/square/square.cpp +++ b/src/block/square/square.cpp @@ -2,6 +2,8 @@ * Square * (C) 1999-2007 Jack Lloyd * +* Based on the public domain reference implemenation +* * Distributed under the terms of the Botan license */ diff --git a/src/block/twofish/twofish.cpp b/src/block/twofish/twofish.cpp index 41bc7ca1c..c0735e202 100644 --- a/src/block/twofish/twofish.cpp +++ b/src/block/twofish/twofish.cpp @@ -2,6 +2,9 @@ * Twofish * (C) 1999-2007 Jack Lloyd * +* The key schedule implemenation is based on a public domain +* implementation by Matthew Skala +* * Distributed under the terms of the Botan license */ diff --git a/src/block/xtea_simd/info.txt b/src/block/xtea_simd/info.txt index 5a8445b35..c16bfa2fa 100644 --- a/src/block/xtea_simd/info.txt +++ b/src/block/xtea_simd/info.txt @@ -2,6 +2,6 @@ define XTEA_SIMD <requires> xtea -simd_32 +simd simd_engine </requires> diff --git a/src/build-data/arch/arm.txt b/src/build-data/arch/arm.txt index 77f15b1d9..b822fe130 100644 --- a/src/build-data/arch/arm.txt +++ b/src/build-data/arch/arm.txt @@ -1,25 +1,43 @@ + +endian little +family arm + +<aliases> +armel # For Debian +armhf # For Debian +</aliases> + <submodels> -arm2 -arm3 -arm6 -arm7 -arm8 -arm9 -strongarm -strongarm110 -strongarm1100 -xscale -cortex-a8 -cortex-a9 +armv2 +armv2a +armv3 +armv3m +armv4 +armv5 +armv5e +armv5te +armv6 +armv6j +armv6t2 +armv6z +armv6zk +armv6-m +armv7 +armv7-a +armv7-r +armv7-m +iwmmxt +iwmmxt2 +ep9312 </submodels> <submodel_aliases> -sa110 -> strongarm110 -sa1100 -> strongarm1100 -strongarm1110 -> strongarm1100 -armv5tel -> xscale +strongarm -> armv4 +xscale -> armv5te +cortex-a8 -> armv7-a +cortex-a9 -> armv7-a </submodel_aliases> <isa_extn> -neon:cortex-a8,cortex-a9 +neon:armv7-a </isa_extn> diff --git a/src/build-data/arch/hitachi-sh.txt b/src/build-data/arch/hitachi-sh.txt deleted file mode 100644 index bab84b48f..000000000 --- a/src/build-data/arch/hitachi-sh.txt +++ /dev/null @@ -1,7 +0,0 @@ -<submodels> -hitachi-sh1 -hitachi-sh2 -hitachi-sh3 -hitachi-sh3e -hitachi-sh4 -</submodels> diff --git a/src/build-data/arch/ppc.txt b/src/build-data/arch/ppc32.txt index dc3ea7829..e33c8ff24 100644 --- a/src/build-data/arch/ppc.txt +++ b/src/build-data/arch/ppc32.txt @@ -5,13 +5,9 @@ family ppc <aliases> powerpc +ppc </aliases> -<submodel_aliases> -g3 -> ppc740 -g4 -> ppc7450 -</submodel_aliases> - <submodels> ppc601 ppc603 @@ -20,8 +16,15 @@ ppc740 ppc750 ppc7400 ppc7450 +e500v2 </submodels> +<submodel_aliases> +g3 -> ppc740 +g4 -> ppc7450 +powerpcspe -> e500v2 # for Debian +</submodel_aliases> + <isa_extn> altivec:ppc7400,ppc7450 </isa_extn> diff --git a/src/build-data/arch/ppc64.txt b/src/build-data/arch/ppc64.txt index 7a2e6b6b3..954d9181e 100644 --- a/src/build-data/arch/ppc64.txt +++ b/src/build-data/arch/ppc64.txt @@ -11,7 +11,6 @@ g5 -> ppc970 </submodel_aliases> <submodels> -rs64a ppc970 power3 power4 diff --git a/src/build-data/arch/sparc32.txt b/src/build-data/arch/sparc32.txt index fc015e520..69f3479aa 100644 --- a/src/build-data/arch/sparc32.txt +++ b/src/build-data/arch/sparc32.txt @@ -26,4 +26,6 @@ sparcv9 -> sparc32-v9 sparc-v7 -> sparc32-v7 sparc-v8 -> sparc32-v8 sparc-v9 -> sparc32-v9 + +sun4u -> sparc32-v9 </submodel_aliases> diff --git a/src/build-data/arch/sparc64.txt b/src/build-data/arch/sparc64.txt index 7344fa390..3a6acd6c3 100644 --- a/src/build-data/arch/sparc64.txt +++ b/src/build-data/arch/sparc64.txt @@ -1,13 +1,11 @@ family sparc -<aliases> -sun4u -</aliases> - <submodels> ultrasparc ultrasparc3 +niagra +niagra2 </submodels> <submodel_aliases> diff --git a/src/build-data/arch/superh.txt b/src/build-data/arch/superh.txt new file mode 100644 index 000000000..c7dc09861 --- /dev/null +++ b/src/build-data/arch/superh.txt @@ -0,0 +1,5 @@ +<submodels> +sh2 +sh3 +sh4 +</submodels> diff --git a/src/build-data/arch/ia32.txt b/src/build-data/arch/x86_32.txt index c2d4d1769..482a53057 100644 --- a/src/build-data/arch/ia32.txt +++ b/src/build-data/arch/x86_32.txt @@ -4,10 +4,13 @@ unaligned ok family x86 <aliases> +ia32 x86 ix86 80x86 i86pc # for Solaris +x86pc # for QNX +bepc # for Haiku </aliases> <submodels> @@ -22,7 +25,7 @@ pentium-m prescott k6 athlon -atom +atom32 </submodels> <submodel_aliases> @@ -59,7 +62,7 @@ intelcput2700 -> prescott </submodel_aliases> <isa_extn> -sse2:pentium4,prescott,pentium-m,atom -ssse3:atom -movbe:atom +sse2:pentium4,prescott,pentium-m,atom32 +ssse3:atom32 +movbe:atom32 </isa_extn> diff --git a/src/build-data/arch/amd64.txt b/src/build-data/arch/x86_64.txt index b3b9879d2..97b84fbde 100644 --- a/src/build-data/arch/amd64.txt +++ b/src/build-data/arch/x86_64.txt @@ -4,8 +4,8 @@ unaligned ok family x86 <aliases> +amd64 x86-64 -x86_64 # for RPM em64t x64 </aliases> @@ -17,6 +17,7 @@ nocona core2 nehalem westmere +atom </submodels> <submodel_aliases> @@ -36,6 +37,6 @@ corei7cpu860 -> nehalem <isa_extn> sse2:all -ssse3:core2,nehalem,westmere +ssse3:core2,nehalem,westmere,atom aes-ni:westmere </isa_extn> diff --git a/src/build-data/botan-config.in b/src/build-data/botan-config.in index f3fa3db94..6780c12b8 100644 --- a/src/build-data/botan-config.in +++ b/src/build-data/botan-config.in @@ -2,7 +2,7 @@ # For normal builds: guess_prefix=`dirname \`dirname $0\`` -includedir=%{includedir} +includedir=%{includedir}/botan-%{version_major}.%{version_minor} libdir=%{libdir} # For workspace builds: @@ -54,9 +54,9 @@ while test $# -gt 0; do --libs) if [ $prefix != "/usr" -a $prefix != "/usr/local" ] then - echo -L$prefix/$libdir -lbotan %{link_to} + echo -L$prefix/$libdir -lbotan-%{version_major}.%{version_minor} %{link_to} else - echo -lbotan %{link_to} + echo -lbotan-%{version_major}.%{version_minor} %{link_to} fi ;; *) diff --git a/src/build-data/botan.doxy.in b/src/build-data/botan.doxy.in index 2f76a756b..52021c01f 100644 --- a/src/build-data/botan.doxy.in +++ b/src/build-data/botan.doxy.in @@ -1,12 +1,9 @@ # Doxyfile 1.5.4 -#--------------------------------------------------------------------------- -# Project related configuration options -#--------------------------------------------------------------------------- -DOXYFILE_ENCODING = UTF-8 PROJECT_NAME = Botan PROJECT_NUMBER = %{version} -OUTPUT_DIRECTORY = doc/doxygen +OUTPUT_DIRECTORY = %{doc_output_dir}/doxygen +DOXYFILE_ENCODING = UTF-8 CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English BRIEF_MEMBER_DESC = YES @@ -33,6 +30,7 @@ SIP_SUPPORT = NO DISTRIBUTE_GROUP_DOC = NO SUBGROUPING = YES TYPEDEF_HIDES_STRUCT = NO + #--------------------------------------------------------------------------- # Build related configuration options #--------------------------------------------------------------------------- @@ -63,6 +61,7 @@ MAX_INITIALIZER_LINES = 30 SHOW_USED_FILES = YES SHOW_DIRECTORIES = NO FILE_VERSION_FILTER = + #--------------------------------------------------------------------------- # configuration options related to warning and progress messages #--------------------------------------------------------------------------- @@ -73,6 +72,7 @@ WARN_IF_DOC_ERROR = YES WARN_NO_PARAMDOC = NO WARN_FORMAT = "$file:$line: $text" WARN_LOGFILE = + #--------------------------------------------------------------------------- # configuration options related to the input files #--------------------------------------------------------------------------- @@ -112,7 +112,7 @@ IGNORE_PREFIX = # configuration options related to the HTML output #--------------------------------------------------------------------------- GENERATE_HTML = YES -HTML_OUTPUT = html +HTML_OUTPUT = . HTML_FILE_EXTENSION = .html HTML_HEADER = HTML_FOOTER = @@ -129,56 +129,7 @@ DISABLE_INDEX = NO ENUM_VALUES_PER_LINE = 4 GENERATE_TREEVIEW = NO TREEVIEW_WIDTH = 250 -#--------------------------------------------------------------------------- -# configuration options related to the LaTeX output -#--------------------------------------------------------------------------- -GENERATE_LATEX = NO -LATEX_OUTPUT = latex -LATEX_CMD_NAME = latex -MAKEINDEX_CMD_NAME = makeindex -COMPACT_LATEX = NO -PAPER_TYPE = a4wide -EXTRA_PACKAGES = -LATEX_HEADER = -PDF_HYPERLINKS = NO -USE_PDFLATEX = NO -LATEX_BATCHMODE = NO -LATEX_HIDE_INDICES = NO -#--------------------------------------------------------------------------- -# configuration options related to the RTF output -#--------------------------------------------------------------------------- -GENERATE_RTF = NO -RTF_OUTPUT = rtf -COMPACT_RTF = NO -RTF_HYPERLINKS = NO -RTF_STYLESHEET_FILE = -RTF_EXTENSIONS_FILE = -#--------------------------------------------------------------------------- -# configuration options related to the man page output -#--------------------------------------------------------------------------- -GENERATE_MAN = NO -MAN_OUTPUT = man -MAN_EXTENSION = .3 -MAN_LINKS = NO -#--------------------------------------------------------------------------- -# configuration options related to the XML output -#--------------------------------------------------------------------------- -GENERATE_XML = NO -XML_OUTPUT = xml -XML_SCHEMA = -XML_DTD = -XML_PROGRAMLISTING = YES -#--------------------------------------------------------------------------- -# configuration options for the AutoGen Definitions output -#--------------------------------------------------------------------------- -GENERATE_AUTOGEN_DEF = NO -#--------------------------------------------------------------------------- -# configuration options related to the Perl module output -#--------------------------------------------------------------------------- -GENERATE_PERLMOD = NO -PERLMOD_LATEX = NO -PERLMOD_PRETTY = YES -PERLMOD_MAKEVAR_PREFIX = + #--------------------------------------------------------------------------- # Configuration options related to the preprocessor #--------------------------------------------------------------------------- @@ -191,6 +142,7 @@ INCLUDE_FILE_PATTERNS = PREDEFINED = EXPAND_AS_DEFINED = SKIP_FUNCTION_MACROS = YES + #--------------------------------------------------------------------------- # Configuration::additions related to external references #--------------------------------------------------------------------------- @@ -199,6 +151,7 @@ GENERATE_TAGFILE = ALLEXTERNALS = NO EXTERNAL_GROUPS = YES PERL_PATH = /usr/bin/perl + #--------------------------------------------------------------------------- # Configuration options related to the dot tool #--------------------------------------------------------------------------- @@ -226,6 +179,7 @@ DOT_TRANSPARENT = YES DOT_MULTI_TARGETS = NO GENERATE_LEGEND = YES DOT_CLEANUP = YES + #--------------------------------------------------------------------------- # Configuration::additions related to the search engine #--------------------------------------------------------------------------- diff --git a/src/build-data/botan.pc.in b/src/build-data/botan.pc.in index 70ed65d70..301f84600 100644 --- a/src/build-data/botan.pc.in +++ b/src/build-data/botan.pc.in @@ -1,12 +1,12 @@ prefix=%{prefix} exec_prefix=${prefix} libdir=${prefix}/%{libdir} -includedir=${prefix}/include +includedir=${prefix}/include/botan-%{version_major}.%{version_minor} Name: Botan Description: Multi-platform C++ crypto library Version: %{version} -Libs: -L${libdir} -lbotan +Libs: -L${libdir} -lbotan-%{version_major}.%{version_minor} Libs.private: %{link_to} Cflags: -I${includedir} diff --git a/src/build-data/buildh.in b/src/build-data/buildh.in index 2682d2ad9..733646524 100644 --- a/src/build-data/buildh.in +++ b/src/build-data/buildh.in @@ -20,7 +20,7 @@ #define BOTAN_DISTRIBUTION_INFO "%{distribution_info}" #ifndef BOTAN_DLL - #define BOTAN_DLL %{dll_import_flags} + #define BOTAN_DLL %{visibility_attribute} #endif /* Chunk sizes */ @@ -35,7 +35,7 @@ /* PK key consistency checking toggles */ #define BOTAN_PUBLIC_KEY_STRONG_CHECKS_ON_LOAD 1 -#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 1 +#define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_LOAD 0 #define BOTAN_PRIVATE_KEY_STRONG_CHECKS_ON_GENERATE 1 /* Should we use GCC-style inline assembler? */ diff --git a/src/build-data/cc/bcc.txt b/src/build-data/cc/bcc.txt index 93306dde1..f2ea46ef2 100644 --- a/src/build-data/cc/bcc.txt +++ b/src/build-data/cc/bcc.txt @@ -15,7 +15,6 @@ lang_flags "" warning_flags "" shared_flags "" -dll_import_flags "" ar_command lib diff --git a/src/build-data/cc/clang.txt b/src/build-data/cc/clang.txt index 14c51349c..f4db26ee8 100644 --- a/src/build-data/cc/clang.txt +++ b/src/build-data/cc/clang.txt @@ -17,11 +17,12 @@ makefile_style unix lib_opt_flags "-O2" check_opt_flags "-O2" -shared_flags "-fPIC -fvisibility=hidden" +shared_flags "-fPIC" debug_flags -g no_debug_flags "-finline-functions" -dll_import_flags '__attribute__((visibility("default")))' +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' <so_link_flags> # The default works for GNU ld and several other Unix linkers @@ -29,12 +30,12 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" </so_link_flags> <mach_opt> -amd64 -> "-march=SUBMODEL" +x86_64 -> "-march=SUBMODEL" nehalem -> "-march=core2 -mssse3 -msse4.1" </mach_opt> <mach_abi_linking> -amd64 -> "-m64" +x86_64 -> "-m64" mips64 -> "-mabi=64" s390 -> "-m31" s390x -> "-m64" diff --git a/src/build-data/cc/ekopath.txt b/src/build-data/cc/ekopath.txt index ac514261e..c6e8b6550 100644 --- a/src/build-data/cc/ekopath.txt +++ b/src/build-data/cc/ekopath.txt @@ -28,10 +28,9 @@ default -> "$(CXX) -shared -fPIC -Wl,-soname,$(SONAME)" athlon -> "-mcpu=athlon" pentium4 -> "-mcpu=pentium4" -opteron -> "-mcpu=opteron" -em64t -> "-mcpu=em64t" +k8 -> "-mcpu=opteron" core2 -> "-mcpu=core" -ia32 -> "-mcpu=anyx86" -amd64 -> "-mcpu=athlon64" +x86_32 -> "-mcpu=anyx86" +x86_64 -> "-mcpu=athlon64" </mach_opt> diff --git a/src/build-data/cc/gcc.txt b/src/build-data/cc/gcc.txt index 2f71c7a18..84e923764 100644 --- a/src/build-data/cc/gcc.txt +++ b/src/build-data/cc/gcc.txt @@ -1,6 +1,6 @@ macro_name GCC -binary_name g++-4.5.2 +binary_name g++-4.6.0 compile_option "-c " output_to_option "-o " @@ -11,15 +11,16 @@ add_lib_option -l lang_flags "-D_REENTRANT -std=c++0x" warning_flags "-W -Wall" -maintainer_warning_flags "-Werror -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual" +maintainer_warning_flags "-Werror -Wall -Wextra -Wstrict-aliasing -Wstrict-overflow=5 -Wcast-align -Wmissing-declarations -Wpointer-arith -Wcast-qual -Wold-style-cast" lib_opt_flags "-O3" check_opt_flags "-O2" -shared_flags "-fPIC -fvisibility=hidden" +shared_flags "-fPIC" debug_flags -g no_debug_flags "-finline-functions" -dll_import_flags '__attribute__((visibility("default")))' +visibility_build_flags "-fvisibility=hidden" +visibility_attribute '__attribute__((visibility("default")))' makefile_style unix @@ -33,53 +34,57 @@ aix -> "$(CXX) -shared -fPIC" darwin -> "$(CXX) -dynamiclib -fPIC -install_name $(LIBDIR)/$(SONAME)" hpux -> "$(CXX) -shared -fPIC -Wl,+h,$(SONAME)" solaris -> "$(CXX) -shared -fPIC -Wl,-h,$(SONAME)" -# Gotta use ld directly on BeOS, their GCC is busted -beos -> "ld -shared -h $(SONAME)" </so_link_flags> <mach_opt> -# Specializations first (they don't need to be, just clearer) -i386 -> "-mtune=i686 -momit-leaf-frame-pointer" -ppc601 -> "-mpowerpc -mcpu=601" +ppc601 -> "-mpowerpc -mcpu=601" +cellppu -> "-mcpu=cell" +e500v2 -> "-mcpu=8548" +atom32 -> "-march=atom -momit-leaf-frame-pointer" + +alpha-ev68 -> "-mcpu=ev67" +alpha-ev7 -> "-mcpu=ev67" + +# The patch from Debian bug 594159 has this, don't know why though... +sh4 -> "-m4 -mieee" + +# This is mostly for Debian's benefit +i486 -> "-mtune=generic -momit-leaf-frame-pointer" # 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" +nehalem -> "-march=core2 -msse4.1 -msse4.2 -momit-leaf-frame-pointer" +westmere -> "-march=core2 -maes -msse4.1 -msse4.2 -momit-leaf-frame-pointer" # Default family options (SUBMODEL is substitued with the real submodel) # Anything after the quotes is what should be *removed* from the submodel name # before it's put into SUBMODEL. alpha -> "-mcpu=SUBMODEL" alpha- -amd64 -> "-march=SUBMODEL -momit-leaf-frame-pointer" -arm -> "-mcpu=SUBMODEL" -ia32 -> "-march=SUBMODEL -momit-leaf-frame-pointer" -ia64 -> "-mtune=SUBMODEL" +arm -> "-march=SUBMODEL" +superh -> "-mSUBMODEL" sh hppa -> "-march=SUBMODEL" hppa +ia64 -> "-mtune=SUBMODEL" m68k -> "-mSUBMODEL" -hitachi-sh -> "-mSUBMODEL" hitachi-sh -sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus" sparc32- -sparc64 -> "-mcpu=v9 -mtune=SUBMODEL" mips32 -> "-mips1 -mcpu=SUBMODEL" mips32- mips64 -> "-mips3 -mcpu=SUBMODEL" mips64- -ppc -> "-mcpu=SUBMODEL" ppc +ppc32 -> "-mcpu=SUBMODEL" ppc ppc64 -> "-mcpu=SUBMODEL" ppc +sparc32 -> "-mcpu=SUBMODEL -Wa,-xarch=v8plus" sparc32- +sparc64 -> "-mcpu=v9 -mtune=SUBMODEL" +x86_32 -> "-march=SUBMODEL -momit-leaf-frame-pointer" +x86_64 -> "-march=SUBMODEL -momit-leaf-frame-pointer" </mach_opt> -# Note that the 'linking' bit means "use this for both compiling *and* linking" +# The 'linking' bit means "use this for both compiling *and* linking" <mach_abi_linking> all -> "-pthread" -amd64 -> "-m64" mips64 -> "-mabi=64" s390 -> "-m31" s390x -> "-m64" sparc32 -> "-m32 -mno-app-regs" sparc64 -> "-m64 -mno-app-regs" ppc64 -> "-m64" +x86_64 -> "-m64" netbsd -> "-D_NETBSD_SOURCE" qnx -> "-fexceptions -D_QNX_SOURCE" diff --git a/src/build-data/cc/icc.txt b/src/build-data/cc/icc.txt index 1aab4d111..e11875cb1 100644 --- a/src/build-data/cc/icc.txt +++ b/src/build-data/cc/icc.txt @@ -30,5 +30,5 @@ westmere -> "-march=core2" </mach_opt> <so_link_flags> -default -> "$(CXX) -fPIC -shared" +default -> "$(CXX) -fPIC -shared -Wl,-soname,$(SONAME)" </so_link_flags> diff --git a/src/build-data/cc/msvc.txt b/src/build-data/cc/msvc.txt index a854a576d..034ea7444 100644 --- a/src/build-data/cc/msvc.txt +++ b/src/build-data/cc/msvc.txt @@ -14,8 +14,8 @@ check_opt_flags "/O2 /D_CONSOLE" lang_flags "/EHs /GR" warning_flags "/W3 /wd4275 /wd4267" -shared_flags "/DBOTAN_DLL=__declspec(dllexport)" -dll_import_flags "__declspec(dllimport)" +visibility_build_flags "/DBOTAN_DLL=__declspec(dllexport)" +visibility_attribute "__declspec(dllimport)" ar_command lib diff --git a/src/build-data/cc/open64.txt b/src/build-data/cc/open64.txt index 34359ef63..52f35a7e8 100644 --- a/src/build-data/cc/open64.txt +++ b/src/build-data/cc/open64.txt @@ -23,5 +23,5 @@ default -> "$(CXX) -shared -Wl,-soname,$(SONAME)" </so_link_flags> <mach_abi_linking> -amd64 -> "-m64" +x86_64 -> "-m64" </mach_abi_linking> diff --git a/src/build-data/cc/pgi.txt b/src/build-data/cc/pgi.txt index 0e4f8baf2..985c534b9 100644 --- a/src/build-data/cc/pgi.txt +++ b/src/build-data/cc/pgi.txt @@ -24,5 +24,5 @@ i586 -> "-tp p5" i686 -> "-tp p6" athlon -> "-tp k7" pentium4 -> "-tp p6" -ia32 -> "-tp px" +x86_32 -> "-tp px" </mach_opt> diff --git a/src/build-data/cc/sunstudio.txt b/src/build-data/cc/sunstudio.txt index d0b25d144..43e5fcf8a 100644 --- a/src/build-data/cc/sunstudio.txt +++ b/src/build-data/cc/sunstudio.txt @@ -40,14 +40,18 @@ nehalem -> "-xtarget=nehalem" sparc32-v9 -> "-xchip=ultra -xarch=v8" +ultrasparc3 -> "-xchip=ultra3" +niagra1 -> "-xchip=ultraT1" +niagra2 -> "-xchip=ultraT2" + sparc32 -> "-xchip=ultra -xarch=SUBMODEL" sparc32- -sparc64 -> "-xchip=SUBMODEL" sparc64- +sparc64 -> "-xchip=generic" </mach_opt> <mach_abi_linking> # Needed on some Linux distros -#linux -> "-library=stlport4" +linux -> "-library=stlport4" sparc64 -> "-xarch=v9" -amd64 -> "-m64" +x86_64 -> "-m64" </mach_abi_linking> diff --git a/src/build-data/innosetup.in b/src/build-data/innosetup.in index 0a7eeb8f6..ed618e8fb 100644 --- a/src/build-data/innosetup.in +++ b/src/build-data/innosetup.in @@ -41,19 +41,19 @@ name: "docs"; Description: "Developer Documentation"; Types: devel ; DLL and license file is always included Source: "..\doc\license.txt"; DestDir: "{app}"; Components: dll; AfterInstall: ConvertLineEndings Source: "..\botan.dll"; DestDir: "{app}"; Components: dll -Source: "..\botan.dll.manifest"; DestDir: "{app}"; Components: dll +Source: "..\botan.dll.manifest"; DestDir: "{app}"; Components: dll; Flags: skipifsourcedoesntexist Source: "include\botan\*"; DestDir: "{app}\include\botan"; Components: includes; AfterInstall: ConvertLineEndings Source: "..\readme.txt"; DestDir: "{app}\doc"; Components: docs; AfterInstall: ConvertLineEndings -Source: "..\doc\log.txt"; DestDir: "{app}\doc"; Components: docs; AfterInstall: ConvertLineEndings +Source: "..\doc\*.txt"; DestDir: "{app}\doc"; Excludes: "license.txt"; Components: docs; AfterInstall: ConvertLineEndings Source: "..\doc\examples\*.cpp"; DestDir: "{app}\doc\examples"; Components: docs; AfterInstall: ConvertLineEndings Source: "..\botan.exp"; DestDir: "{app}"; Components: implib Source: "..\botan.lib"; DestDir: "{app}"; Components: implib -Source: "..\doc\api.pdf"; DestDir: "{app}\doc"; Components: docs; Flags: skipifsourcedoesntexist +Source: "..\doc\manual.pdf"; DestDir: "{app}\doc"; Components: docs; Flags: skipifsourcedoesntexist Source: "..\doc\tutorial.pdf"; DestDir: "{app}\doc"; Components: docs; Flags: skipifsourcedoesntexist [Code] diff --git a/src/build-data/makefile/nmake.in b/src/build-data/makefile/nmake.in index 9ca071da3..3e20d988a 100644 --- a/src/build-data/makefile/nmake.in +++ b/src/build-data/makefile/nmake.in @@ -17,6 +17,7 @@ DESTDIR = %{prefix} ### Aliases for Common Programs AR = %{ar_command} +COPY = copy CD = @cd ECHO = @echo INSTALL = %{install_cmd_exec} @@ -30,8 +31,6 @@ RMDIR = @rmdir ### File Lists CHECK = check -DOCS = %{doc_files} - HEADERS = %{include_files} LIBOBJS = %{lib_objs} @@ -67,6 +66,9 @@ $(BOTAN_LIB): $(LIBOBJS) !Endif ### Fake Targets +docs: +%{build_doc_commands} + clean: $(RM) %{build_dir}\lib\* %{build_dir}\checks\* $(RM) *.manifest *.exp *.dll diff --git a/src/build-data/makefile/unix.in b/src/build-data/makefile/unix.in index c525aa6bf..5290beda8 100644 --- a/src/build-data/makefile/unix.in +++ b/src/build-data/makefile/unix.in @@ -9,13 +9,14 @@ LINK_TO = %{link_to} # Version Numbers VERSION = %{version} +SERIES = %{version_major}.%{version_minor} # Installation Settings DESTDIR = %{prefix} BINDIR = $(DESTDIR)/bin LIBDIR = $(DESTDIR)/%{libdir} -HEADERDIR = $(DESTDIR)/%{includedir}/botan +HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION) PKGCONF_DIR = $(LIBDIR)/pkgconfig @@ -24,6 +25,8 @@ PKGCONFIG = %{botan_pkgconfig} # Aliases for Common Programs AR = %{ar_command} +COPY = cp +COPY_R = cp -r CD = @cd ECHO = @echo INSTALL_CMD_EXEC = %{install_cmd_exec} @@ -38,8 +41,6 @@ RM_R = @rm -rf # File Lists CHECK = %{check_prefix}check -DOCS = %{doc_files} - HEADERS = %{include_files} LIBOBJS = %{lib_objs} @@ -52,7 +53,7 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) LIBRARIES = $(STATIC_LIB) LIBNAME = %{lib_prefix}libbotan -STATIC_LIB = $(LIBNAME).a +STATIC_LIB = $(LIBNAME)-$(SERIES).a all: $(LIBRARIES) @@ -63,7 +64,7 @@ all: $(LIBRARIES) # Link Commands $(CHECK): $(LIBRARIES) $(CHECKOBJS) - $(CXX) $(CHECKOBJS) -L. libbotan.a $(LINK_TO) -o $(CHECK) + $(CXX) $(CHECKOBJS) $(STATIC_LIB) $(LINK_TO) -o $(CHECK) $(STATIC_LIB): $(LIBOBJS) $(RM) $(STATIC_LIB) @@ -71,12 +72,12 @@ $(STATIC_LIB): $(LIBOBJS) $(RANLIB) $(STATIC_LIB) # Fake Targets -.PHONY = doxygen clean distclean install static +.PHONY = docs clean distclean install static static: $(STATIC_LIB) -doxygen: - doxygen %{build_dir}/botan.doxy +docs: +%{build_doc_commands} clean: $(RM_R) %{build_dir}/lib/* %{build_dir}/checks/* @@ -84,22 +85,24 @@ clean: distclean: clean $(RM_R) %{build_dir} - $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) botan_all.cpp botan_all.h -install: $(LIBRARIES) +install: $(LIBRARIES) docs $(ECHO) "Installing Botan into $(DESTDIR)... " $(MKDIR_INSTALL) $(DOCDIR) + $(COPY_R) %{doc_output_dir}/* $(DOCDIR) + $(MKDIR_INSTALL) $(HEADERDIR) - $(MKDIR_INSTALL) $(LIBDIR) - $(MKDIR_INSTALL) $(BINDIR) - $(MKDIR_INSTALL) $(PKGCONF_DIR) - for i in $(DOCS); do \ - $(INSTALL_CMD_DATA) $$i $(DOCDIR); \ - done for i in $(HEADERS); do \ $(INSTALL_CMD_DATA) $$i $(HEADERDIR); \ done + + $(MKDIR_INSTALL) $(LIBDIR) $(INSTALL_CMD_DATA) $(STATIC_LIB) $(LIBDIR) + + $(MKDIR_INSTALL) $(BINDIR) $(INSTALL_CMD_EXEC) $(CONFIG_SCRIPT) $(BINDIR) + + $(MKDIR_INSTALL) $(PKGCONF_DIR) $(INSTALL_CMD_DATA) $(PKGCONFIG) $(PKGCONF_DIR) diff --git a/src/build-data/makefile/unix_shr.in b/src/build-data/makefile/unix_shr.in index aaedeeaf8..31060afbb 100644 --- a/src/build-data/makefile/unix_shr.in +++ b/src/build-data/makefile/unix_shr.in @@ -11,14 +11,14 @@ LINK_TO = %{link_to} # Version Numbers VERSION = %{version} -SO_VERSION = %{so_version} +SERIES = %{version_major}.%{version_minor} # Installation Settings DESTDIR = %{prefix} BINDIR = $(DESTDIR)/bin LIBDIR = $(DESTDIR)/%{libdir} -HEADERDIR = $(DESTDIR)/%{includedir}/botan +HEADERDIR = $(DESTDIR)/%{includedir}/botan-$(SERIES)/botan DOCDIR = $(DESTDIR)/%{docdir}/botan-$(VERSION) PKGCONF_DIR = $(LIBDIR)/pkgconfig @@ -27,6 +27,8 @@ PKGCONFIG = %{botan_pkgconfig} # Aliases for Common Programs AR = %{ar_command} +COPY = cp +COPY_R = cp -r CD = @cd ECHO = @echo INSTALL_CMD_EXEC = %{install_cmd_exec} @@ -41,8 +43,6 @@ RM_R = @rm -rf # File Lists CHECK = %{check_prefix}check -DOCS = %{doc_files} - HEADERS = %{include_files} LIBOBJS = %{lib_objs} @@ -55,12 +55,12 @@ CHECK_FLAGS = $(CHECK_OPT) $(LANG_FLAGS) $(WARN_FLAGS) LIBRARIES = $(STATIC_LIB) $(SHARED_LIB) LIBNAME = %{lib_prefix}libbotan -STATIC_LIB = $(LIBNAME).a +STATIC_LIB = $(LIBNAME)-$(SERIES).a -SHARED_LIB = $(LIBNAME)-$(SO_VERSION).%{so_suffix} -SONAME = $(LIBNAME)-$(SO_VERSION).%{so_suffix} +SONAME = $(LIBNAME)-$(SERIES).%{so_suffix}.%{so_abi_rev} +SHARED_LIB = $(SONAME).%{version_patch} -SYMLINK = libbotan.%{so_suffix} +SYMLINK = $(LIBNAME)-$(SERIES).%{so_suffix} all: $(LIBRARIES) @@ -71,7 +71,7 @@ all: $(LIBRARIES) # Link Commands $(CHECK): $(LIBRARIES) $(CHECKOBJS) - $(CXX) $(LDFLAGS) $(CHECKOBJS) -o $(CHECK) -L. -lbotan-%{so_version} $(LINK_TO) + $(CXX) $(LDFLAGS) $(CHECKOBJS) $(SHARED_LIB) $(LINK_TO) -o $(CHECK) $(STATIC_LIB): $(LIBOBJS) $(RM) $(STATIC_LIB) @@ -80,42 +80,46 @@ $(STATIC_LIB): $(LIBOBJS) $(SHARED_LIB): $(LIBOBJS) $(SO_LINK_CMD) $(LDFLAGS) $(LIBOBJS) -o $(SHARED_LIB) $(LINK_TO) + $(LN) $(SHARED_LIB) $(SONAME) $(LN) $(SHARED_LIB) $(SYMLINK) # Fake Targets -.PHONY = doxygen clean distclean install static shared +.PHONY = docs clean distclean install static shared static: $(STATIC_LIB) shared: $(SHARED_LIB) -doxygen: - doxygen %{build_dir}/botan.doxy +docs: +%{build_doc_commands} clean: $(RM_R) %{build_dir}/lib/* %{build_dir}/checks/* - $(RM) $(LIBRARIES) $(SYMLINK) $(CHECK) + $(RM) $(LIBRARIES) $(SYMLINK) $(SONAME) $(CHECK) distclean: clean $(RM_R) %{build_dir} - $(RM_R) %{doc_src_dir}/doxygen %{doc_src_dir}/botan.doxy $(RM) Makefile* $(CONFIG_SCRIPT) $(PKGCONFIG) + $(RM) botan_all.cpp botan_all.h -install: $(LIBRARIES) +install: $(LIBRARIES) docs $(ECHO) "Installing Botan into $(DESTDIR)... " $(MKDIR_INSTALL) $(DOCDIR) + $(COPY_R) %{doc_output_dir}/* $(DOCDIR) + $(MKDIR_INSTALL) $(HEADERDIR) - $(MKDIR_INSTALL) $(LIBDIR) - $(MKDIR_INSTALL) $(BINDIR) - $(MKDIR_INSTALL) $(PKGCONF_DIR) - for i in $(DOCS); do \ - $(INSTALL_CMD_DATA) $$i $(DOCDIR); \ - done for i in $(HEADERS); do \ $(INSTALL_CMD_DATA) $$i $(HEADERDIR); \ done + + $(MKDIR_INSTALL) $(LIBDIR) $(INSTALL_CMD_DATA) $(STATIC_LIB) $(LIBDIR) - $(INSTALL_CMD_EXEC) $(CONFIG_SCRIPT) $(BINDIR) $(INSTALL_CMD_EXEC) $(SHARED_LIB) $(LIBDIR) - $(INSTALL_CMD_DATA) $(PKGCONFIG) $(PKGCONF_DIR) $(CD) $(LIBDIR); $(LN) $(SHARED_LIB) $(SYMLINK) + $(CD) $(LIBDIR); $(LN) $(SHARED_LIB) $(SONAME) + + $(MKDIR_INSTALL) $(BINDIR) + $(INSTALL_CMD_EXEC) $(CONFIG_SCRIPT) $(BINDIR) + + $(MKDIR_INSTALL) $(PKGCONF_DIR) + $(INSTALL_CMD_DATA) $(PKGCONFIG) $(PKGCONF_DIR) diff --git a/src/build-data/os/beos.txt b/src/build-data/os/beos.txt deleted file mode 100644 index 4a16b6326..000000000 --- a/src/build-data/os/beos.txt +++ /dev/null @@ -1,14 +0,0 @@ -os_type beos - -install_root /boot/beos -header_dir ../develop/headers -lib_dir system/lib -doc_dir documentation - -<target_features> -gettimeofday -</target_features> - -<aliases> -haiku -</aliases> diff --git a/src/build-data/os/haiku.txt b/src/build-data/os/haiku.txt new file mode 100644 index 000000000..8e35e76eb --- /dev/null +++ b/src/build-data/os/haiku.txt @@ -0,0 +1,15 @@ +os_type unix + +install_root /boot +header_dir develop/headers +lib_dir system/lib +doc_dir system/documentation + +<target_features> +gettimeofday +gmtime_r +</target_features> + +<aliases> +beos +</aliases> diff --git a/src/build-data/os/mingw.txt b/src/build-data/os/mingw.txt index 08f85b4db..5daabac90 100644 --- a/src/build-data/os/mingw.txt +++ b/src/build-data/os/mingw.txt @@ -14,9 +14,6 @@ header_dir include lib_dir lib doc_dir share/doc -install_cmd_data "install -m 644" -install_cmd_exec "install -m 755" - <aliases> msys mingw32 diff --git a/src/build-data/os/qnx.txt b/src/build-data/os/qnx.txt index 369b720c4..4c0965764 100644 --- a/src/build-data/os/qnx.txt +++ b/src/build-data/os/qnx.txt @@ -1,5 +1,9 @@ os_type unix <target_features> +clock_gettime gettimeofday +posix_mlock +gmtime_r +dlopen </target_features> diff --git a/src/build-data/os/solaris.txt b/src/build-data/os/solaris.txt index 47e7bccbc..0ed785036 100644 --- a/src/build-data/os/solaris.txt +++ b/src/build-data/os/solaris.txt @@ -1,5 +1,8 @@ os_type unix +install_cmd_data '/usr/ucb/install -m 644' +install_cmd_exec '/usr/ucb/install -m 755' + <target_features> posix_mlock gettimeofday diff --git a/src/cert/cvc/cvc_self.cpp b/src/cert/cvc/cvc_self.cpp index 4b6c5af8c..1646adeef 100644 --- a/src/cert/cvc/cvc_self.cpp +++ b/src/cert/cvc/cvc_self.cpp @@ -41,7 +41,7 @@ MemoryVector<byte> eac_1_1_encoding(const EC_PublicKey* key, if(key->domain_format() == EC_DOMPAR_ENC_OID) throw Encoding_Error("CVC encoder: cannot encode parameters by OID"); - const EC_Domain_Params& domain = key->domain(); + const EC_Group& domain = key->domain(); // This is why we can't have nice things diff --git a/src/cert/cvc/info.txt b/src/cert/cvc/info.txt index d6281802b..3cf759188 100644 --- a/src/cert/cvc/info.txt +++ b/src/cert/cvc/info.txt @@ -1,5 +1,5 @@ define CARD_VERIFIABLE_CERTIFICATES -load_on auto +load_on request <header:public> cvc_ado.h diff --git a/src/cert/x509ca/x509_ca.cpp b/src/cert/x509ca/x509_ca.cpp index b97b106f8..37b4f44b4 100644 --- a/src/cert/x509ca/x509_ca.cpp +++ b/src/cert/x509ca/x509_ca.cpp @@ -94,7 +94,7 @@ X509_Certificate X509_CA::make_cert(PK_Signer* signer, const Extensions& extensions) { const size_t X509_CERT_VERSION = 3; - const size_t SERIAL_BITS = 256; + const size_t SERIAL_BITS = 128; BigInt serial_no(rng, SERIAL_BITS); diff --git a/src/cert/x509cert/x509_ext.cpp b/src/cert/x509cert/x509_ext.cpp index 462b29669..6e0befaf3 100644 --- a/src/cert/x509cert/x509_ext.cpp +++ b/src/cert/x509cert/x509_ext.cpp @@ -443,6 +443,9 @@ class Policy_Information : public ASN1_Object public: OID oid; + Policy_Information() {} + Policy_Information(const OID& oid) : oid(oid) {} + void encode_into(DER_Encoder& codec) const { codec.start_cons(SEQUENCE) @@ -466,18 +469,16 @@ class Policy_Information : public ASN1_Object */ MemoryVector<byte> Certificate_Policies::encode_inner() const { - // FIXME -#if 1 - throw Internal_Error("Certificate_Policies::encode_inner: Bugged"); -#else std::vector<Policy_Information> policies; + for(size_t i = 0; i != oids.size(); ++i) + policies.push_back(oids[i]); + return DER_Encoder() .start_cons(SEQUENCE) .encode_list(policies) .end_cons() .get_contents(); -#endif } /* @@ -491,6 +492,10 @@ void Certificate_Policies::decode_inner(const MemoryRegion<byte>& in) .start_cons(SEQUENCE) .decode_list(policies) .end_cons(); + + oids.clear(); + for(size_t i = 0; i != policies.size(); ++i) + oids.push_back(policies[i].oid); } /* diff --git a/src/cert/x509cert/x509cert.cpp b/src/cert/x509cert/x509cert.cpp index 40b61b47d..1d7e51d08 100644 --- a/src/cert/x509cert/x509cert.cpp +++ b/src/cert/x509cert/x509cert.cpp @@ -390,8 +390,12 @@ std::string X509_Certificate::to_string() const OIDS::lookup(this->signature_algorithm().oid) << "\n"; out << "Serial number: " << hex_encode(this->serial_number()) << "\n"; - out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n"; - out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n"; + + if(this->authority_key_id().size()) + out << "Authority keyid: " << hex_encode(this->authority_key_id()) << "\n"; + + if(this->subject_key_id().size()) + out << "Subject keyid: " << hex_encode(this->subject_key_id()) << "\n"; X509_PublicKey* pubkey = this->subject_public_key(); out << "Public Key:\n" << X509::PEM_encode(*pubkey); diff --git a/src/cms/cms_algo.cpp b/src/cms/cms_algo.cpp index 50384d85a..3c245cc6f 100644 --- a/src/cms/cms_algo.cpp +++ b/src/cms/cms_algo.cpp @@ -99,7 +99,7 @@ SecureVector<byte> CMS_Encoder::wrap_key(RandomNumberGenerator& rng, throw Encoding_Error("CMS: 128-bit KEKs must be used with " + cipher); SecureVector<byte> lcekpad; - lcekpad.push_back((byte)cek.length()); + lcekpad.push_back(static_cast<byte>(cek.length())); lcekpad += cek.bits_of(); while(lcekpad.size() % 8) lcekpad.push_back(rng.next_byte()); diff --git a/src/cms/cms_dec.cpp b/src/cms/cms_dec.cpp index c86e1d0ae..a9f4e69d9 100644 --- a/src/cms/cms_dec.cpp +++ b/src/cms/cms_dec.cpp @@ -86,7 +86,9 @@ std::string CMS_Decoder::get_data() const { if(layer_type() != DATA) throw Invalid_State("CMS: Cannot retrieve data from non-DATA layer"); - return std::string((const char*)&data[0], data.size()); + + return std::string(reinterpret_cast<const char*>(&data[0]), + data.size()); } /* diff --git a/src/cms/cms_enc.cpp b/src/cms/cms_enc.cpp index cd739ef08..1a45a6a46 100644 --- a/src/cms/cms_enc.cpp +++ b/src/cms/cms_enc.cpp @@ -30,7 +30,7 @@ void CMS_Encoder::set_data(const byte buf[], size_t length) */ void CMS_Encoder::set_data(const std::string& str) { - set_data((const byte*)str.c_str(), str.length()); + set_data(reinterpret_cast<const byte*>(str.c_str()), str.length()); } /* diff --git a/src/cms/info.txt b/src/cms/info.txt index dc2110ae5..34e2c089c 100644 --- a/src/cms/info.txt +++ b/src/cms/info.txt @@ -1,5 +1,7 @@ define CMS +load_on request + <requires> asn1 bigint diff --git a/src/codec/base64/base64.cpp b/src/codec/base64/base64.cpp index d6c5ec7c0..6a53a7a9a 100644 --- a/src/codec/base64/base64.cpp +++ b/src/codec/base64/base64.cpp @@ -97,5 +97,155 @@ std::string base64_encode(const MemoryRegion<byte>& input) return base64_encode(&input[0], input.size()); } +size_t base64_decode(byte output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws) + { + /* + * Base64 Decoder Lookup Table + * Warning: assumes ASCII encodings + */ + static const byte BASE64_TO_BIN[256] = { + 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x80, + 0x80, 0xFF, 0xFF, 0x80, 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, 0x3E, 0xFF, 0xFF, 0xFF, 0x3F, 0x34, 0x35, + 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0xFF, 0xFF, + 0xFF, 0x81, 0xFF, 0xFF, 0xFF, 0x00, 0x01, 0x02, 0x03, 0x04, + 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, + 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, + 0x19, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0x1A, 0x1B, 0x1C, + 0x1D, 0x1E, 0x1F, 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, + 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F, 0x30, + 0x31, 0x32, 0x33, 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; + byte decode_buf[4]; + size_t decode_buf_pos = 0; + size_t final_truncate = 0; + + clear_mem(output, input_length * 3 / 4); + + for(size_t i = 0; i != input_length; ++i) + { + const byte bin = BASE64_TO_BIN[static_cast<byte>(input[i])]; + + if(bin <= 0x3F) + { + decode_buf[decode_buf_pos] = bin; + decode_buf_pos += 1; + } + else if(!(bin == 0x81 || (bin == 0x80 && ignore_ws))) + { + std::string bad_char(1, input[i]); + if(bad_char == "\t") + bad_char = "\\t"; + else if(bad_char == "\n") + bad_char = "\\n"; + else if(bad_char == "\r") + bad_char = "\\r"; + + throw std::invalid_argument( + std::string("base64_decode: invalid base64 character '") + + bad_char + "'"); + } + + /* + * If we're at the end of the input, pad with 0s and truncate + */ + if(final_inputs && (i == input_length - 1)) + { + if(decode_buf_pos) + { + for(size_t i = decode_buf_pos; i != 4; ++i) + decode_buf[i] = 0; + final_truncate = (4 - decode_buf_pos); + decode_buf_pos = 4; + } + } + + if(decode_buf_pos == 4) + { + out_ptr[0] = (decode_buf[0] << 2) | (decode_buf[1] >> 4); + out_ptr[1] = (decode_buf[1] << 4) | (decode_buf[2] >> 2); + out_ptr[2] = (decode_buf[2] << 6) | decode_buf[3]; + + out_ptr += 3; + decode_buf_pos = 0; + input_consumed = i+1; + } + } + + while(input_consumed < input_length && + BASE64_TO_BIN[static_cast<byte>(input[input_consumed])] == 0x80) + { + ++input_consumed; + } + + size_t written = (out_ptr - output) - final_truncate; + + return written; + } + +size_t base64_decode(byte output[], + const char input[], + size_t input_length, + bool ignore_ws) + { + size_t consumed = 0; + size_t written = base64_decode(output, input, input_length, + consumed, true, ignore_ws); + + if(consumed != input_length) + throw std::invalid_argument("base64_decode: input did not have full bytes"); + + return written; + } + +size_t base64_decode(byte output[], + const std::string& input, + bool ignore_ws) + { + return base64_decode(output, &input[0], input.length(), ignore_ws); + } + +SecureVector<byte> base64_decode(const char input[], + size_t input_length, + bool ignore_ws) + { + SecureVector<byte> bin((round_up<size_t>(input_length, 4) * 3) / 4); + + size_t written = base64_decode(&bin[0], + input, + input_length, + ignore_ws); + + bin.resize(written); + return bin; + } + +SecureVector<byte> base64_decode(const std::string& input, + bool ignore_ws) + { + return base64_decode(&input[0], input.size(), ignore_ws); + } + } diff --git a/src/codec/base64/base64.h b/src/codec/base64/base64.h index 6daac73d8..23a2558bd 100644 --- a/src/codec/base64/base64.h +++ b/src/codec/base64/base64.h @@ -48,6 +48,76 @@ std::string BOTAN_DLL base64_encode(const byte input[], */ std::string BOTAN_DLL base64_encode(const MemoryRegion<byte>& input); +/** +* Perform base64 decoding +* @param output an array of at least input_length*3/4 bytes +* @param input some base64 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 final_inputs true iff this is the last input, in which case + padding is allowed +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const char input[], + size_t input_length, + size_t& input_consumed, + bool final_inputs, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least input_length*3/4 bytes +* @param input some base64 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 +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param output an array of at least input_length/3*4 bytes +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return number of bytes written to output +*/ +size_t BOTAN_DLL base64_decode(byte output[], + const std::string& input, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 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 base64 output +*/ +SecureVector<byte> BOTAN_DLL base64_decode(const char input[], + size_t input_length, + bool ignore_ws = true); + +/** +* Perform base64 decoding +* @param input some base64 input +* @param ignore_ws ignore whitespace on input; if false, throw an + exception if whitespace is encountered +* @return decoded base64 output +*/ +SecureVector<byte> BOTAN_DLL base64_decode(const std::string& input, + bool ignore_ws = true); + } #endif diff --git a/src/codec/hex/hex.cpp b/src/codec/hex/hex.cpp index 596e0e235..41ba1298d 100644 --- a/src/codec/hex/hex.cpp +++ b/src/codec/hex/hex.cpp @@ -37,9 +37,7 @@ void hex_encode(char output[], std::string hex_encode(const MemoryRegion<byte>& input, bool uppercase) { - return hex_encode(&input[0], - input.size(), - uppercase); + return hex_encode(&input[0], input.size(), uppercase); } std::string hex_encode(const byte input[], @@ -47,7 +45,10 @@ std::string hex_encode(const byte input[], bool uppercase) { std::string output(2 * input_length, 0); - hex_encode(&output[0], input, input_length, uppercase); + + if(input_length) + hex_encode(&output[0], input, input_length, uppercase); + return output; } @@ -101,7 +102,7 @@ size_t hex_decode(byte output[], for(size_t i = 0; i != input_length; ++i) { - const byte bin = HEX_TO_BIN[(byte)input[i]]; + const byte bin = HEX_TO_BIN[static_cast<byte>(input[i])]; if(bin >= 0x10) { diff --git a/src/constructs/fpe/fpe.cpp b/src/constructs/fpe_fe1/fpe_fe1.cpp index 1023b067c..91d328c17 100644 --- a/src/constructs/fpe/fpe.cpp +++ b/src/constructs/fpe_fe1/fpe_fe1.cpp @@ -8,7 +8,7 @@ * Distributed under the terms of the Botan license */ -#include <botan/fpe.h> +#include <botan/fpe_fe1.h> #include <botan/numthry.h> #include <botan/hmac.h> #include <botan/sha2_32.h> @@ -16,6 +16,8 @@ namespace Botan { +namespace FPE { + namespace { // Normally FPE is for SSNs, CC#s, etc, nothing too big @@ -105,10 +107,10 @@ FPE_Encryptor::FPE_Encryptor(const SymmetricKey& key, if(n_bin.size() > MAX_N_BYTES) throw std::runtime_error("N is too large for FPE encryption"); - mac->update_be((u32bit)n_bin.size()); + mac->update_be(static_cast<u32bit>(n_bin.size())); mac->update(&n_bin[0], n_bin.size()); - mac->update_be((u32bit)tweak.size()); + mac->update_be(static_cast<u32bit>(tweak.size())); mac->update(&tweak[0], tweak.size()); mac_n_t = mac->final(); @@ -119,9 +121,9 @@ BigInt FPE_Encryptor::operator()(size_t round_no, const BigInt& R) SecureVector<byte> r_bin = BigInt::encode(R); mac->update(mac_n_t); - mac->update_be((u32bit)round_no); + mac->update_be(static_cast<u32bit>(round_no)); - mac->update_be((u32bit)r_bin.size()); + mac->update_be(static_cast<u32bit>(r_bin.size())); mac->update(&r_bin[0], r_bin.size()); SecureVector<byte> X = mac->final(); @@ -133,7 +135,7 @@ BigInt FPE_Encryptor::operator()(size_t round_no, const BigInt& R) /* * Generic Z_n FPE encryption, FE1 scheme */ -BigInt fpe_encrypt(const BigInt& n, const BigInt& X0, +BigInt fe1_encrypt(const BigInt& n, const BigInt& X0, const SymmetricKey& key, const MemoryRegion<byte>& tweak) { @@ -161,7 +163,7 @@ BigInt fpe_encrypt(const BigInt& n, const BigInt& X0, /* * Generic Z_n FPE decryption, FD1 scheme */ -BigInt fpe_decrypt(const BigInt& n, const BigInt& X0, +BigInt fe1_decrypt(const BigInt& n, const BigInt& X0, const SymmetricKey& key, const MemoryRegion<byte>& tweak) { @@ -187,3 +189,5 @@ BigInt fpe_decrypt(const BigInt& n, const BigInt& X0, } } + +} diff --git a/src/constructs/fpe/fpe.h b/src/constructs/fpe_fe1/fpe_fe1.h index 7a4a7861a..da9a6bcb6 100644 --- a/src/constructs/fpe/fpe.h +++ b/src/constructs/fpe_fe1/fpe_fe1.h @@ -1,18 +1,20 @@ /* -* Format Preserving Encryption +* Format Preserving Encryption (FE1 scheme) * (C) 2009 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_FORMAT_PRESERVING_ENCRYPTION_H__ -#define BOTAN_FORMAT_PRESERVING_ENCRYPTION_H__ +#ifndef BOTAN_FPE_FE1_H__ +#define BOTAN_FPE_FE1_H__ #include <botan/bigint.h> #include <botan/symkey.h> namespace Botan { +namespace FPE { + /** * Encrypt X from and onto the group Z_n using key and tweak * @param n the modulus @@ -20,7 +22,7 @@ namespace Botan { * @param key a random key * @param tweak will modify the ciphertext (think of as an IV) */ -BigInt BOTAN_DLL fpe_encrypt(const BigInt& n, const BigInt& X, +BigInt BOTAN_DLL fe1_encrypt(const BigInt& n, const BigInt& X, const SymmetricKey& key, const MemoryRegion<byte>& tweak); @@ -31,10 +33,12 @@ BigInt BOTAN_DLL fpe_encrypt(const BigInt& n, const BigInt& X, * @param key is the key used for encryption * @param tweak the same tweak used for encryption */ -BigInt BOTAN_DLL fpe_decrypt(const BigInt& n, const BigInt& X, +BigInt BOTAN_DLL fe1_decrypt(const BigInt& n, const BigInt& X, const SymmetricKey& key, const MemoryRegion<byte>& tweak); } +} + #endif diff --git a/src/constructs/fpe/info.txt b/src/constructs/fpe_fe1/info.txt index 078eb2135..33b5a1c80 100644 --- a/src/constructs/fpe/info.txt +++ b/src/constructs/fpe_fe1/info.txt @@ -1,4 +1,4 @@ -define FORMAT_PRESERVING_ENCRYPTION +define FPE_FE1 <requires> hmac diff --git a/src/engine/aes_isa_eng/aes_isa_engine.cpp b/src/engine/aes_isa_eng/aes_isa_engine.cpp index 7f541d583..e56f6e9ca 100644 --- a/src/engine/aes_isa_eng/aes_isa_engine.cpp +++ b/src/engine/aes_isa_eng/aes_isa_engine.cpp @@ -8,8 +8,8 @@ #include <botan/internal/aes_isa_engine.h> #include <botan/cpuid.h> -#if defined(BOTAN_HAS_AES_INTEL) - #include <botan/aes_intel.h> +#if defined(BOTAN_HAS_AES_NI) + #include <botan/aes_ni.h> #endif namespace Botan { @@ -18,15 +18,15 @@ BlockCipher* AES_ISA_Engine::find_block_cipher(const SCAN_Name& request, Algorithm_Factory&) const { -#if defined(BOTAN_HAS_AES_INTEL) +#if defined(BOTAN_HAS_AES_NI) if(CPUID::has_aes_ni()) { if(request.algo_name() == "AES-128") - return new AES_128_Intel; + return new AES_128_NI; if(request.algo_name() == "AES-192") - return new AES_192_Intel; + return new AES_192_NI; if(request.algo_name() == "AES-256") - return new AES_256_Intel; + return new AES_256_NI; } #endif diff --git a/src/engine/asm_engine/asm_engine.cpp b/src/engine/asm_engine/asm_engine.cpp index 747e8c00f..6d475136f 100644 --- a/src/engine/asm_engine/asm_engine.cpp +++ b/src/engine/asm_engine/asm_engine.cpp @@ -7,24 +7,24 @@ #include <botan/internal/asm_engine.h> -#if defined(BOTAN_HAS_SERPENT_IA32) - #include <botan/serp_ia32.h> +#if defined(BOTAN_HAS_SERPENT_X86_32) + #include <botan/serp_x86_32.h> #endif -#if defined(BOTAN_HAS_MD4_IA32) - #include <botan/md4_ia32.h> +#if defined(BOTAN_HAS_MD4_X86_32) + #include <botan/md4_x86_32.h> #endif -#if defined(BOTAN_HAS_MD5_IA32) - #include <botan/md5_ia32.h> +#if defined(BOTAN_HAS_MD5_X86_32) + #include <botan/md5_x86_32.h> #endif -#if defined(BOTAN_HAS_SHA1_AMD64) - #include <botan/sha1_amd64.h> +#if defined(BOTAN_HAS_SHA1_X86_64) + #include <botan/sha1_x86_64.h> #endif -#if defined(BOTAN_HAS_SHA1_IA32) - #include <botan/sha1_ia32.h> +#if defined(BOTAN_HAS_SHA1_X86_32) + #include <botan/sha1_x86_32.h> #endif namespace Botan { @@ -35,8 +35,8 @@ Assembler_Engine::find_block_cipher(const SCAN_Name& request, { if(request.algo_name() == "Serpent") { -#if defined(BOTAN_HAS_SERPENT_IA32) - return new Serpent_IA32; +#if defined(BOTAN_HAS_SERPENT_X86_32) + return new Serpent_X86_32; #endif } @@ -47,24 +47,24 @@ HashFunction* Assembler_Engine::find_hash(const SCAN_Name& request, Algorithm_Factory&) const { -#if defined(BOTAN_HAS_MD4_IA32) +#if defined(BOTAN_HAS_MD4_X86_32) if(request.algo_name() == "MD4") - return new MD4_IA32; + return new MD4_X86_32; #endif -#if defined(BOTAN_HAS_MD5_IA32) +#if defined(BOTAN_HAS_MD5_X86_32) if(request.algo_name() == "MD5") - return new MD5_IA32; + return new MD5_X86_32; #endif if(request.algo_name() == "SHA-160") - { -#if defined(BOTAN_HAS_SHA1_AMD64) - return new SHA_160_AMD64; -#elif defined(BOTAN_HAS_SHA1_IA32) - return new SHA_160_IA32; + { +#if defined(BOTAN_HAS_SHA1_X86_64) + return new SHA_160_X86_64; +#elif defined(BOTAN_HAS_SHA1_X86_32) + return new SHA_160_X86_32; #endif - } + } return 0; } diff --git a/src/engine/asm_engine/asm_engine.h b/src/engine/asm_engine/asm_engine.h index e3e9a546c..bd82566d3 100644 --- a/src/engine/asm_engine/asm_engine.h +++ b/src/engine/asm_engine/asm_engine.h @@ -5,8 +5,8 @@ * Distributed under the terms of the Botan license */ -#ifndef BOTAN_IA32_ASM_ENGINE_H__ -#define BOTAN_IA32_ASM_ENGINE_H__ +#ifndef BOTAN_X86_32_ASM_ENGINE_H__ +#define BOTAN_X86_32_ASM_ENGINE_H__ #include <botan/engine.h> diff --git a/src/engine/simd_engine/info.txt b/src/engine/simd_engine/info.txt index cddb7524a..229b1daaf 100644 --- a/src/engine/simd_engine/info.txt +++ b/src/engine/simd_engine/info.txt @@ -9,3 +9,7 @@ simd_engine.cpp <header:internal> simd_engine.h </header:internal> + +<requires> +simd +</requires> diff --git a/src/entropy/beos_stats/es_beos.cpp b/src/entropy/beos_stats/es_beos.cpp index 2b4a7a24f..e514eb121 100644 --- a/src/entropy/beos_stats/es_beos.cpp +++ b/src/entropy/beos_stats/es_beos.cpp @@ -26,8 +26,6 @@ void BeOS_EntropySource::poll(Entropy_Accumulator& accum) get_key_info(&info_key); accum.add(info_key, 0); - accum.add(idle_time(), 0); - team_info info_team; int32 cookie_team = 0; diff --git a/src/entropy/beos_stats/info.txt b/src/entropy/beos_stats/info.txt index 088b926f9..c7ed9fe5a 100644 --- a/src/entropy/beos_stats/info.txt +++ b/src/entropy/beos_stats/info.txt @@ -9,9 +9,9 @@ es_beos.h </header:internal> <os> -beos +haiku </os> <libs> -beos -> root,be +haiku -> root,be </libs> diff --git a/src/entropy/dev_random/dev_random.cpp b/src/entropy/dev_random/dev_random.cpp index b15240aba..d14ae43ae 100644 --- a/src/entropy/dev_random/dev_random.cpp +++ b/src/entropy/dev_random/dev_random.cpp @@ -12,6 +12,7 @@ #include <sys/stat.h> #include <unistd.h> #include <fcntl.h> +#include <string.h> namespace Botan { diff --git a/src/entropy/dev_random/info.txt b/src/entropy/dev_random/info.txt index cabb47ea2..4c69a57f4 100644 --- a/src/entropy/dev_random/info.txt +++ b/src/entropy/dev_random/info.txt @@ -10,11 +10,11 @@ dev_random.h <os> aix -beos cygwin darwin -freebsd dragonfly +freebsd +haiku hpux hurd irix diff --git a/src/entropy/egd/es_egd.cpp b/src/entropy/egd/es_egd.cpp index d2ce2706b..b2b629930 100644 --- a/src/entropy/egd/es_egd.cpp +++ b/src/entropy/egd/es_egd.cpp @@ -89,7 +89,7 @@ size_t EGD_EntropySource::EGD_Socket::read(byte outbuf[], size_t length) throw std::runtime_error("Reading response length from EGD failed"); if(out_len > egd_read_command[1]) - throw std::runtime_error("Bogus length field recieved from EGD"); + throw std::runtime_error("Bogus length field received from EGD"); ssize_t count = ::read(m_fd, outbuf, out_len); diff --git a/src/entropy/hres_timer/hres_timer.cpp b/src/entropy/hres_timer/hres_timer.cpp index b0f99170a..a10cdaf46 100644 --- a/src/entropy/hres_timer/hres_timer.cpp +++ b/src/entropy/hres_timer/hres_timer.cpp @@ -32,13 +32,13 @@ void High_Resolution_Timestamp::poll(Entropy_Accumulator& accum) #if defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) if(CPUID::has_rdtsc()) // not availble on all x86 CPUs { - size_t rtc_low = 0, rtc_high = 0; + u32bit rtc_low = 0, rtc_high = 0; asm volatile("rdtsc" : "=d" (rtc_high), "=a" (rtc_low)); rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low; } #elif defined(BOTAN_TARGET_CPU_IS_PPC_FAMILY) - size_t rtc_low = 0, rtc_high = 0; + u32bit rtc_low = 0, rtc_high = 0; asm volatile("mftbu %0; mftb %1" : "=r" (rtc_high), "=r" (rtc_low)); rtc = (static_cast<u64bit>(rtc_high) << 32) | rtc_low; diff --git a/src/entropy/unix_procs/info.txt b/src/entropy/unix_procs/info.txt index 2100584e4..d2a15f13d 100644 --- a/src/entropy/unix_procs/info.txt +++ b/src/entropy/unix_procs/info.txt @@ -13,10 +13,10 @@ unix_cmd.h <os> aix -beos cygwin darwin -#freebsd +freebsd +haiku hpux irix linux diff --git a/src/entropy/unix_procs/unix_cmd.cpp b/src/entropy/unix_procs/unix_cmd.cpp index f4ae5054c..930444075 100644 --- a/src/entropy/unix_procs/unix_cmd.cpp +++ b/src/entropy/unix_procs/unix_cmd.cpp @@ -12,6 +12,7 @@ #include <sys/time.h> #include <sys/types.h> #include <sys/wait.h> +#include <string.h> #include <stdlib.h> #include <unistd.h> #include <signal.h> diff --git a/src/filters/codec_filt/b64_filt.cpp b/src/filters/codec_filt/b64_filt.cpp index 8a90f8b5f..9341571d4 100644 --- a/src/filters/codec_filt/b64_filt.cpp +++ b/src/filters/codec_filt/b64_filt.cpp @@ -14,32 +14,6 @@ namespace Botan { /* -* Base64 Decoder Lookup Table -* Warning: assumes ASCII encodings -*/ -static const byte BASE64_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, 0x3E, 0x80, 0x80, 0x80, 0x3F, 0x34, 0x35, 0x36, 0x37, -0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x80, -0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, -0x0D, 0x0E, 0x0F, 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, -0x80, 0x80, 0x80, 0x80, 0x80, 0x80, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F, 0x20, -0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, -0x2E, 0x2F, 0x30, 0x31, 0x32, 0x33, 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 }; - -/* * Base64_Encoder Constructor */ Base64_Encoder::Base64_Encoder(bool breaks, size_t length, bool t_n) : @@ -68,6 +42,7 @@ void Base64_Encoder::encode_and_send(const byte input[], size_t length, do_output(&out[0], produced); + // FIXME: s/proc/consumed/? input += proc; length -= proc; } @@ -138,58 +113,9 @@ void Base64_Encoder::end_msg() /* * Base64_Decoder Constructor */ -Base64_Decoder::Base64_Decoder(Decoder_Checking c) : checking(c) - { - in.resize(48); - out.resize(3); - position = 0; - } - -/* -* Check if a character is a valid Base64 char -*/ -bool Base64_Decoder::is_valid(byte in) - { - return (BASE64_TO_BIN[in] != 0x80); - } - -/* -* Base64 Decoding Operation -*/ -void Base64_Decoder::decode(const byte in[4], byte out[3]) - { - out[0] = ((BASE64_TO_BIN[in[0]] << 2) | (BASE64_TO_BIN[in[1]] >> 4)); - out[1] = ((BASE64_TO_BIN[in[1]] << 4) | (BASE64_TO_BIN[in[2]] >> 2)); - out[2] = ((BASE64_TO_BIN[in[2]] << 6) | (BASE64_TO_BIN[in[3]])); - } - -/* -* Decode and send a block -*/ -void Base64_Decoder::decode_and_send(const byte block[], size_t length) - { - for(size_t i = 0; i != length; i += 4) - { - decode(block + i, &out[0]); - send(out, 3); - } - } - -/* -* Handle processing an invalid character -*/ -void Base64_Decoder::handle_bad_char(byte c) +Base64_Decoder::Base64_Decoder(Decoder_Checking c) : + checking(c), in(64), out(48), position(0) { - if(c == '=' || checking == NONE) - return; - - if((checking == IGNORE_WS) && Charset::is_space(c)) - return; - - throw Decoding_Error( - std::string("Base64_Decoder: Invalid base64 character '") + - static_cast<char>(c) + "'" - ); } /* @@ -197,18 +123,32 @@ void Base64_Decoder::handle_bad_char(byte c) */ void Base64_Decoder::write(const byte input[], size_t length) { - for(size_t i = 0; i != length; ++i) + while(length) { - if(is_valid(input[i])) - in[position++] = input[i]; - else - handle_bad_char(input[i]); + size_t to_copy = std::min<size_t>(length, in.size() - position); + copy_mem(&in[position], input, to_copy); + position += to_copy; + + size_t consumed = 0; + size_t written = base64_decode(&out[0], + reinterpret_cast<const char*>(&in[0]), + position, + consumed, + false, + checking != FULL_CHECK); + + send(out, written); - if(position == in.size()) + if(consumed != position) { - decode_and_send(&in[0], in.size()); - position = 0; + copy_mem(&in[0], &in[consumed], position - consumed); + position = position - consumed; } + else + position = 0; + + length -= to_copy; + input += to_copy; } } @@ -217,21 +157,22 @@ void Base64_Decoder::write(const byte input[], size_t length) */ void Base64_Decoder::end_msg() { - if(position != 0) - { - size_t start_of_last_block = 4 * (position / 4), - left_over = position % 4; - decode_and_send(&in[0], start_of_last_block); + size_t consumed = 0; + size_t written = base64_decode(&out[0], + reinterpret_cast<const char*>(&in[0]), + position, + consumed, + true, + checking != FULL_CHECK); + + send(out, written); + + const bool not_full_bytes = consumed != position; - if(left_over) - { - SecureVector<byte> remainder(4); - copy_mem(&remainder[0], &in[start_of_last_block], left_over); - decode(&remainder[0], &out[0]); - send(out, ((left_over == 1) ? (1) : (left_over - 1))); - } - } position = 0; + + if(not_full_bytes) + throw std::invalid_argument("Base64_Decoder: Input not full bytes"); } } diff --git a/src/filters/codec_filt/b64_filt.h b/src/filters/codec_filt/b64_filt.h index df3896666..afff53f30 100644 --- a/src/filters/codec_filt/b64_filt.h +++ b/src/filters/codec_filt/b64_filt.h @@ -47,7 +47,7 @@ class BOTAN_DLL Base64_Encoder : public Filter const size_t line_length; const bool trailing_newline; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position, out_position; }; @@ -78,14 +78,8 @@ class BOTAN_DLL Base64_Decoder : public Filter */ Base64_Decoder(Decoder_Checking checking = NONE); private: - static void decode(const byte input[4], byte output[3]); - static bool is_valid(byte c); - - void decode_and_send(const byte[], size_t); - void handle_bad_char(byte); - const Decoder_Checking checking; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position; }; diff --git a/src/filters/codec_filt/hex_filt.h b/src/filters/codec_filt/hex_filt.h index cfbb818d3..0dc38c804 100644 --- a/src/filters/codec_filt/hex_filt.h +++ b/src/filters/codec_filt/hex_filt.h @@ -49,7 +49,7 @@ class BOTAN_DLL Hex_Encoder : public Filter const Case casing; const size_t line_length; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position, counter; }; @@ -72,7 +72,7 @@ class BOTAN_DLL Hex_Decoder : public Filter Hex_Decoder(Decoder_Checking checking = NONE); private: const Decoder_Checking checking; - SecureVector<byte> in, out; + MemoryVector<byte> in, out; size_t position; }; diff --git a/src/filters/fd_unix/info.txt b/src/filters/fd_unix/info.txt index 9c3d0acbc..d636035f0 100644 --- a/src/filters/fd_unix/info.txt +++ b/src/filters/fd_unix/info.txt @@ -4,11 +4,11 @@ load_on auto <os> aix -beos cygwin darwin -freebsd dragonfly +freebsd +haiku hpux irix linux diff --git a/src/hash/bmw/bmw_512.cpp b/src/hash/bmw_512/bmw_512.cpp index 40338fdf0..40338fdf0 100644 --- a/src/hash/bmw/bmw_512.cpp +++ b/src/hash/bmw_512/bmw_512.cpp diff --git a/src/hash/bmw/bmw_512.h b/src/hash/bmw_512/bmw_512.h index 474b607bb..474b607bb 100644 --- a/src/hash/bmw/bmw_512.h +++ b/src/hash/bmw_512/bmw_512.h diff --git a/src/hash/bmw/info.txt b/src/hash/bmw_512/info.txt index 7170223d7..7170223d7 100644 --- a/src/hash/bmw/info.txt +++ b/src/hash/bmw_512/info.txt diff --git a/src/hash/md4_ia32/info.txt b/src/hash/md4_x86_32/info.txt index 5d14188f2..fdc534df4 100644 --- a/src/hash/md4_ia32/info.txt +++ b/src/hash/md4_x86_32/info.txt @@ -1,12 +1,12 @@ -define MD4_IA32 +define MD4_X86_32 load_on asm_ok <arch> -ia32 +x86_32 </arch> <requires> -asm_ia32 +asm_x86_32 md4 </requires> diff --git a/src/hash/md4_ia32/md4_ia32.cpp b/src/hash/md4_x86_32/md4_x86_32.cpp index 98d3c7a19..750e65a95 100644 --- a/src/hash/md4_ia32/md4_ia32.cpp +++ b/src/hash/md4_x86_32/md4_x86_32.cpp @@ -1,32 +1,32 @@ /* -* MD4 (IA-32) +* MD4 (x86-32) * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/md4_ia32.h> +#include <botan/md4_x86_32.h> namespace Botan { /** -* MD4 compression function in IA-32 asm +* MD4 compression function in x86-32 asm * @param digest the current digest * @param input the input block * @param M the message buffer */ -extern "C" void botan_md4_ia32_compress(u32bit digest[4], +extern "C" void botan_md4_x86_32_compress(u32bit digest[4], const byte input[64], u32bit M[16]); /* * MD4 Compression Function */ -void MD4_IA32::compress_n(const byte input[], size_t blocks) +void MD4_X86_32::compress_n(const byte input[], size_t blocks) { for(size_t i = 0; i != blocks; ++i) { - botan_md4_ia32_compress(digest, input, M); + botan_md4_x86_32_compress(digest, input, M); input += hash_block_size(); } } diff --git a/src/hash/md4_ia32/md4_ia32.h b/src/hash/md4_x86_32/md4_x86_32.h index 4bb8f1add..a9f23e94f 100644 --- a/src/hash/md4_ia32/md4_ia32.h +++ b/src/hash/md4_x86_32/md4_x86_32.h @@ -1,12 +1,12 @@ /* -* MD4 (IA-32) +* MD4 (x86-32) * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_MD4_IA32_H__ -#define BOTAN_MD4_IA32_H__ +#ifndef BOTAN_MD4_X86_32_H__ +#define BOTAN_MD4_X86_32_H__ #include <botan/md4.h> @@ -15,10 +15,10 @@ namespace Botan { /** * MD4 using x86 assembly */ -class BOTAN_DLL MD4_IA32 : public MD4 +class BOTAN_DLL MD4_X86_32 : public MD4 { public: - HashFunction* clone() const { return new MD4_IA32; } + HashFunction* clone() const { return new MD4_X86_32; } private: void compress_n(const byte[], size_t blocks); }; diff --git a/src/hash/md4_ia32/md4_ia32_imp.S b/src/hash/md4_x86_32/md4_x86_32_imp.S index c7e108147..192751166 100644 --- a/src/hash/md4_ia32/md4_ia32_imp.S +++ b/src/hash/md4_x86_32/md4_x86_32_imp.S @@ -1,15 +1,15 @@ /* -* MD4 in IA-32 assembler +* MD4 in x86-32 assembler * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/internal/asm_macr_ia32.h> +#include <botan/internal/asm_x86_32.h> -START_LISTING(md4_ia32.S) +START_LISTING(md4_x86_32_imp.S) -START_FUNCTION(botan_md4_ia32_compress) +START_FUNCTION(botan_md4_x86_32_compress) SPILL_REGS() #define PUSHED 4 @@ -134,4 +134,4 @@ LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT) ADD(ARRAY4(EBP, 3), EDX) RESTORE_REGS() -END_FUNCTION(botan_md4_ia32_compress) +END_FUNCTION(botan_md4_x86_32_compress) diff --git a/src/hash/md5_ia32/info.txt b/src/hash/md5_x86_32/info.txt index 9be698a3f..adec65f81 100644 --- a/src/hash/md5_ia32/info.txt +++ b/src/hash/md5_x86_32/info.txt @@ -1,12 +1,12 @@ -define MD5_IA32 +define MD5_X86_32 load_on asm_ok <arch> -ia32 +x86_32 </arch> <requires> -asm_ia32 +asm_x86_32 md5 </requires> diff --git a/src/hash/md5_ia32/md5_ia32.cpp b/src/hash/md5_x86_32/md5_x86_32.cpp index 6ae235d2b..123fcff77 100644 --- a/src/hash/md5_ia32/md5_ia32.cpp +++ b/src/hash/md5_x86_32/md5_x86_32.cpp @@ -1,29 +1,29 @@ /* -* MD5 (IA-32) +* MD5 (x86-32) * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/md5_ia32.h> +#include <botan/md5_x86_32.h> namespace Botan { namespace { extern "C" -void botan_md5_ia32_compress(u32bit[4], const byte[64], u32bit[16]); +void botan_md5_x86_32_compress(u32bit[4], const byte[64], u32bit[16]); } /* * MD5 Compression Function */ -void MD5_IA32::compress_n(const byte input[], size_t blocks) +void MD5_X86_32::compress_n(const byte input[], size_t blocks) { for(size_t i = 0; i != blocks; ++i) { - botan_md5_ia32_compress(digest, input, M); + botan_md5_x86_32_compress(digest, input, M); input += hash_block_size(); } } diff --git a/src/hash/md5_ia32/md5_ia32.h b/src/hash/md5_x86_32/md5_x86_32.h index bf4b4c505..0150249ae 100644 --- a/src/hash/md5_ia32/md5_ia32.h +++ b/src/hash/md5_x86_32/md5_x86_32.h @@ -1,12 +1,12 @@ /* -* MD5 (IA-32) +* MD5 (x86-32) * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_MD5_IA32_H__ -#define BOTAN_MD5_IA32_H__ +#ifndef BOTAN_MD5_X86_32_H__ +#define BOTAN_MD5_X86_32_H__ #include <botan/md5.h> @@ -15,10 +15,10 @@ namespace Botan { /** * MD5 in x86 assembly */ -class BOTAN_DLL MD5_IA32 : public MD5 +class BOTAN_DLL MD5_X86_32 : public MD5 { public: - HashFunction* clone() const { return new MD5_IA32; } + HashFunction* clone() const { return new MD5_X86_32; } private: void compress_n(const byte[], size_t blocks); }; diff --git a/src/hash/md5_ia32/md5_ia32_imp.S b/src/hash/md5_x86_32/md5_x86_32_imp.S index e77836353..f41aaccbf 100644 --- a/src/hash/md5_ia32/md5_ia32_imp.S +++ b/src/hash/md5_x86_32/md5_x86_32_imp.S @@ -1,15 +1,15 @@ /* -* MD5 in IA-32 assembler +* MD5 in x86-32 assembler * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/internal/asm_macr_ia32.h> +#include <botan/internal/asm_x86_32.h> -START_LISTING(md5_ia32.S) +START_LISTING(md5_x86_32.S) -START_FUNCTION(botan_md5_ia32_compress) +START_FUNCTION(botan_md5_x86_32_compress) SPILL_REGS() #define PUSHED 4 @@ -163,4 +163,4 @@ LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT) ADD(ARRAY4(EBP, 3), EDX) RESTORE_REGS() -END_FUNCTION(botan_md5_ia32_compress) +END_FUNCTION(botan_md5_x86_32_compress) diff --git a/src/hash/sha1/sha160.cpp b/src/hash/sha1/sha160.cpp index 7a42ca867..f5daaadb2 100644 --- a/src/hash/sha1/sha160.cpp +++ b/src/hash/sha1/sha160.cpp @@ -1,6 +1,6 @@ /* * SHA-160 -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2008,2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,6 +11,8 @@ namespace Botan { +namespace SHA1_F { + namespace { /* @@ -51,11 +53,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) } +} + /* * SHA-160 Compression Function */ void SHA_160::compress_n(const byte input[], size_t blocks) { + using namespace SHA1_F; + u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4]; diff --git a/src/hash/sha1_ia32/sha1_ia32.h b/src/hash/sha1_ia32/sha1_ia32.h deleted file mode 100644 index 5cff03016..000000000 --- a/src/hash/sha1_ia32/sha1_ia32.h +++ /dev/null @@ -1,31 +0,0 @@ -/* -* SHA-160 (IA-32) -* (C) 1999-2007 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SHA_160_IA32_H__ -#define BOTAN_SHA_160_IA32_H__ - -#include <botan/sha160.h> - -namespace Botan { - -/** -* SHA-160 in x86 assembly -*/ -class BOTAN_DLL SHA_160_IA32 : public SHA_160 - { - public: - HashFunction* clone() const { return new SHA_160_IA32; } - - // Note 81 instead of normal 80: IA-32 asm needs an extra temp - SHA_160_IA32() : SHA_160(81) {} - private: - void compress_n(const byte[], size_t blocks); - }; - -} - -#endif diff --git a/src/hash/sha1_sse2/sha1_sse2.cpp b/src/hash/sha1_sse2/sha1_sse2.cpp index e890967c6..f96afd9ce 100644 --- a/src/hash/sha1_sse2/sha1_sse2.cpp +++ b/src/hash/sha1_sse2/sha1_sse2.cpp @@ -1,6 +1,6 @@ /* * SHA-1 using SSE2 -* (C) 2009-2010 Jack Lloyd +* (C) 2009-2011 Jack Lloyd * * Distributed under the terms of the Botan license * @@ -14,6 +14,8 @@ namespace Botan { +namespace SHA1_SSE2_F { + namespace { /* @@ -146,11 +148,15 @@ inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) } +} + /* * SHA-160 Compression Function using SSE for message expansion */ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) { + using namespace SHA1_SSE2_F; + const __m128i K00_19 = _mm_set1_epi32(0x5A827999); const __m128i K20_39 = _mm_set1_epi32(0x6ED9EBA1); const __m128i K40_59 = _mm_set1_epi32(0x8F1BBCDC); @@ -323,4 +329,7 @@ void SHA_160_SSE2::compress_n(const byte input_bytes[], size_t blocks) #undef GET_P_32 } +#undef prep00_15 +#undef prep + } diff --git a/src/hash/sha1_ia32/info.txt b/src/hash/sha1_x86_32/info.txt index 47d8e753e..7359a6754 100644 --- a/src/hash/sha1_ia32/info.txt +++ b/src/hash/sha1_x86_32/info.txt @@ -1,12 +1,12 @@ -define SHA1_IA32 +define SHA1_X86_32 load_on asm_ok <arch> -ia32 +x86_32 </arch> <requires> -asm_ia32 +asm_x86_32 sha1 </requires> diff --git a/src/hash/sha1_ia32/sha1_ia32.cpp b/src/hash/sha1_x86_32/sha1_x86_32.cpp index 3e9cff047..6a4dc2a1d 100644 --- a/src/hash/sha1_ia32/sha1_ia32.cpp +++ b/src/hash/sha1_x86_32/sha1_x86_32.cpp @@ -1,29 +1,29 @@ /* -* SHA-160 (IA-32) +* SHA-160 in x86-32 * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/sha1_ia32.h> +#include <botan/sha1_x86_32.h> namespace Botan { namespace { extern "C" -void botan_sha160_ia32_compress(u32bit[5], const byte[64], u32bit[81]); +void botan_sha160_x86_32_compress(u32bit[5], const byte[64], u32bit[81]); } /* * SHA-160 Compression Function */ -void SHA_160_IA32::compress_n(const byte input[], size_t blocks) +void SHA_160_X86_32::compress_n(const byte input[], size_t blocks) { for(size_t i = 0; i != blocks; ++i) { - botan_sha160_ia32_compress(&digest[0], input, &W[0]); + botan_sha160_x86_32_compress(&digest[0], input, &W[0]); input += hash_block_size(); } } diff --git a/src/hash/sha1_x86_32/sha1_x86_32.h b/src/hash/sha1_x86_32/sha1_x86_32.h new file mode 100644 index 000000000..b344d4ae2 --- /dev/null +++ b/src/hash/sha1_x86_32/sha1_x86_32.h @@ -0,0 +1,31 @@ +/* +* SHA-160 in x86-32 asm +* (C) 1999-2007 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SHA_160_X86_32_H__ +#define BOTAN_SHA_160_X86_32_H__ + +#include <botan/sha160.h> + +namespace Botan { + +/** +* SHA-160 in x86 assembly +*/ +class BOTAN_DLL SHA_160_X86_32 : public SHA_160 + { + public: + HashFunction* clone() const { return new SHA_160_X86_32; } + + // Note 81 instead of normal 80: x86-32 asm needs an extra temp + SHA_160_X86_32() : SHA_160(81) {} + private: + void compress_n(const byte[], size_t blocks); + }; + +} + +#endif diff --git a/src/hash/sha1_ia32/sha1_ia32_imp.S b/src/hash/sha1_x86_32/sha1_x86_32_imp.S index c2777b4b5..775ef6854 100644 --- a/src/hash/sha1_ia32/sha1_ia32_imp.S +++ b/src/hash/sha1_x86_32/sha1_x86_32_imp.S @@ -1,15 +1,15 @@ /* -* SHA-1 in IA-32 assembler +* SHA-1 in x86-32 asm * (C) 1999-2007 Jack Lloyd * * Distributed under the terms of the Botan license */ -#include <botan/internal/asm_macr_ia32.h> +#include <botan/internal/asm_x86_32.h> -START_LISTING(sha1_ia32.S) +START_LISTING(sha1_x86_32_imp.S) -START_FUNCTION(botan_sha160_ia32_compress) +START_FUNCTION(botan_sha160_x86_32_compress) SPILL_REGS() #define PUSHED 4 @@ -42,7 +42,7 @@ LOOP_UNTIL_EQ(ESI, 16, .LOAD_INPUT) ADD2_IMM(EDI, EBP, 64) -START_LOOP(.EXPANSION) +START_LOOP(.L_SHA_EXPANSION) ADD_IMM(ESI, 4) ZEROIZE(EAX) @@ -77,7 +77,7 @@ START_LOOP(.EXPANSION) ASSIGN(ARRAY4(EDI, 3), EAX) ADD_IMM(EDI, 16) -LOOP_UNTIL_EQ(ESI, 80, .EXPANSION) +LOOP_UNTIL_EQ(ESI, 80, .L_SHA_EXPANSION) #define MAGIC1 0x5A827999 #define MAGIC2 0x6ED9EBA1 @@ -241,4 +241,4 @@ LOOP_UNTIL_EQ(ESI, 80, .EXPANSION) ADD(ARRAY4(EBP, 4), ECX) RESTORE_REGS() -END_FUNCTION(botan_sha160_ia32_compress) +END_FUNCTION(botan_sha160_x86_32_compress) diff --git a/src/hash/sha1_amd64/info.txt b/src/hash/sha1_x86_64/info.txt index 78eaa23c2..3d54c0baa 100644 --- a/src/hash/sha1_amd64/info.txt +++ b/src/hash/sha1_x86_64/info.txt @@ -1,13 +1,13 @@ -define SHA1_AMD64 +define SHA1_X86_64 load_on asm_ok <arch> -amd64 +x86_64 </arch> <requires> asm_engine -asm_amd64 +asm_x86_64 sha1 </requires> diff --git a/src/hash/sha1_amd64/sha1_amd64.cpp b/src/hash/sha1_x86_64/sha1_x86_64.cpp index d32b44901..a3e92e313 100644 --- a/src/hash/sha1_amd64/sha1_amd64.cpp +++ b/src/hash/sha1_x86_64/sha1_x86_64.cpp @@ -5,25 +5,25 @@ * Distributed under the terms of the Botan license */ -#include <botan/sha1_amd64.h> +#include <botan/sha1_x86_64.h> namespace Botan { namespace { extern "C" -void botan_sha160_amd64_compress(u32bit[5], const byte[64], u32bit[80]); +void botan_sha160_x86_64_compress(u32bit[5], const byte[64], u32bit[80]); } /* * SHA-160 Compression Function */ -void SHA_160_AMD64::compress_n(const byte input[], size_t blocks) +void SHA_160_X86_64::compress_n(const byte input[], size_t blocks) { for(size_t i = 0; i != blocks; ++i) { - botan_sha160_amd64_compress(&digest[0], input, &W[0]); + botan_sha160_x86_64_compress(&digest[0], input, &W[0]); input += hash_block_size(); } } diff --git a/src/hash/sha1_amd64/sha1_amd64.h b/src/hash/sha1_x86_64/sha1_x86_64.h index 6b741184d..068a94595 100644 --- a/src/hash/sha1_amd64/sha1_amd64.h +++ b/src/hash/sha1_x86_64/sha1_x86_64.h @@ -5,8 +5,8 @@ * Distributed under the terms of the Botan license */ -#ifndef BOTAN_SHA_160_AMD64_H__ -#define BOTAN_SHA_160_AMD64_H__ +#ifndef BOTAN_SHA_160_X86_64_H__ +#define BOTAN_SHA_160_X86_64_H__ #include <botan/sha160.h> @@ -15,10 +15,10 @@ namespace Botan { /** * SHA-160 in x86-64 assembly */ -class BOTAN_DLL SHA_160_AMD64 : public SHA_160 +class BOTAN_DLL SHA_160_X86_64 : public SHA_160 { public: - HashFunction* clone() const { return new SHA_160_AMD64; } + HashFunction* clone() const { return new SHA_160_X86_64; } private: void compress_n(const byte[], size_t blocks); }; diff --git a/src/hash/sha1_amd64/sha1_amd64_imp.S b/src/hash/sha1_x86_64/sha1_x86_64_imp.S index 4eea75f11..ee35f0d85 100644 --- a/src/hash/sha1_amd64/sha1_amd64_imp.S +++ b/src/hash/sha1_x86_64/sha1_x86_64_imp.S @@ -5,11 +5,11 @@ * Distributed under the terms of the Botan license */ -#include <botan/internal/asm_macr_amd64.h> +#include <botan/internal/asm_x86_64.h> -START_LISTING(sha1_amd64.S) +START_LISTING(sha1_x86_64_imp.S) -START_FUNCTION(botan_sha160_amd64_compress) +START_FUNCTION(botan_sha160_x86_64_compress) #define DIGEST_ARR %rdi #define INPUT %rsi @@ -263,4 +263,4 @@ ALIGN; ADD(ARRAY4(DIGEST_ARR, 3), B) ADD(ARRAY4(DIGEST_ARR, 4), C) -END_FUNCTION(botan_sha160_amd64_compress) +END_FUNCTION(botan_sha160_x86_64_compress) diff --git a/src/hash/sha2_32/sha2_32.cpp b/src/hash/sha2_32/sha2_32.cpp index 4e5f2b38c..6dd780e64 100644 --- a/src/hash/sha2_32/sha2_32.cpp +++ b/src/hash/sha2_32/sha2_32.cpp @@ -14,6 +14,8 @@ namespace Botan { namespace { +namespace SHA2_32 { + /* * SHA-256 Rho Function */ @@ -33,22 +35,23 @@ inline u32bit sigma(u32bit X, u32bit rot1, u32bit rot2, u32bit shift) /* * SHA-256 F1 Function +* +* Use a macro as many compilers won't inline a function this big, +* even though it is much faster if inlined. */ -inline void F1(u32bit A, u32bit B, u32bit C, u32bit& D, - u32bit E, u32bit F, u32bit G, u32bit& H, - u32bit msg, u32bit magic) - { - H += magic + rho(E, 6, 11, 25) + ((E & F) ^ (~E & G)) + msg; - D += H; - H += rho(A, 2, 13, 22) + ((A & B) | ((A | B) & C)); - } +#define SHA2_32_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \ + do { \ + H += magic + rho(E, 6, 11, 25) + ((E & F) ^ (~E & G)) + M1; \ + D += H; \ + H += rho(A, 2, 13, 22) + ((A & B) | ((A | B) & C)); \ + M1 += sigma(M2, 17, 19, 10) + M3 + sigma(M4, 7, 18, 3); \ + } while(0); /* * SHA-224 / SHA-256 compression function */ -void sha2_32_compress(MemoryRegion<u32bit>& W, - MemoryRegion<u32bit>& digest, - const byte input[], size_t blocks) +void compress(MemoryRegion<u32bit>& digest, + const byte input[], size_t blocks) { u32bit A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], @@ -56,92 +59,87 @@ void sha2_32_compress(MemoryRegion<u32bit>& W, for(size_t i = 0; i != blocks; ++i) { - load_be(&W[0], input, 16); - - for(size_t j = 16; j != 64; j += 8) - { - W[j ] = sigma(W[j- 2], 17, 19, 10) + W[j-7] + - sigma(W[j-15], 7, 18, 3) + W[j-16]; - W[j+1] = sigma(W[j- 1], 17, 19, 10) + W[j-6] + - sigma(W[j-14], 7, 18, 3) + W[j-15]; - W[j+2] = sigma(W[j ], 17, 19, 10) + W[j-5] + - sigma(W[j-13], 7, 18, 3) + W[j-14]; - W[j+3] = sigma(W[j+ 1], 17, 19, 10) + W[j-4] + - sigma(W[j-12], 7, 18, 3) + W[j-13]; - W[j+4] = sigma(W[j+ 2], 17, 19, 10) + W[j-3] + - sigma(W[j-11], 7, 18, 3) + W[j-12]; - W[j+5] = sigma(W[j+ 3], 17, 19, 10) + W[j-2] + - sigma(W[j-10], 7, 18, 3) + W[j-11]; - W[j+6] = sigma(W[j+ 4], 17, 19, 10) + W[j-1] + - sigma(W[j- 9], 7, 18, 3) + W[j-10]; - W[j+7] = sigma(W[j+ 5], 17, 19, 10) + W[j ] + - sigma(W[j- 8], 7, 18, 3) + W[j- 9]; - } - - F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98); - F1(H, A, B, C, D, E, F, G, W[ 1], 0x71374491); - F1(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF); - F1(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5); - F1(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B); - F1(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1); - F1(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4); - F1(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5); - F1(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98); - F1(H, A, B, C, D, E, F, G, W[ 9], 0x12835B01); - F1(G, H, A, B, C, D, E, F, W[10], 0x243185BE); - F1(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3); - F1(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74); - F1(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE); - F1(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7); - F1(B, C, D, E, F, G, H, A, W[15], 0xC19BF174); - F1(A, B, C, D, E, F, G, H, W[16], 0xE49B69C1); - F1(H, A, B, C, D, E, F, G, W[17], 0xEFBE4786); - F1(G, H, A, B, C, D, E, F, W[18], 0x0FC19DC6); - F1(F, G, H, A, B, C, D, E, W[19], 0x240CA1CC); - F1(E, F, G, H, A, B, C, D, W[20], 0x2DE92C6F); - F1(D, E, F, G, H, A, B, C, W[21], 0x4A7484AA); - F1(C, D, E, F, G, H, A, B, W[22], 0x5CB0A9DC); - F1(B, C, D, E, F, G, H, A, W[23], 0x76F988DA); - F1(A, B, C, D, E, F, G, H, W[24], 0x983E5152); - F1(H, A, B, C, D, E, F, G, W[25], 0xA831C66D); - F1(G, H, A, B, C, D, E, F, W[26], 0xB00327C8); - F1(F, G, H, A, B, C, D, E, W[27], 0xBF597FC7); - F1(E, F, G, H, A, B, C, D, W[28], 0xC6E00BF3); - F1(D, E, F, G, H, A, B, C, W[29], 0xD5A79147); - F1(C, D, E, F, G, H, A, B, W[30], 0x06CA6351); - F1(B, C, D, E, F, G, H, A, W[31], 0x14292967); - F1(A, B, C, D, E, F, G, H, W[32], 0x27B70A85); - F1(H, A, B, C, D, E, F, G, W[33], 0x2E1B2138); - F1(G, H, A, B, C, D, E, F, W[34], 0x4D2C6DFC); - F1(F, G, H, A, B, C, D, E, W[35], 0x53380D13); - F1(E, F, G, H, A, B, C, D, W[36], 0x650A7354); - F1(D, E, F, G, H, A, B, C, W[37], 0x766A0ABB); - F1(C, D, E, F, G, H, A, B, W[38], 0x81C2C92E); - F1(B, C, D, E, F, G, H, A, W[39], 0x92722C85); - F1(A, B, C, D, E, F, G, H, W[40], 0xA2BFE8A1); - F1(H, A, B, C, D, E, F, G, W[41], 0xA81A664B); - F1(G, H, A, B, C, D, E, F, W[42], 0xC24B8B70); - F1(F, G, H, A, B, C, D, E, W[43], 0xC76C51A3); - F1(E, F, G, H, A, B, C, D, W[44], 0xD192E819); - F1(D, E, F, G, H, A, B, C, W[45], 0xD6990624); - F1(C, D, E, F, G, H, A, B, W[46], 0xF40E3585); - F1(B, C, D, E, F, G, H, A, W[47], 0x106AA070); - F1(A, B, C, D, E, F, G, H, W[48], 0x19A4C116); - F1(H, A, B, C, D, E, F, G, W[49], 0x1E376C08); - F1(G, H, A, B, C, D, E, F, W[50], 0x2748774C); - F1(F, G, H, A, B, C, D, E, W[51], 0x34B0BCB5); - F1(E, F, G, H, A, B, C, D, W[52], 0x391C0CB3); - F1(D, E, F, G, H, A, B, C, W[53], 0x4ED8AA4A); - F1(C, D, E, F, G, H, A, B, W[54], 0x5B9CCA4F); - F1(B, C, D, E, F, G, H, A, W[55], 0x682E6FF3); - F1(A, B, C, D, E, F, G, H, W[56], 0x748F82EE); - F1(H, A, B, C, D, E, F, G, W[57], 0x78A5636F); - F1(G, H, A, B, C, D, E, F, W[58], 0x84C87814); - F1(F, G, H, A, B, C, D, E, W[59], 0x8CC70208); - F1(E, F, G, H, A, B, C, D, W[60], 0x90BEFFFA); - F1(D, E, F, G, H, A, B, C, W[61], 0xA4506CEB); - F1(C, D, E, F, G, H, A, B, W[62], 0xBEF9A3F7); - F1(B, C, D, E, F, G, H, A, W[63], 0xC67178F2); + u32bit W00 = load_be<u32bit>(input, 0); + u32bit W01 = load_be<u32bit>(input, 1); + u32bit W02 = load_be<u32bit>(input, 2); + u32bit W03 = load_be<u32bit>(input, 3); + u32bit W04 = load_be<u32bit>(input, 4); + u32bit W05 = load_be<u32bit>(input, 5); + u32bit W06 = load_be<u32bit>(input, 6); + u32bit W07 = load_be<u32bit>(input, 7); + u32bit W08 = load_be<u32bit>(input, 8); + u32bit W09 = load_be<u32bit>(input, 9); + u32bit W10 = load_be<u32bit>(input, 10); + u32bit W11 = load_be<u32bit>(input, 11); + u32bit W12 = load_be<u32bit>(input, 12); + u32bit W13 = load_be<u32bit>(input, 13); + u32bit W14 = load_be<u32bit>(input, 14); + u32bit W15 = load_be<u32bit>(input, 15); + + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x71374491); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCF); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25B); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B01); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174); + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C1); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC6); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DC); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C8); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF3); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x14292967); + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A85); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B2138); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D13); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A7354); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C85); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A1); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664B); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A3); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD6990624); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E3585); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA070); + SHA2_32_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116); + SHA2_32_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C08); + SHA2_32_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774C); + SHA2_32_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5); + SHA2_32_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3); + SHA2_32_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4A); + SHA2_32_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F); + SHA2_32_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3); + SHA2_32_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE); + SHA2_32_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F); + SHA2_32_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814); + SHA2_32_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC70208); + SHA2_32_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA); + SHA2_32_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEB); + SHA2_32_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7); + SHA2_32_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2); A = (digest[0] += A); B = (digest[1] += B); @@ -158,12 +156,14 @@ void sha2_32_compress(MemoryRegion<u32bit>& W, } +} + /* * SHA-224 compression function */ void SHA_224::compress_n(const byte input[], size_t blocks) { - sha2_32_compress(W, digest, input, blocks); + SHA2_32::compress(digest, input, blocks); } /* @@ -181,7 +181,6 @@ void SHA_224::copy_out(byte output[]) void SHA_224::clear() { MDx_HashFunction::clear(); - zeroise(W); digest[0] = 0xC1059ED8; digest[1] = 0x367CD507; digest[2] = 0x3070DD17; @@ -197,7 +196,7 @@ void SHA_224::clear() */ void SHA_256::compress_n(const byte input[], size_t blocks) { - sha2_32_compress(W, digest, input, blocks); + SHA2_32::compress(digest, input, blocks); } /* @@ -215,7 +214,6 @@ void SHA_256::copy_out(byte output[]) void SHA_256::clear() { MDx_HashFunction::clear(); - zeroise(W); digest[0] = 0x6A09E667; digest[1] = 0xBB67AE85; digest[2] = 0x3C6EF372; diff --git a/src/hash/sha2_32/sha2_32.h b/src/hash/sha2_32/sha2_32.h index ffda11772..807b979d1 100644 --- a/src/hash/sha2_32/sha2_32.h +++ b/src/hash/sha2_32/sha2_32.h @@ -1,6 +1,6 @@ /* * SHA-{224,256} -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * 2007 FlexSecure GmbH * * Distributed under the terms of the Botan license @@ -25,13 +25,13 @@ class BOTAN_DLL SHA_224 : public MDx_HashFunction void clear(); - SHA_224() : MDx_HashFunction(64, true, true), W(64), digest(8) + SHA_224() : MDx_HashFunction(64, true, true), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - SecureVector<u32bit> W, digest; + SecureVector<u32bit> digest; }; /** @@ -46,13 +46,13 @@ class BOTAN_DLL SHA_256 : public MDx_HashFunction void clear(); - SHA_256() : MDx_HashFunction(64, true, true), W(64), digest(8) + SHA_256() : MDx_HashFunction(64, true, true), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - SecureVector<u32bit> W, digest; + SecureVector<u32bit> digest; }; } diff --git a/src/hash/sha2_64/sha2_64.cpp b/src/hash/sha2_64/sha2_64.cpp index 3c1df9be6..3026c3a39 100644 --- a/src/hash/sha2_64/sha2_64.cpp +++ b/src/hash/sha2_64/sha2_64.cpp @@ -1,6 +1,6 @@ /* * SHA-{384,512} -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -13,6 +13,8 @@ namespace Botan { namespace { +namespace SHA2_64 { + /* * SHA-{384,512} Rho Function */ @@ -23,18 +25,6 @@ inline u64bit rho(u64bit X, u32bit rot1, u32bit rot2, u32bit rot3) } /* -* SHA-{384,512} F1 Function -*/ -inline void F1(u64bit A, u64bit B, u64bit C, u64bit& D, - u64bit E, u64bit F, u64bit G, u64bit& H, - u64bit msg, u64bit magic) - { - magic += rho(E, 14, 18, 41) + ((E & F) ^ (~E & G)) + msg; - D += magic + H; - H += magic + rho(A, 28, 34, 39) + ((A & B) ^ (A & C) ^ (B & C)); - } - -/* * SHA-{384,512} Sigma Function */ inline u64bit sigma(u64bit X, u32bit rot1, u32bit rot2, u32bit shift) @@ -43,11 +33,24 @@ inline u64bit sigma(u64bit X, u32bit rot1, u32bit rot2, u32bit shift) } /* +* SHA-512 F1 Function +* +* Use a macro as many compilers won't inline a function this big, +* even though it is much faster if inlined. +*/ +#define SHA2_64_F(A, B, C, D, E, F, G, H, M1, M2, M3, M4, magic) \ + do { \ + H += magic + rho(E, 14, 18, 41) + ((E & F) ^ (~E & G)) + M1; \ + D += H; \ + H += rho(A, 28, 34, 39) + ((A & B) | ((A | B) & C)); \ + M1 += sigma(M2, 19, 61, 6) + M3 + sigma(M4, 1, 8, 7); \ + } while(0); + +/* * SHA-{384,512} Compression Function */ -void sha2_64_compress(MemoryRegion<u64bit>& W, - MemoryRegion<u64bit>& digest, - const byte input[], size_t blocks) +void compress(MemoryRegion<u64bit>& digest, + const byte input[], size_t blocks) { u64bit A = digest[0], B = digest[1], C = digest[2], D = digest[3], E = digest[4], F = digest[5], @@ -55,100 +58,103 @@ void sha2_64_compress(MemoryRegion<u64bit>& W, for(size_t i = 0; i != blocks; ++i) { - load_be(&W[0], input, 16); - - for(size_t j = 16; j != 80; j += 8) - { - W[j ] = sigma(W[j-2], 19, 61, 6) + W[j-7] + sigma(W[j-15], 1, 8, 7) + W[j-16]; - W[j+1] = sigma(W[j-1], 19, 61, 6) + W[j-6] + sigma(W[j-14], 1, 8, 7) + W[j-15]; - W[j+2] = sigma(W[j ], 19, 61, 6) + W[j-5] + sigma(W[j-13], 1, 8, 7) + W[j-14]; - W[j+3] = sigma(W[j+1], 19, 61, 6) + W[j-4] + sigma(W[j-12], 1, 8, 7) + W[j-13]; - W[j+4] = sigma(W[j+2], 19, 61, 6) + W[j-3] + sigma(W[j-11], 1, 8, 7) + W[j-12]; - W[j+5] = sigma(W[j+3], 19, 61, 6) + W[j-2] + sigma(W[j-10], 1, 8, 7) + W[j-11]; - W[j+6] = sigma(W[j+4], 19, 61, 6) + W[j-1] + sigma(W[j- 9], 1, 8, 7) + W[j-10]; - W[j+7] = sigma(W[j+5], 19, 61, 6) + W[j ] + sigma(W[j- 8], 1, 8, 7) + W[j- 9]; - } - - F1(A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98D728AE22); - F1(H, A, B, C, D, E, F, G, W[ 1], 0x7137449123EF65CD); - F1(G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCFEC4D3B2F); - F1(F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA58189DBBC); - F1(E, F, G, H, A, B, C, D, W[ 4], 0x3956C25BF348B538); - F1(D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1B605D019); - F1(C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4AF194F9B); - F1(B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5DA6D8118); - F1(A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98A3030242); - F1(H, A, B, C, D, E, F, G, W[ 9], 0x12835B0145706FBE); - F1(G, H, A, B, C, D, E, F, W[10], 0x243185BE4EE4B28C); - F1(F, G, H, A, B, C, D, E, W[11], 0x550C7DC3D5FFB4E2); - F1(E, F, G, H, A, B, C, D, W[12], 0x72BE5D74F27B896F); - F1(D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE3B1696B1); - F1(C, D, E, F, G, H, A, B, W[14], 0x9BDC06A725C71235); - F1(B, C, D, E, F, G, H, A, W[15], 0xC19BF174CF692694); - F1(A, B, C, D, E, F, G, H, W[16], 0xE49B69C19EF14AD2); - F1(H, A, B, C, D, E, F, G, W[17], 0xEFBE4786384F25E3); - F1(G, H, A, B, C, D, E, F, W[18], 0x0FC19DC68B8CD5B5); - F1(F, G, H, A, B, C, D, E, W[19], 0x240CA1CC77AC9C65); - F1(E, F, G, H, A, B, C, D, W[20], 0x2DE92C6F592B0275); - F1(D, E, F, G, H, A, B, C, W[21], 0x4A7484AA6EA6E483); - F1(C, D, E, F, G, H, A, B, W[22], 0x5CB0A9DCBD41FBD4); - F1(B, C, D, E, F, G, H, A, W[23], 0x76F988DA831153B5); - F1(A, B, C, D, E, F, G, H, W[24], 0x983E5152EE66DFAB); - F1(H, A, B, C, D, E, F, G, W[25], 0xA831C66D2DB43210); - F1(G, H, A, B, C, D, E, F, W[26], 0xB00327C898FB213F); - F1(F, G, H, A, B, C, D, E, W[27], 0xBF597FC7BEEF0EE4); - F1(E, F, G, H, A, B, C, D, W[28], 0xC6E00BF33DA88FC2); - F1(D, E, F, G, H, A, B, C, W[29], 0xD5A79147930AA725); - F1(C, D, E, F, G, H, A, B, W[30], 0x06CA6351E003826F); - F1(B, C, D, E, F, G, H, A, W[31], 0x142929670A0E6E70); - F1(A, B, C, D, E, F, G, H, W[32], 0x27B70A8546D22FFC); - F1(H, A, B, C, D, E, F, G, W[33], 0x2E1B21385C26C926); - F1(G, H, A, B, C, D, E, F, W[34], 0x4D2C6DFC5AC42AED); - F1(F, G, H, A, B, C, D, E, W[35], 0x53380D139D95B3DF); - F1(E, F, G, H, A, B, C, D, W[36], 0x650A73548BAF63DE); - F1(D, E, F, G, H, A, B, C, W[37], 0x766A0ABB3C77B2A8); - F1(C, D, E, F, G, H, A, B, W[38], 0x81C2C92E47EDAEE6); - F1(B, C, D, E, F, G, H, A, W[39], 0x92722C851482353B); - F1(A, B, C, D, E, F, G, H, W[40], 0xA2BFE8A14CF10364); - F1(H, A, B, C, D, E, F, G, W[41], 0xA81A664BBC423001); - F1(G, H, A, B, C, D, E, F, W[42], 0xC24B8B70D0F89791); - F1(F, G, H, A, B, C, D, E, W[43], 0xC76C51A30654BE30); - F1(E, F, G, H, A, B, C, D, W[44], 0xD192E819D6EF5218); - F1(D, E, F, G, H, A, B, C, W[45], 0xD69906245565A910); - F1(C, D, E, F, G, H, A, B, W[46], 0xF40E35855771202A); - F1(B, C, D, E, F, G, H, A, W[47], 0x106AA07032BBD1B8); - F1(A, B, C, D, E, F, G, H, W[48], 0x19A4C116B8D2D0C8); - F1(H, A, B, C, D, E, F, G, W[49], 0x1E376C085141AB53); - F1(G, H, A, B, C, D, E, F, W[50], 0x2748774CDF8EEB99); - F1(F, G, H, A, B, C, D, E, W[51], 0x34B0BCB5E19B48A8); - F1(E, F, G, H, A, B, C, D, W[52], 0x391C0CB3C5C95A63); - F1(D, E, F, G, H, A, B, C, W[53], 0x4ED8AA4AE3418ACB); - F1(C, D, E, F, G, H, A, B, W[54], 0x5B9CCA4F7763E373); - F1(B, C, D, E, F, G, H, A, W[55], 0x682E6FF3D6B2B8A3); - F1(A, B, C, D, E, F, G, H, W[56], 0x748F82EE5DEFB2FC); - F1(H, A, B, C, D, E, F, G, W[57], 0x78A5636F43172F60); - F1(G, H, A, B, C, D, E, F, W[58], 0x84C87814A1F0AB72); - F1(F, G, H, A, B, C, D, E, W[59], 0x8CC702081A6439EC); - F1(E, F, G, H, A, B, C, D, W[60], 0x90BEFFFA23631E28); - F1(D, E, F, G, H, A, B, C, W[61], 0xA4506CEBDE82BDE9); - F1(C, D, E, F, G, H, A, B, W[62], 0xBEF9A3F7B2C67915); - F1(B, C, D, E, F, G, H, A, W[63], 0xC67178F2E372532B); - F1(A, B, C, D, E, F, G, H, W[64], 0xCA273ECEEA26619C); - F1(H, A, B, C, D, E, F, G, W[65], 0xD186B8C721C0C207); - F1(G, H, A, B, C, D, E, F, W[66], 0xEADA7DD6CDE0EB1E); - F1(F, G, H, A, B, C, D, E, W[67], 0xF57D4F7FEE6ED178); - F1(E, F, G, H, A, B, C, D, W[68], 0x06F067AA72176FBA); - F1(D, E, F, G, H, A, B, C, W[69], 0x0A637DC5A2C898A6); - F1(C, D, E, F, G, H, A, B, W[70], 0x113F9804BEF90DAE); - F1(B, C, D, E, F, G, H, A, W[71], 0x1B710B35131C471B); - F1(A, B, C, D, E, F, G, H, W[72], 0x28DB77F523047D84); - F1(H, A, B, C, D, E, F, G, W[73], 0x32CAAB7B40C72493); - F1(G, H, A, B, C, D, E, F, W[74], 0x3C9EBE0A15C9BEBC); - F1(F, G, H, A, B, C, D, E, W[75], 0x431D67C49C100D4C); - F1(E, F, G, H, A, B, C, D, W[76], 0x4CC5D4BECB3E42B6); - F1(D, E, F, G, H, A, B, C, W[77], 0x597F299CFC657E2A); - F1(C, D, E, F, G, H, A, B, W[78], 0x5FCB6FAB3AD6FAEC); - F1(B, C, D, E, F, G, H, A, W[79], 0x6C44198C4A475817); + u64bit W00 = load_be<u64bit>(input, 0); + u64bit W01 = load_be<u64bit>(input, 1); + u64bit W02 = load_be<u64bit>(input, 2); + u64bit W03 = load_be<u64bit>(input, 3); + u64bit W04 = load_be<u64bit>(input, 4); + u64bit W05 = load_be<u64bit>(input, 5); + u64bit W06 = load_be<u64bit>(input, 6); + u64bit W07 = load_be<u64bit>(input, 7); + u64bit W08 = load_be<u64bit>(input, 8); + u64bit W09 = load_be<u64bit>(input, 9); + u64bit W10 = load_be<u64bit>(input, 10); + u64bit W11 = load_be<u64bit>(input, 11); + u64bit W12 = load_be<u64bit>(input, 12); + u64bit W13 = load_be<u64bit>(input, 13); + u64bit W14 = load_be<u64bit>(input, 14); + u64bit W15 = load_be<u64bit>(input, 15); + + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x428A2F98D728AE22); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x7137449123EF65CD); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xB5C0FBCFEC4D3B2F); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xE9B5DBA58189DBBC); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x3956C25BF348B538); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x59F111F1B605D019); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x923F82A4AF194F9B); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0xAB1C5ED5DA6D8118); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xD807AA98A3030242); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x12835B0145706FBE); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x243185BE4EE4B28C); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x550C7DC3D5FFB4E2); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x72BE5D74F27B896F); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x80DEB1FE3B1696B1); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x9BDC06A725C71235); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC19BF174CF692694); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xE49B69C19EF14AD2); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xEFBE4786384F25E3); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x0FC19DC68B8CD5B5); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x240CA1CC77AC9C65); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x2DE92C6F592B0275); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4A7484AA6EA6E483); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5CB0A9DCBD41FBD4); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x76F988DA831153B5); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x983E5152EE66DFAB); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA831C66D2DB43210); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xB00327C898FB213F); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xBF597FC7BEEF0EE4); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xC6E00BF33DA88FC2); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD5A79147930AA725); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x06CA6351E003826F); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x142929670A0E6E70); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x27B70A8546D22FFC); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x2E1B21385C26C926); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x4D2C6DFC5AC42AED); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x53380D139D95B3DF); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x650A73548BAF63DE); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x766A0ABB3C77B2A8); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x81C2C92E47EDAEE6); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x92722C851482353B); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0xA2BFE8A14CF10364); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0xA81A664BBC423001); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0xC24B8B70D0F89791); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0xC76C51A30654BE30); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0xD192E819D6EF5218); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xD69906245565A910); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xF40E35855771202A); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x106AA07032BBD1B8); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0x19A4C116B8D2D0C8); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0x1E376C085141AB53); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0x2748774CDF8EEB99); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0x34B0BCB5E19B48A8); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x391C0CB3C5C95A63); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x4ED8AA4AE3418ACB); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x5B9CCA4F7763E373); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x682E6FF3D6B2B8A3); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x748F82EE5DEFB2FC); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x78A5636F43172F60); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x84C87814A1F0AB72); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x8CC702081A6439EC); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x90BEFFFA23631E28); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0xA4506CEBDE82BDE9); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0xBEF9A3F7B2C67915); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0xC67178F2E372532B); + SHA2_64_F(A, B, C, D, E, F, G, H, W00, W14, W09, W01, 0xCA273ECEEA26619C); + SHA2_64_F(H, A, B, C, D, E, F, G, W01, W15, W10, W02, 0xD186B8C721C0C207); + SHA2_64_F(G, H, A, B, C, D, E, F, W02, W00, W11, W03, 0xEADA7DD6CDE0EB1E); + SHA2_64_F(F, G, H, A, B, C, D, E, W03, W01, W12, W04, 0xF57D4F7FEE6ED178); + SHA2_64_F(E, F, G, H, A, B, C, D, W04, W02, W13, W05, 0x06F067AA72176FBA); + SHA2_64_F(D, E, F, G, H, A, B, C, W05, W03, W14, W06, 0x0A637DC5A2C898A6); + SHA2_64_F(C, D, E, F, G, H, A, B, W06, W04, W15, W07, 0x113F9804BEF90DAE); + SHA2_64_F(B, C, D, E, F, G, H, A, W07, W05, W00, W08, 0x1B710B35131C471B); + SHA2_64_F(A, B, C, D, E, F, G, H, W08, W06, W01, W09, 0x28DB77F523047D84); + SHA2_64_F(H, A, B, C, D, E, F, G, W09, W07, W02, W10, 0x32CAAB7B40C72493); + SHA2_64_F(G, H, A, B, C, D, E, F, W10, W08, W03, W11, 0x3C9EBE0A15C9BEBC); + SHA2_64_F(F, G, H, A, B, C, D, E, W11, W09, W04, W12, 0x431D67C49C100D4C); + SHA2_64_F(E, F, G, H, A, B, C, D, W12, W10, W05, W13, 0x4CC5D4BECB3E42B6); + SHA2_64_F(D, E, F, G, H, A, B, C, W13, W11, W06, W14, 0x597F299CFC657E2A); + SHA2_64_F(C, D, E, F, G, H, A, B, W14, W12, W07, W15, 0x5FCB6FAB3AD6FAEC); + SHA2_64_F(B, C, D, E, F, G, H, A, W15, W13, W08, W00, 0x6C44198C4A475817); A = (digest[0] += A); B = (digest[1] += B); @@ -165,12 +171,14 @@ void sha2_64_compress(MemoryRegion<u64bit>& W, } +} + /* * SHA-384 compression function */ void SHA_384::compress_n(const byte input[], size_t blocks) { - sha2_64_compress(W, digest, input, blocks); + SHA2_64::compress(digest, input, blocks); } /* @@ -188,7 +196,6 @@ void SHA_384::copy_out(byte output[]) void SHA_384::clear() { MDx_HashFunction::clear(); - zeroise(W); digest[0] = 0xCBBB9D5DC1059ED8; digest[1] = 0x629A292A367CD507; digest[2] = 0x9159015A3070DD17; @@ -204,7 +211,7 @@ void SHA_384::clear() */ void SHA_512::compress_n(const byte input[], size_t blocks) { - sha2_64_compress(W, digest, input, blocks); + SHA2_64::compress(digest, input, blocks); } /* @@ -222,7 +229,6 @@ void SHA_512::copy_out(byte output[]) void SHA_512::clear() { MDx_HashFunction::clear(); - zeroise(W); digest[0] = 0x6A09E667F3BCC908; digest[1] = 0xBB67AE8584CAA73B; digest[2] = 0x3C6EF372FE94F82B; diff --git a/src/hash/sha2_64/sha2_64.h b/src/hash/sha2_64/sha2_64.h index dcfb7224c..124d4bbfb 100644 --- a/src/hash/sha2_64/sha2_64.h +++ b/src/hash/sha2_64/sha2_64.h @@ -24,13 +24,13 @@ class BOTAN_DLL SHA_384 : public MDx_HashFunction void clear(); - SHA_384() : MDx_HashFunction(128, true, true, 16), W(80), digest(8) + SHA_384() : MDx_HashFunction(128, true, true, 16), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - SecureVector<u64bit> W, digest; + SecureVector<u64bit> digest; }; /** @@ -45,13 +45,13 @@ class BOTAN_DLL SHA_512 : public MDx_HashFunction void clear(); - SHA_512() : MDx_HashFunction(128, true, true, 16), W(80), digest(8) + SHA_512() : MDx_HashFunction(128, true, true, 16), digest(8) { clear(); } private: void compress_n(const byte[], size_t blocks); void copy_out(byte[]); - SecureVector<u64bit> W, digest; + SecureVector<u64bit> digest; }; } diff --git a/src/hash/skein/skein_512.cpp b/src/hash/skein/skein_512.cpp index 92acf0814..b5f7677db 100644 --- a/src/hash/skein/skein_512.cpp +++ b/src/hash/skein/skein_512.cpp @@ -43,7 +43,7 @@ void ubi_512(MemoryRegion<u64bit>& H, if(to_proc % 8) { for(size_t j = 0; j != to_proc % 8; ++j) - M[to_proc/8] |= ((u64bit)msg[8*(to_proc/8)+j] << (8*j)); + M[to_proc/8] |= static_cast<u64bit>(msg[8*(to_proc/8)+j]) << (8*j); } H[8] = H[0] ^ H[1] ^ H[2] ^ H[3] ^ @@ -117,7 +117,8 @@ void ubi_512(MemoryRegion<u64bit>& H, H[6] = X6 ^ M[6]; H[7] = X7 ^ M[7]; - T[1] &= ~((u64bit)1 << 62); // clear first flag if set + // clear first flag if set + T[1] &= ~(static_cast<u64bit>(1) << 62); msg_len -= to_proc; msg += to_proc; @@ -128,7 +129,10 @@ void reset_tweak(MemoryRegion<u64bit>& T, type_code type, bool final) { T[0] = 0; - T[1] = ((u64bit)type << 56) | ((u64bit)1 << 62) | ((u64bit)final << 63); + + T[1] = (static_cast<u64bit>(type) << 56) | + (static_cast<u64bit>(1) << 62) | + (static_cast<u64bit>(final) << 63); } void initial_block(MemoryRegion<u64bit>& H, @@ -227,7 +231,7 @@ void Skein_512::add_data(const byte input[], size_t length) void Skein_512::final_result(byte out[]) { - T[1] |= ((u64bit)1 << 63); // final block flag + T[1] |= (static_cast<u64bit>(1) << 63); // final block flag for(size_t i = buf_pos; i != buffer.size(); ++i) buffer[i] = 0; diff --git a/src/kdf/ssl_prf/info.txt b/src/kdf/prf_ssl3/info.txt index 0ef297119..0ef297119 100644 --- a/src/kdf/ssl_prf/info.txt +++ b/src/kdf/prf_ssl3/info.txt diff --git a/src/kdf/ssl_prf/prf_ssl3.cpp b/src/kdf/prf_ssl3/prf_ssl3.cpp index 72cf023e2..72cf023e2 100644 --- a/src/kdf/ssl_prf/prf_ssl3.cpp +++ b/src/kdf/prf_ssl3/prf_ssl3.cpp diff --git a/src/kdf/ssl_prf/prf_ssl3.h b/src/kdf/prf_ssl3/prf_ssl3.h index b07454be2..b07454be2 100644 --- a/src/kdf/ssl_prf/prf_ssl3.h +++ b/src/kdf/prf_ssl3/prf_ssl3.h diff --git a/src/kdf/tls_prf/info.txt b/src/kdf/prf_tls/info.txt index 9531a6a83..9531a6a83 100644 --- a/src/kdf/tls_prf/info.txt +++ b/src/kdf/prf_tls/info.txt diff --git a/src/kdf/tls_prf/prf_tls.cpp b/src/kdf/prf_tls/prf_tls.cpp index 2b57cdd25..2b57cdd25 100644 --- a/src/kdf/tls_prf/prf_tls.cpp +++ b/src/kdf/prf_tls/prf_tls.cpp diff --git a/src/kdf/tls_prf/prf_tls.h b/src/kdf/prf_tls/prf_tls.h index 5237f17c0..5237f17c0 100644 --- a/src/kdf/tls_prf/prf_tls.h +++ b/src/kdf/prf_tls/prf_tls.h diff --git a/src/kdf/x942_prf/info.txt b/src/kdf/prf_x942/info.txt index e51aafd08..e51aafd08 100644 --- a/src/kdf/x942_prf/info.txt +++ b/src/kdf/prf_x942/info.txt diff --git a/src/kdf/x942_prf/prf_x942.cpp b/src/kdf/prf_x942/prf_x942.cpp index fc31effe4..fc31effe4 100644 --- a/src/kdf/x942_prf/prf_x942.cpp +++ b/src/kdf/prf_x942/prf_x942.cpp diff --git a/src/kdf/x942_prf/prf_x942.h b/src/kdf/prf_x942/prf_x942.h index e6093eda6..e6093eda6 100644 --- a/src/kdf/x942_prf/prf_x942.h +++ b/src/kdf/prf_x942/prf_x942.h diff --git a/src/libstate/lookup.cpp b/src/libstate/lookup.cpp index 24a46e3e9..0d3f33573 100644 --- a/src/libstate/lookup.cpp +++ b/src/libstate/lookup.cpp @@ -62,6 +62,63 @@ size_t output_length_of(const std::string& name) } /* +* Query the minimum allowed key length of an algorithm implementation +*/ +size_t min_keylength_of(const std::string& name) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + + if(const BlockCipher* bc = af.prototype_block_cipher(name)) + return bc->key_spec().minimum_keylength(); + + if(const StreamCipher* sc = af.prototype_stream_cipher(name)) + return sc->key_spec().minimum_keylength(); + + if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) + return mac->key_spec().minimum_keylength(); + + throw Algorithm_Not_Found(name); + } + +/* +* Query the maximum allowed keylength of an algorithm implementation +*/ +size_t max_keylength_of(const std::string& name) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + + if(const BlockCipher* bc = af.prototype_block_cipher(name)) + return bc->key_spec().maximum_keylength(); + + if(const StreamCipher* sc = af.prototype_stream_cipher(name)) + return sc->key_spec().maximum_keylength(); + + if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) + return mac->key_spec().maximum_keylength(); + + throw Algorithm_Not_Found(name); + } + +/* +* Query the number of byte a valid key must be a multiple of +*/ +size_t keylength_multiple_of(const std::string& name) + { + Algorithm_Factory& af = global_state().algorithm_factory(); + + if(const BlockCipher* bc = af.prototype_block_cipher(name)) + return bc->key_spec().keylength_multiple(); + + if(const StreamCipher* sc = af.prototype_stream_cipher(name)) + return sc->key_spec().keylength_multiple(); + + if(const MessageAuthenticationCode* mac = af.prototype_mac(name)) + return mac->key_spec().keylength_multiple(); + + throw Algorithm_Not_Found(name); + } + +/* * Get a cipher object */ Keyed_Filter* get_cipher(const std::string& algo_spec, diff --git a/src/libstate/lookup.h b/src/libstate/lookup.h index 02c1708aa..e10c195b8 100644 --- a/src/libstate/lookup.h +++ b/src/libstate/lookup.h @@ -299,6 +299,36 @@ BOTAN_DLL size_t block_size_of(const std::string& algo_spec); */ BOTAN_DLL size_t output_length_of(const std::string& algo_spec); +/** +* Find out the minimum key size of a certain symmetric algorithm. +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return minimum key length of the specified algorithm +*/ +BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") +BOTAN_DLL size_t min_keylength_of(const std::string& algo_spec); + +/** +* Find out the maximum key size of a certain symmetric algorithm. +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return maximum key length of the specified algorithm +*/ +BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") +BOTAN_DLL size_t max_keylength_of(const std::string& algo_spec); + +/** +* Find out the size any valid key is a multiple of for a certain algorithm. +* @deprecated Call algorithm_factory() directly +* +* @param algo_spec the name of the algorithm +* @return size any valid key is a multiple of +*/ +BOTAN_DEPRECATED("Retrieve object you want and then call key_spec") +BOTAN_DLL size_t keylength_multiple_of(const std::string& algo_spec); + } #endif diff --git a/src/math/bigint/bigint.cpp b/src/math/bigint/bigint.cpp index a49335e75..ae536813f 100644 --- a/src/math/bigint/bigint.cpp +++ b/src/math/bigint/bigint.cpp @@ -1,6 +1,6 @@ /* * BigInt Base -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -26,8 +26,8 @@ BigInt::BigInt(u64bit n) const size_t limbs_needed = sizeof(u64bit) / sizeof(word); reg.resize(4*limbs_needed); - for(size_t j = 0; j != limbs_needed; ++j) - reg[j] = ((n >> (j*MP_WORD_BITS)) & MP_WORD_MASK); + for(size_t i = 0; i != limbs_needed; ++i) + reg[i] = ((n >> (i*MP_WORD_BITS)) & MP_WORD_MASK); } /* @@ -190,16 +190,35 @@ u32bit BigInt::get_substring(size_t offset, size_t length) const throw Invalid_Argument("BigInt::get_substring: Substring size too big"); u64bit piece = 0; - for(size_t j = 0; j != 8; ++j) - piece = (piece << 8) | byte_at((offset / 8) + (7-j)); + for(size_t i = 0; i != 8; ++i) + { + const byte part = byte_at((offset / 8) + (7-i)); + piece = (piece << 8) | part; + } - u64bit mask = (1 << length) - 1; - size_t shift = (offset % 8); + const u64bit mask = (static_cast<u64bit>(1) << length) - 1; + const size_t shift = (offset % 8); return static_cast<u32bit>((piece >> shift) & mask); } /* +* Convert this number to a u32bit, if possible +*/ +u32bit BigInt::to_u32bit() const + { + if(is_negative()) + throw Encoding_Error("BigInt::to_u32bit: Number is negative"); + if(bits() >= 32) + throw Encoding_Error("BigInt::to_u32bit: Number is too big to convert"); + + u32bit out = 0; + for(u32bit j = 0; j != 4; ++j) + out = (out << 8) | byte_at(3-j); + return out; + } + +/* * Set bit number n */ void BigInt::set_bit(size_t n) @@ -233,8 +252,8 @@ void BigInt::mask_bits(size_t n) const word mask = (static_cast<word>(1) << (n % MP_WORD_BITS)) - 1; if(top_word < size()) - for(size_t j = top_word + 1; j != size(); ++j) - reg[j] = 0; + for(size_t i = top_word + 1; i != size(); ++i) + reg[i] = 0; reg[top_word] &= mask; } @@ -340,8 +359,8 @@ BigInt BigInt::abs() const void BigInt::binary_encode(byte output[]) const { const size_t sig_bytes = bytes(); - for(size_t j = 0; j != sig_bytes; ++j) - output[sig_bytes-j-1] = byte_at(j); + for(size_t i = 0; i != sig_bytes; ++i) + output[sig_bytes-i-1] = byte_at(i); } /* @@ -354,14 +373,15 @@ void BigInt::binary_decode(const byte buf[], size_t length) clear(); reg.resize(round_up<size_t>((length / WORD_BYTES) + 1, 8)); - for(size_t j = 0; j != length / WORD_BYTES; ++j) + for(size_t i = 0; i != length / WORD_BYTES; ++i) { - size_t top = length - WORD_BYTES*j; - for(size_t k = WORD_BYTES; k > 0; --k) - reg[j] = (reg[j] << 8) | buf[top - k]; + const size_t top = length - WORD_BYTES*i; + for(size_t j = WORD_BYTES; j > 0; --j) + reg[i] = (reg[i] << 8) | buf[top - j]; } - for(size_t j = 0; j != length % WORD_BYTES; ++j) - reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[j]; + + for(size_t i = 0; i != length % WORD_BYTES; ++i) + reg[length / WORD_BYTES] = (reg[length / WORD_BYTES] << 8) | buf[i]; } /* diff --git a/src/math/bigint/bigint.h b/src/math/bigint/bigint.h index 5b3dcc2dd..06e3ecd2f 100644 --- a/src/math/bigint/bigint.h +++ b/src/math/bigint/bigint.h @@ -218,6 +218,13 @@ class BOTAN_DLL BigInt u32bit get_substring(size_t offset, size_t length) const; /** + * Convert this value into a u32bit, if it is in the range + * [0 ... 2**32-1], or otherwise throw an exception. + * @result the value as a u32bit if conversion is possible + */ + u32bit to_u32bit() const; + + /** * @param n the offset to get a byte from * @result byte at offset n */ diff --git a/src/math/numbertheory/curve_gfp.h b/src/math/ec_gfp/curve_gfp.h index 1ab803ec9..9867f82fe 100644 --- a/src/math/numbertheory/curve_gfp.h +++ b/src/math/ec_gfp/curve_gfp.h @@ -2,7 +2,7 @@ * Elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2010 Jack Lloyd +* 2010-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -11,7 +11,6 @@ #define BOTAN_GFP_CURVE_H__ #include <botan/numthry.h> -#include <botan/reducer.h> namespace Botan { @@ -34,18 +33,15 @@ class BOTAN_DLL CurveGFp * @param b second coefficient */ CurveGFp(const BigInt& p, const BigInt& a, const BigInt& b) : - p(p), a(a), b(b), reducer_p(p) + p(p), a(a), b(b), p_words(p.sig_words()) { - r = 1; - r <<= p.sig_words() * BOTAN_MP_WORD_BITS; + BigInt r(BigInt::Power2, p_words * BOTAN_MP_WORD_BITS); - r_inv = inverse_mod(r, p); + p_dash = (((r * inverse_mod(r, p)) - 1) / p).word_at(0); - p_dash = (((r * r_inv) - 1) / p).word_at(0); - - a_r = reducer_p.multiply(a, r); - - p_words = p.sig_words(); + r2 = (r * r) % p; + a_r = (a * r) % p; + b_r = (b * r) % p; } // CurveGFp(const CurveGFp& other) = default; @@ -68,19 +64,19 @@ class BOTAN_DLL CurveGFp const BigInt& get_p() const { return p; } /** - * @return Montgomery parameter r + * @return Montgomery parameter r^2 % p */ - const BigInt& get_r() const { return r; } + const BigInt& get_r2() const { return r2; } /** - * @return Montgomery parameter r^-1 + * @return a * r mod p */ - const BigInt& get_r_inv() const { return r_inv; } + const BigInt& get_a_r() const { return a_r; } /** - * @return a * r mod p + * @return b * r mod p */ - const BigInt& get_a_r() const { return a_r; } + const BigInt& get_b_r() const { return b_r; } /** * @return Montgomery parameter p-dash @@ -93,23 +89,22 @@ class BOTAN_DLL CurveGFp size_t get_p_words() const { return p_words; } /** - * @return modular reducer for p - */ - const Modular_Reducer& mod_p() const { return reducer_p; } - - /** * swaps the states of *this and other, does not throw * @param other curve to swap values with */ void swap(CurveGFp& other) { + std::swap(p, other.p); + std::swap(a, other.a); std::swap(b, other.b); - std::swap(p, other.p); - std::swap(reducer_p, other.reducer_p); - std::swap(r, other.r); - std::swap(r_inv, other.r_inv); + std::swap(a_r, other.a_r); + std::swap(b_r, other.b_r); + + std::swap(p_words, other.p_words); + + std::swap(r2, other.r2); std::swap(p_dash, other.p_dash); } @@ -120,7 +115,11 @@ class BOTAN_DLL CurveGFp */ bool operator==(const CurveGFp& other) const { - return (p == other.p && a == other.a && b == other.b); + /* + Relies on choice of R, but that is fixed by constructor based + on size of p + */ + return (p == other.p && a_r == other.a_r && b_r == other.b_r); } private: @@ -130,10 +129,8 @@ class BOTAN_DLL CurveGFp size_t p_words; // cache of p.sig_words() // Montgomery parameters - BigInt r, r_inv, a_r; + BigInt r2, a_r, b_r; word p_dash; - - Modular_Reducer reducer_p; }; /** diff --git a/src/math/ec_gfp/info.txt b/src/math/ec_gfp/info.txt new file mode 100644 index 000000000..e6ee1d6bf --- /dev/null +++ b/src/math/ec_gfp/info.txt @@ -0,0 +1,16 @@ +define EC_CURVE_GFP + +load_on auto + +<header:public> +curve_gfp.h +point_gfp.h +</header:public> + +<source> +point_gfp.cpp +</source> + +<requires> +numbertheory +</requires> diff --git a/src/math/numbertheory/point_gfp.cpp b/src/math/ec_gfp/point_gfp.cpp index fab731d29..7ac6b4141 100644 --- a/src/math/numbertheory/point_gfp.cpp +++ b/src/math/ec_gfp/point_gfp.cpp @@ -1,40 +1,37 @@ /* -* Arithmetic for point groups of elliptic curves over GF(p) +* Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2010 Jack Lloyd +* 2008-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ #include <botan/point_gfp.h> #include <botan/numthry.h> +#include <botan/reducer.h> #include <botan/internal/mp_core.h> namespace Botan { PointGFp::PointGFp(const CurveGFp& curve) : - curve(curve), - coord_x(0), - coord_y(curve.get_r()), - coord_z(0) + curve(curve), ws(2 * (curve.get_p_words() + 2)) { + coord_x = 0; + coord_y = monty_mult(1, curve.get_r2()); + coord_z = 0; } PointGFp::PointGFp(const CurveGFp& curve, const BigInt& x, const BigInt& y) : - curve(curve) + curve(curve), ws(2 * (curve.get_p_words() + 2)) { - const Modular_Reducer& mod_p = curve.mod_p(); - - coord_x = mod_p.multiply(curve.get_r(), x); - coord_y = mod_p.multiply(curve.get_r(), y); - coord_z = mod_p.reduce(curve.get_r()); + coord_x = monty_mult(x, curve.get_r2()); + coord_y = monty_mult(y, curve.get_r2()); + coord_z = monty_mult(1, curve.get_r2()); } // Montgomery multiplication -void PointGFp::monty_mult(BigInt& z, - const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const +void PointGFp::monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const { //assert(&z != &x && &z != &y); @@ -52,19 +49,15 @@ void PointGFp::monty_mult(BigInt& z, z_reg.resize(2*p_size+1); zeroise(z_reg); - bigint_mul(&z_reg[0], z_reg.size(), - &workspace[0], - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - p.data(), p_size, p_dash); + bigint_monty_mul(&z_reg[0], z_reg.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + p.data(), p_size, p_dash, + &ws[0]); } // Montgomery squaring -void PointGFp::monty_sqr(BigInt& z, const BigInt& x, - MemoryRegion<word>& workspace) const +void PointGFp::monty_sqr(BigInt& z, const BigInt& x) const { //assert(&z != &x); @@ -82,17 +75,14 @@ void PointGFp::monty_sqr(BigInt& z, const BigInt& x, z_reg.resize(2*p_size+1); zeroise(z_reg); - bigint_sqr(&z[0], z.size(), - &workspace[0], - x.data(), x.size(), x.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - p.data(), p_size, p_dash); + bigint_monty_sqr(&z_reg[0], z_reg.size(), + x.data(), x.size(), x.sig_words(), + p.data(), p_size, p_dash, + &ws[0]); } // Point addition -void PointGFp::add(const PointGFp& rhs, Workspace& workspace) +void PointGFp::add(const PointGFp& rhs, std::vector<BigInt>& ws_bn) { if(is_zero()) { @@ -106,9 +96,6 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) const BigInt& p = curve.get_p(); - MemoryRegion<word>& ws = workspace.ws_monty; - std::vector<BigInt>& ws_bn = workspace.ws_bn; - BigInt& rhs_z2 = ws_bn[0]; BigInt& U1 = ws_bn[1]; BigInt& S1 = ws_bn[2]; @@ -120,17 +107,13 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) BigInt& H = ws_bn[6]; BigInt& r = ws_bn[7]; - BigInt& x = ws_bn[8]; - BigInt& y = ws_bn[9]; - BigInt& z = ws_bn[10]; + monty_sqr(rhs_z2, rhs.coord_z); + monty_mult(U1, coord_x, rhs_z2); + monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2)); - monty_sqr(rhs_z2, rhs.coord_z, ws); - monty_mult(U1, coord_x, rhs_z2, ws); - monty_mult(S1, coord_y, monty_mult(rhs.coord_z, rhs_z2, ws), ws); - - monty_sqr(lhs_z2, coord_z, ws); - monty_mult(U2, rhs.coord_x, lhs_z2, ws); - monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2, ws), ws); + monty_sqr(lhs_z2, coord_z); + monty_mult(U2, rhs.coord_x, lhs_z2); + monty_mult(S2, rhs.coord_y, monty_mult(coord_z, lhs_z2)); H = U2; H -= U1; @@ -146,7 +129,7 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) { if(r.is_zero()) { - mult2(workspace); + mult2(ws_bn); return; } @@ -154,36 +137,32 @@ void PointGFp::add(const PointGFp& rhs, Workspace& workspace) return; } - monty_sqr(U2, H, ws); + monty_sqr(U2, H); - monty_mult(S2, U2, H, ws); + monty_mult(S2, U2, H); - U2 = monty_mult(U1, U2, ws); + U2 = monty_mult(U1, U2); - monty_sqr(x, r, ws); - x -= S2; - x -= (U2 << 1); - while(x.is_negative()) - x += p; + monty_sqr(coord_x, r); + coord_x -= S2; + coord_x -= (U2 << 1); + while(coord_x.is_negative()) + coord_x += p; - U2 -= x; + U2 -= coord_x; if(U2.is_negative()) U2 += p; - monty_mult(y, r, U2, ws); - y -= monty_mult(S1, S2, ws); - if(y.is_negative()) - y += p; - - monty_mult(z, monty_mult(coord_z, rhs.coord_z, ws), H, ws); + monty_mult(coord_y, r, U2); + coord_y -= monty_mult(S1, S2); + if(coord_y.is_negative()) + coord_y += p; - coord_x = x; - coord_y = y; - coord_z = z; + monty_mult(coord_z, monty_mult(coord_z, rhs.coord_z), H); } // *this *= 2 -void PointGFp::mult2(Workspace& workspace) +void PointGFp::mult2(std::vector<BigInt>& ws_bn) { if(is_zero()) return; @@ -195,9 +174,6 @@ void PointGFp::mult2(Workspace& workspace) const BigInt& p = curve.get_p(); - MemoryRegion<word>& ws = workspace.ws_monty; - std::vector<BigInt>& ws_bn = workspace.ws_bn; - BigInt& y_2 = ws_bn[0]; BigInt& S = ws_bn[1]; BigInt& z4 = ws_bn[2]; @@ -208,27 +184,27 @@ void PointGFp::mult2(Workspace& workspace) BigInt& y = ws_bn[7]; BigInt& z = ws_bn[8]; - monty_sqr(y_2, coord_y, ws); + monty_sqr(y_2, coord_y); - monty_mult(S, coord_x, y_2, ws); + monty_mult(S, coord_x, y_2); S <<= 2; // * 4 while(S >= p) S -= p; - monty_sqr(z4, monty_sqr(coord_z, ws), ws); - monty_mult(a_z4, curve.get_a_r(), z4, ws); + monty_sqr(z4, monty_sqr(coord_z)); + monty_mult(a_z4, curve.get_a_r(), z4); - M = 3 * monty_sqr(coord_x, ws); + M = 3 * monty_sqr(coord_x); M += a_z4; while(M >= p) M -= p; - monty_sqr(x, M, ws); + monty_sqr(x, M); x -= (S << 1); while(x.is_negative()) x += p; - monty_sqr(U, y_2, ws); + monty_sqr(U, y_2); U <<= 3; while(U >= p) U -= p; @@ -237,12 +213,12 @@ void PointGFp::mult2(Workspace& workspace) while(S.is_negative()) S += p; - monty_mult(y, M, S, ws); + monty_mult(y, M, S); y -= U; if(y.is_negative()) y += p; - monty_mult(z, coord_y, coord_z, ws); + monty_mult(z, coord_y, coord_z); z <<= 1; if(z >= p) z -= p; @@ -255,7 +231,7 @@ void PointGFp::mult2(Workspace& workspace) // arithmetic operators PointGFp& PointGFp::operator+=(const PointGFp& rhs) { - Workspace ws(curve.get_p_words()); + std::vector<BigInt> ws(9); add(rhs, ws); return *this; } @@ -278,6 +254,39 @@ PointGFp& PointGFp::operator*=(const BigInt& scalar) return *this; } +PointGFp multi_exponentiate(const PointGFp& p1, const BigInt& z1, + const PointGFp& p2, const BigInt& z2) + { + const PointGFp p3 = p1 + p2; + + PointGFp H(p1.curve); // create as zero + size_t bits_left = std::max(z1.bits(), z2.bits()); + + std::vector<BigInt> ws(9); + + while(bits_left) + { + H.mult2(ws); + + const bool z1_b = z1.get_bit(bits_left - 1); + const bool z2_b = z2.get_bit(bits_left - 1); + + if(z1_b == true && z2_b == true) + H.add(p3, ws); + else if(z1_b) + H.add(p1, ws); + else if(z2_b) + H.add(p2, ws); + + --bits_left; + } + + if(z1.is_negative() != z2.is_negative()) + H.negate(); + + return H; + } + PointGFp operator*(const BigInt& scalar, const PointGFp& point) { const CurveGFp& curve = point.get_curve(); @@ -285,7 +294,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) if(scalar.is_zero()) return PointGFp(curve); // zero point - PointGFp::Workspace ws(curve.get_p_words()); + std::vector<BigInt> ws(9); if(scalar.abs() <= 2) // special cases for small values { @@ -304,6 +313,38 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) const size_t scalar_bits = scalar.bits(); +#if 0 + + PointGFp x1 = PointGFp(curve); + PointGFp x2 = point; + + size_t bits_left = scalar_bits; + + // Montgomery Ladder + while(bits_left) + { + const bool bit_set = scalar.get_bit(bits_left - 1); + + if(bit_set) + { + x1.add(x2, ws); + x2.mult2(ws); + } + else + { + x2.add(x1, ws); + x1.mult2(ws); + } + + --bits_left; + } + + if(scalar.is_negative()) + x1.negate(); + + return x1; + +#else const size_t window_size = 4; std::vector<PointGFp> Ps(1 << window_size); @@ -345,6 +386,7 @@ PointGFp operator*(const BigInt& scalar, const PointGFp& point) H.negate(); return H; +#endif } BigInt PointGFp::get_affine_x() const @@ -352,23 +394,13 @@ BigInt PointGFp::get_affine_x() const if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - const Modular_Reducer& mod_p = curve.mod_p(); - -#if 1 - BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); - - BigInt z2 = mod_p.square(z); - return mod_p.multiply(x, inverse_mod(z2, curve.get_p())); -#else - - SecureVector<word> ws(2 * (curve.get_p_words() + 2)); + const BigInt& r2 = curve.get_r2(); - BigInt z2 = monty_sqr(coord_z, ws); + BigInt z2 = monty_sqr(coord_z); z2 = inverse_mod(z2, curve.get_p()); - z2 = mod_p.multiply(z2, curve.get_r()); - return monty_mult(coord_x, z2, ws); -#endif + + z2 = monty_mult(z2, r2); + return monty_mult(coord_x, z2); } BigInt PointGFp::get_affine_y() const @@ -376,23 +408,12 @@ BigInt PointGFp::get_affine_y() const if(is_zero()) throw Illegal_Transformation("Cannot convert zero point to affine"); - const Modular_Reducer& mod_p = curve.mod_p(); + const BigInt& r2 = curve.get_r2(); -#if 1 - BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); - - BigInt z3 = mod_p.cube(z); - return mod_p.multiply(y, inverse_mod(z3, curve.get_p())); -#else - - SecureVector<word> ws(2 * (curve.get_p_words() + 2)); - - BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z, ws), ws); + BigInt z3 = monty_mult(coord_z, monty_sqr(coord_z)); z3 = inverse_mod(z3, curve.get_p()); - z3 = mod_p.multiply(z3, curve.get_r()); - return monty_mult(coord_y, z3, ws); -#endif + z3 = monty_mult(z3, r2); + return monty_mult(coord_y, z3); } bool PointGFp::on_the_curve() const @@ -407,31 +428,28 @@ bool PointGFp::on_the_curve() const if(is_zero()) return true; - const Modular_Reducer& mod_p = curve.mod_p(); + BigInt y2 = monty_mult(monty_sqr(coord_y), 1); + BigInt x3 = monty_mult(coord_x, monty_sqr(coord_x)); - BigInt x = mod_p.multiply(curve.get_r_inv(), coord_x); - BigInt y = mod_p.multiply(curve.get_r_inv(), coord_y); - BigInt z = mod_p.multiply(curve.get_r_inv(), coord_z); + BigInt ax = monty_mult(coord_x, curve.get_a_r()); - BigInt y2 = mod_p.square(y); - BigInt x3 = mod_p.cube(x); + const BigInt& b_r = curve.get_b_r(); - BigInt ax = mod_p.multiply(x, curve.get_a()); + BigInt z2 = monty_sqr(coord_z); - if(z == 1) + if(coord_z == z2) // Is z equal to 1 (in Montgomery form)? { - if(mod_p.reduce(x3 + ax + curve.get_b()) != y2) + if(y2 != monty_mult(x3 + ax + b_r, 1)) return false; } - BigInt z2 = mod_p.square(z); - BigInt z3 = mod_p.multiply(z, z2); + BigInt z3 = monty_mult(coord_z, z2); - BigInt ax_z4 = mod_p.multiply(mod_p.multiply(z3, z), ax); + BigInt ax_z4 = monty_mult(ax, monty_sqr(z2)); - BigInt b_z6 = mod_p.multiply(curve.get_b(), mod_p.square(z3)); + BigInt b_z6 = monty_mult(b_r, monty_sqr(z3)); - if(y2 != mod_p.reduce(x3 + ax_z4 + b_z6)) + if(y2 != monty_mult(x3 + ax_z4 + b_z6, 1)) return false; return true; @@ -444,6 +462,7 @@ void PointGFp::swap(PointGFp& other) coord_x.swap(other.coord_x); coord_y.swap(other.coord_y); coord_z.swap(other.coord_z); + ws.swap(other.ws); } bool PointGFp::operator==(const PointGFp& other) const diff --git a/src/math/numbertheory/point_gfp.h b/src/math/ec_gfp/point_gfp.h index 35ec6d503..b2b6fe2f0 100644 --- a/src/math/numbertheory/point_gfp.h +++ b/src/math/ec_gfp/point_gfp.h @@ -1,8 +1,8 @@ /* -* Arithmetic for point groups of elliptic curves over GF(p) +* Point arithmetic on elliptic curves over GF(p) * * (C) 2007 Martin Doering, Christoph Ludwig, Falko Strenzke -* 2008-2010 Jack Lloyd +* 2008-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -99,6 +99,18 @@ class BOTAN_DLL PointGFp friend BOTAN_DLL PointGFp operator*(const BigInt& scalar, const PointGFp& point); /** + * Multiexponentiation + * @param p1 a point + * @param z1 a scalar + * @param p2 a point + * @param z2 a scalar + * @result (p1 * z1 + p2 * z2) + */ + friend BOTAN_DLL PointGFp multi_exponentiate( + const PointGFp& p1, const BigInt& z1, + const PointGFp& p2, const BigInt& z2); + + /** * Negate this point * @return *this */ @@ -153,27 +165,16 @@ class BOTAN_DLL PointGFp bool operator==(const PointGFp& other) const; private: - class Workspace - { - public: - Workspace(size_t p_words) : - ws_monty(2*(p_words+2)), ws_bn(12) {} - - SecureVector<word> ws_monty; - std::vector<BigInt> ws_bn; - }; - /** * Montgomery multiplication/reduction * @param x first multiplicand * @param y second multiplicand * @param workspace temp space */ - BigInt monty_mult(const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const + BigInt monty_mult(const BigInt& x, const BigInt& y) const { BigInt result; - monty_mult(result, x, y, workspace); + monty_mult(result, x, y); return result; } @@ -183,22 +184,17 @@ class BOTAN_DLL PointGFp * @param z output * @param x first multiplicand * @param y second multiplicand - * @param workspace temp space */ - void monty_mult(BigInt& z, - const BigInt& x, const BigInt& y, - MemoryRegion<word>& workspace) const; + void monty_mult(BigInt& z, const BigInt& x, const BigInt& y) const; /** * Montgomery squaring/reduction * @param x multiplicand - * @param workspace temp space */ - BigInt monty_sqr(const BigInt& x, - MemoryRegion<word>& workspace) const + BigInt monty_sqr(const BigInt& x) const { BigInt result; - monty_sqr(result, x, workspace); + monty_sqr(result, x); return result; } @@ -207,24 +203,24 @@ class BOTAN_DLL PointGFp * @warning z cannot alias x * @param z output * @param x multiplicand - * @param workspace temp space */ - void monty_sqr(BigInt& z, const BigInt& x, - MemoryRegion<word>& workspace) const; + void monty_sqr(BigInt& z, const BigInt& x) const; /** * Point addition + * @param workspace temp space, at least 11 elements */ - void add(const PointGFp& other, Workspace& workspace); + void add(const PointGFp& other, std::vector<BigInt>& workspace); /** * Point doubling - * @param workspace temp space + * @param workspace temp space, at least 9 elements */ - void mult2(Workspace& workspace); + void mult2(std::vector<BigInt>& workspace); CurveGFp curve; BigInt coord_x, coord_y, coord_z; + mutable SecureVector<word> ws; // workspace for Montgomery }; // relational operators diff --git a/src/math/mp/info.txt b/src/math/mp/info.txt index a3c994d8b..bf7f40d3c 100644 --- a/src/math/mp/info.txt +++ b/src/math/mp/info.txt @@ -4,6 +4,8 @@ define BIGINT_MP mp_asm.cpp mp_comba.cpp mp_karat.cpp +mp_monty.cpp +mp_mulop.cpp mp_misc.cpp mp_shift.cpp </source> @@ -17,7 +19,5 @@ mp_core.h </header:internal> <requires> -mp_amd64|mp_msvc64|mp_asm64|mp_ia32|mp_ia32_msvc|mp_generic -monty_generic -mulop_generic +mp_x86_64|mp_msvc64|mp_asm64|mp_x86_32|mp_x86_32_msvc|mp_generic </requires> diff --git a/src/math/mp/monty_generic/info.txt b/src/math/mp/monty_generic/info.txt deleted file mode 100644 index cd05ccdc0..000000000 --- a/src/math/mp/monty_generic/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -load_on dep - -<source> -mp_monty.cpp -</source> diff --git a/src/math/mp/monty_generic/mp_monty.cpp b/src/math/mp/monty_generic/mp_monty.cpp deleted file mode 100644 index d7f7e0306..000000000 --- a/src/math/mp/monty_generic/mp_monty.cpp +++ /dev/null @@ -1,72 +0,0 @@ -/* -* Montgomery Reduction -* (C) 1999-2010 Jack Lloyd -* 2006 Luca Piccarreta -* -* Distributed under the terms of the Botan license -*/ - -#include <botan/internal/mp_core.h> -#include <botan/internal/mp_asm.h> -#include <botan/internal/mp_asmi.h> -#include <botan/mem_ops.h> - -namespace Botan { - -extern "C" { - -/* -* Montgomery Reduction Algorithm -*/ -void bigint_monty_redc(word z[], size_t z_size, - word ws[], - const word x[], size_t x_size, - word u) - { - const size_t blocks_of_8 = x_size - (x_size % 8); - - for(size_t i = 0; i != x_size; ++i) - { - word* z_i = z + i; - - const word y = z_i[0] * u; - - /* - bigint_linmul3(ws, x, x_size, y); - bigint_add2(z_i, z_size - i, ws, x_size+1); - */ - word carry = 0; - - for(size_t j = 0; j != blocks_of_8; j += 8) - carry = word8_madd3(z_i + j, x + j, y, carry); - - for(size_t j = blocks_of_8; j != x_size; ++j) - z_i[j] = word_madd3(x[j], y, z_i[j], &carry); - - word z_sum = z_i[x_size] + carry; - carry = (z_sum < z_i[x_size]); - z_i[x_size] = z_sum; - - // Note: not constant time - for(size_t j = x_size + 1; carry && j != z_size - i; ++j) - { - ++z_i[j]; - carry = !z_i[j]; - } - } - - word borrow = 0; - for(size_t i = 0; i != x_size; ++i) - ws[i] = word_sub(z[x_size + i], x[i], &borrow); - - ws[x_size] = word_sub(z[x_size+x_size], 0, &borrow); - - copy_mem(ws + x_size + 1, z + x_size, x_size + 1); - - copy_mem(z, ws + borrow*(x_size+1), x_size + 1); - clear_mem(z + x_size + 1, z_size - x_size - 1); - } - -} - -} diff --git a/src/math/mp/mp_asm.cpp b/src/math/mp/mp_asm.cpp index d164c1d33..3ba52c4b1 100644 --- a/src/math/mp/mp_asm.cpp +++ b/src/math/mp/mp_asm.cpp @@ -67,7 +67,8 @@ word bigint_add3_nc(word z[], const word x[], size_t x_size, */ void bigint_add2(word x[], size_t x_size, const word y[], size_t y_size) { - x[x_size] += bigint_add2_nc(x, x_size, y, y_size); + if(bigint_add2_nc(x, x_size, y, y_size)) + x[x_size] += 1; } /* diff --git a/src/math/mp/mp_asm64/info.txt b/src/math/mp/mp_asm64/info.txt index fd0242a7a..9af7c4ae7 100644 --- a/src/math/mp/mp_asm64/info.txt +++ b/src/math/mp/mp_asm64/info.txt @@ -8,7 +8,6 @@ mp_generic:mp_asmi.h </header:internal> <arch> -#amd64 alpha ia64 mips64 @@ -21,5 +20,5 @@ sparc64 # win, so it's probably worth using elsewhere. <cc> gcc -sunwspro +sunstudio </cc> diff --git a/src/math/mp/mp_core.h b/src/math/mp/mp_core.h index e1692006e..40327b02b 100644 --- a/src/math/mp/mp_core.h +++ b/src/math/mp/mp_core.h @@ -77,19 +77,35 @@ void bigint_simple_sqr(word z[], const word x[], size_t x_size); void bigint_linmul2(word x[], size_t x_size, word y); void bigint_linmul3(word z[], const word x[], size_t x_size, word y); -/* +/** * Montgomery Reduction -* @param z integer to reduce (also output in first x_size+1 words) -* @param z_size size of z (should be >= 2*x_size+1) -* @param workspace array of at least 2*(x_size+1) words -* @param x modulus -* @param x_size size of x -* @param u Montgomery value +* @param z integer to reduce (also output in first p_size+1 words) +* @param z_size size of z (should be >= 2*p_size+1) +* @param p modulus +* @param p_size size of p +* @param p_dash Montgomery value +* @param workspace array of at least 2*(p_size+1) words */ void bigint_monty_redc(word z[], size_t z_size, - word workspace[], - const word x[], size_t x_size, - word u); + const word p[], size_t p_size, word p_dash, + word workspace[]); + +/* +* Montgomery Multiplication +*/ +void bigint_monty_mul(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word y[], size_t y_size, size_t y_sw, + const word p[], size_t p_size, word p_dash, + word workspace[]); + +/* +* Montgomery Squaring +*/ +void bigint_monty_sqr(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word p[], size_t p_size, word p_dash, + word workspace[]); /* * Division operation diff --git a/src/math/mp/mp_generic/mp_asm.h b/src/math/mp/mp_generic/mp_asm.h index ee46e1aa9..7c18343ef 100644 --- a/src/math/mp/mp_generic/mp_asm.h +++ b/src/math/mp/mp_generic/mp_asm.h @@ -14,7 +14,7 @@ #if (BOTAN_MP_WORD_BITS == 8) typedef Botan::u16bit dword; #elif (BOTAN_MP_WORD_BITS == 16) - typedef Botan::size_t dword; + typedef Botan::u32bit dword; #elif (BOTAN_MP_WORD_BITS == 32) typedef Botan::u64bit dword; #elif (BOTAN_MP_WORD_BITS == 64) diff --git a/src/math/mp/mp_monty.cpp b/src/math/mp/mp_monty.cpp new file mode 100644 index 000000000..d37fb5844 --- /dev/null +++ b/src/math/mp/mp_monty.cpp @@ -0,0 +1,99 @@ +/* +* Montgomery Reduction +* (C) 1999-2011 Jack Lloyd +* 2006 Luca Piccarreta +* +* Distributed under the terms of the Botan license +*/ + +#include <botan/internal/mp_core.h> +#include <botan/internal/mp_asm.h> +#include <botan/internal/mp_asmi.h> +#include <botan/mem_ops.h> + +namespace Botan { + +extern "C" { + +/* +* Montgomery Reduction Algorithm +*/ +void bigint_monty_redc(word z[], size_t z_size, + const word p[], size_t p_size, + word p_dash, word ws[]) + { + const size_t blocks_of_8 = p_size - (p_size % 8); + + for(size_t i = 0; i != p_size; ++i) + { + word* z_i = z + i; + + const word y = z_i[0] * p_dash; + + /* + bigint_linmul3(ws, p, p_size, y); + bigint_add2(z_i, z_size - i, ws, p_size+1); + */ + + word carry = 0; + + for(size_t j = 0; j != blocks_of_8; j += 8) + carry = word8_madd3(z_i + j, p + j, y, carry); + + for(size_t j = blocks_of_8; j != p_size; ++j) + z_i[j] = word_madd3(p[j], y, z_i[j], &carry); + + word z_sum = z_i[p_size] + carry; + carry = (z_sum < z_i[p_size]); + z_i[p_size] = z_sum; + + for(size_t j = p_size + 1; carry && j != z_size - i; ++j) + { + ++z_i[j]; + carry = !z_i[j]; + } + } + + word borrow = 0; + for(size_t i = 0; i != p_size; ++i) + ws[i] = word_sub(z[p_size + i], p[i], &borrow); + + ws[p_size] = word_sub(z[p_size+p_size], 0, &borrow); + + copy_mem(ws + p_size + 1, z + p_size, p_size + 1); + + copy_mem(z, ws + borrow*(p_size+1), p_size + 1); + clear_mem(z + p_size + 1, z_size - p_size - 1); + } + +void bigint_monty_mul(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word y[], size_t y_size, size_t y_sw, + const word p[], size_t p_size, word p_dash, + word ws[]) + { + bigint_mul(&z[0], z_size, &ws[0], + &x[0], x_size, x_sw, + &y[0], y_size, y_sw); + + bigint_monty_redc(&z[0], z_size, + &p[0], p_size, p_dash, + &ws[0]); + } + +void bigint_monty_sqr(word z[], size_t z_size, + const word x[], size_t x_size, size_t x_sw, + const word p[], size_t p_size, word p_dash, + word ws[]) + { + bigint_sqr(&z[0], z_size, &ws[0], + &x[0], x_size, x_sw); + + bigint_monty_redc(&z[0], z_size, + &p[0], p_size, p_dash, + &ws[0]); + } + +} + +} diff --git a/src/math/mp/mp_msvc64/info.txt b/src/math/mp/mp_msvc64/info.txt index 56ae05927..fa7d90fed 100644 --- a/src/math/mp/mp_msvc64/info.txt +++ b/src/math/mp/mp_msvc64/info.txt @@ -8,7 +8,7 @@ mp_generic:mp_asmi.h </header:internal> <arch> -amd64 +x86_64 ia64 </arch> diff --git a/src/math/mp/mulop_generic/mp_mulop.cpp b/src/math/mp/mp_mulop.cpp index e6a8ba891..e6a8ba891 100644 --- a/src/math/mp/mulop_generic/mp_mulop.cpp +++ b/src/math/mp/mp_mulop.cpp diff --git a/src/math/mp/mp_ia32/info.txt b/src/math/mp/mp_x86_32/info.txt index 1659f74cf..432f909f8 100644 --- a/src/math/mp/mp_ia32/info.txt +++ b/src/math/mp/mp_x86_32/info.txt @@ -8,7 +8,7 @@ mp_asmi.h </header:internal> <arch> -ia32 +x86_32 </arch> <cc> diff --git a/src/math/mp/mp_ia32/mp_asm.h b/src/math/mp/mp_x86_32/mp_asm.h index 4d3afc992..9be5680f8 100644 --- a/src/math/mp/mp_ia32/mp_asm.h +++ b/src/math/mp/mp_x86_32/mp_asm.h @@ -12,7 +12,7 @@ #include <botan/mp_types.h> #if (BOTAN_MP_WORD_BITS != 32) - #error The mp_ia32 module requires that BOTAN_MP_WORD_BITS == 32 + #error The mp_x86_32 module requires that BOTAN_MP_WORD_BITS == 32 #endif namespace Botan { diff --git a/src/math/mp/mp_ia32/mp_asmi.h b/src/math/mp/mp_x86_32/mp_asmi.h index c7b679e80..c7b679e80 100644 --- a/src/math/mp/mp_ia32/mp_asmi.h +++ b/src/math/mp/mp_x86_32/mp_asmi.h diff --git a/src/math/mp/mp_ia32_msvc/info.txt b/src/math/mp/mp_x86_32_msvc/info.txt index 55a42c310..8d35c02e7 100644 --- a/src/math/mp/mp_ia32_msvc/info.txt +++ b/src/math/mp/mp_x86_32_msvc/info.txt @@ -8,7 +8,7 @@ mp_asmi.h </header:internal> <arch> -ia32 +x86_32 </arch> <cc> diff --git a/src/math/mp/mp_ia32_msvc/mp_asmi.h b/src/math/mp/mp_x86_32_msvc/mp_asmi.h index aee457d65..aee457d65 100644 --- a/src/math/mp/mp_ia32_msvc/mp_asmi.h +++ b/src/math/mp/mp_x86_32_msvc/mp_asmi.h diff --git a/src/math/mp/mp_amd64/info.txt b/src/math/mp/mp_x86_64/info.txt index 11cc380e2..fdcc05dd6 100644 --- a/src/math/mp/mp_amd64/info.txt +++ b/src/math/mp/mp_x86_64/info.txt @@ -8,7 +8,7 @@ mp_asmi.h </header:internal> <arch> -amd64 +x86_64 </arch> <cc> diff --git a/src/math/mp/mp_amd64/mp_asm.h b/src/math/mp/mp_x86_64/mp_asm.h index fa66d04f3..edfaf6352 100644 --- a/src/math/mp/mp_amd64/mp_asm.h +++ b/src/math/mp/mp_x86_64/mp_asm.h @@ -12,7 +12,7 @@ #include <botan/mp_types.h> #if (BOTAN_MP_WORD_BITS != 64) - #error The mp_amd64 module requires that BOTAN_MP_WORD_BITS == 64 + #error The mp_x86_64 module requires that BOTAN_MP_WORD_BITS == 64 #endif namespace Botan { @@ -20,7 +20,7 @@ namespace Botan { extern "C" { /* -* Helper Macros for amd64 Assembly +* Helper Macros for x86-64 Assembly */ #define ASM(x) x "\n\t" diff --git a/src/math/mp/mp_amd64/mp_asmi.h b/src/math/mp/mp_x86_64/mp_asmi.h index adf7774ef..f14df0e89 100644 --- a/src/math/mp/mp_amd64/mp_asmi.h +++ b/src/math/mp/mp_x86_64/mp_asmi.h @@ -16,7 +16,7 @@ namespace Botan { extern "C" { /* -* Helper Macros for amd64 Assembly +* Helper Macros for x86-64 Assembly */ #ifndef ASM #define ASM(x) x "\n\t" diff --git a/src/math/mp/mulop_generic/info.txt b/src/math/mp/mulop_generic/info.txt deleted file mode 100644 index 548d0f44b..000000000 --- a/src/math/mp/mulop_generic/info.txt +++ /dev/null @@ -1,5 +0,0 @@ -load_on dep - -<source> -mp_mulop.cpp -</source> diff --git a/src/math/numbertheory/info.txt b/src/math/numbertheory/info.txt index 18349ef78..0c6a9aefc 100644 --- a/src/math/numbertheory/info.txt +++ b/src/math/numbertheory/info.txt @@ -1,11 +1,9 @@ -load_on auto - define BIGINT_MATH +load_on auto + <header:public> -curve_gfp.h numthry.h -point_gfp.h pow_mod.h reducer.h </header:public> @@ -20,7 +18,6 @@ jacobi.cpp make_prm.cpp mp_numth.cpp numthry.cpp -point_gfp.cpp pow_mod.cpp powm_fw.cpp powm_mnt.cpp diff --git a/src/math/numbertheory/pow_mod.cpp b/src/math/numbertheory/pow_mod.cpp index a66a1f7df..bf6b29275 100644 --- a/src/math/numbertheory/pow_mod.cpp +++ b/src/math/numbertheory/pow_mod.cpp @@ -118,7 +118,12 @@ size_t Power_Mod::window_bits(size_t exp_bits, size_t, Power_Mod::Usage_Hints hints) { static const size_t wsize[][2] = { - { 2048, 7 }, { 1024, 6 }, { 256, 5 }, { 128, 4 }, { 64, 3 }, { 0, 0 } + { 1434, 7 }, + { 539, 6 }, + { 197, 4 }, + { 70, 3 }, + { 25, 2 }, + { 0, 0 } }; size_t window_bits = 1; diff --git a/src/math/numbertheory/powm_mnt.cpp b/src/math/numbertheory/powm_mnt.cpp index 421470364..8993f4ba9 100644 --- a/src/math/numbertheory/powm_mnt.cpp +++ b/src/math/numbertheory/powm_mnt.cpp @@ -33,13 +33,12 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) SecureVector<word> workspace(z.size()); g[0] = (base >= modulus) ? (base % modulus) : base; - bigint_mul(&z[0], z.size(), &workspace[0], - g[0].data(), g[0].size(), g[0].sig_words(), - R2.data(), R2.size(), R2.sig_words()); - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + g[0].data(), g[0].size(), g[0].sig_words(), + R2.data(), R2.size(), R2.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); g[0].assign(&z[0], mod_words + 1); @@ -52,13 +51,11 @@ void Montgomery_Exponentiator::set_base(const BigInt& base) const size_t y_sig = y.sig_words(); zeroise(z); - bigint_mul(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x_sig, - y.data(), y.size(), y_sig); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x_sig, + y.data(), y.size(), y_sig, + modulus.data(), mod_words, mod_prime, + &workspace[0]); g[i].assign(&z[0], mod_words + 1); } @@ -80,12 +77,11 @@ BigInt Montgomery_Exponentiator::execute() const for(size_t k = 0; k != window_bits; ++k) { zeroise(z); - bigint_sqr(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x.sig_words()); - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_sqr(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.assign(&z[0], mod_words + 1); } @@ -95,13 +91,11 @@ BigInt Montgomery_Exponentiator::execute() const const BigInt& y = g[nibble-1]; zeroise(z); - bigint_mul(&z[0], z.size(), &workspace[0], - x.data(), x.size(), x.sig_words(), - y.data(), y.size(), y.sig_words()); - - bigint_monty_redc(&z[0], z.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + bigint_monty_mul(&z[0], z.size(), + x.data(), x.size(), x.sig_words(), + y.data(), y.size(), y.sig_words(), + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.assign(&z[0], mod_words + 1); } @@ -110,8 +104,8 @@ BigInt Montgomery_Exponentiator::execute() const x.get_reg().resize(2*mod_words+1); bigint_monty_redc(&x[0], x.size(), - &workspace[0], - modulus.data(), mod_words, mod_prime); + modulus.data(), mod_words, mod_prime, + &workspace[0]); x.get_reg().resize(mod_words+1); @@ -134,14 +128,12 @@ Montgomery_Exponentiator::Montgomery_Exponentiator(const BigInt& mod, mod_words = modulus.sig_words(); - BigInt mod_prime_bn(BigInt::Power2, MP_WORD_BITS); - mod_prime = (mod_prime_bn - inverse_mod(modulus, mod_prime_bn)).word_at(0); + BigInt r(BigInt::Power2, mod_words * BOTAN_MP_WORD_BITS); + mod_prime = (((r * inverse_mod(r, mod)) - 1) / mod).word_at(0); - R_mod = BigInt(BigInt::Power2, MP_WORD_BITS * mod_words); - R_mod %= modulus; + R_mod = r % modulus; - R2 = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words); - R2 %= modulus; + R2 = (R_mod * R_mod) % modulus; } } diff --git a/src/math/numbertheory/reducer.cpp b/src/math/numbertheory/reducer.cpp index 257ece56e..466996e99 100644 --- a/src/math/numbertheory/reducer.cpp +++ b/src/math/numbertheory/reducer.cpp @@ -1,6 +1,6 @@ /* * Modular Reducer -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -22,10 +22,8 @@ Modular_Reducer::Modular_Reducer(const BigInt& mod) mod_words = modulus.sig_words(); modulus_2 = Botan::square(modulus); - mod2_words = modulus_2.sig_words(); mu = BigInt(BigInt::Power2, 2 * MP_WORD_BITS * mod_words) / modulus; - mu_words = mu.sig_words(); } /* @@ -36,45 +34,49 @@ BigInt Modular_Reducer::reduce(const BigInt& x) const if(mod_words == 0) throw Invalid_State("Modular_Reducer: Never initalized"); - BigInt t1 = x; - t1.set_sign(BigInt::Positive); - - if(t1 < modulus) + if(x.cmp(modulus, false) < 0) { - if(x.is_negative() && t1.is_nonzero()) - return modulus - t1; + if(x.is_negative()) + return x + modulus; // make positive return x; } + else if(x.cmp(modulus_2, false) < 0) + { + BigInt t1 = x; + t1.set_sign(BigInt::Positive); + t1 >>= (MP_WORD_BITS * (mod_words - 1)); + t1 *= mu; - if(t1 >= modulus_2) - return (x % modulus); + t1 >>= (MP_WORD_BITS * (mod_words + 1)); + t1 *= modulus; - t1 >>= (MP_WORD_BITS * (mod_words - 1)); - t1 *= mu; - t1 >>= (MP_WORD_BITS * (mod_words + 1)); + t1.mask_bits(MP_WORD_BITS * (mod_words + 1)); - t1 *= modulus; - t1.mask_bits(MP_WORD_BITS * (mod_words+1)); + BigInt t2 = x; + t2.set_sign(BigInt::Positive); + t2.mask_bits(MP_WORD_BITS * (mod_words + 1)); - BigInt t2 = x; - t2.set_sign(BigInt::Positive); - t2.mask_bits(MP_WORD_BITS * (mod_words+1)); + t2 -= t1; - t1 = t2 - t1; + if(t2.is_negative()) + { + BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words + 1)); + t2 += b_to_k1; + } - if(t1.is_negative()) + while(t2 >= modulus) + t2 -= modulus; + + if(x.is_positive()) + return t2; + else + return (modulus - t2); + } + else { - BigInt b_to_k1(BigInt::Power2, MP_WORD_BITS * (mod_words+1)); - t1 += b_to_k1; + // too big, fall back to normal division + return (x % modulus); } - - while(t1 >= modulus) - t1 -= modulus; - - if(x.is_negative() && t1.is_nonzero()) - t1 = modulus - t1; - - return t1; } } diff --git a/src/math/numbertheory/reducer.h b/src/math/numbertheory/reducer.h index 05c12a440..76712074c 100644 --- a/src/math/numbertheory/reducer.h +++ b/src/math/numbertheory/reducer.h @@ -13,7 +13,7 @@ namespace Botan { /** -* Modular Reducer +* Modular Reducer (using Barrett's technique) */ class BOTAN_DLL Modular_Reducer { @@ -53,7 +53,7 @@ class BOTAN_DLL Modular_Reducer Modular_Reducer(const BigInt& mod); private: BigInt modulus, modulus_2, mu; - size_t mod_words, mod2_words, mu_words; + size_t mod_words; }; } diff --git a/src/passhash/bcrypt/bcrypt.cpp b/src/passhash/bcrypt/bcrypt.cpp index 3507db879..b0d654717 100644 --- a/src/passhash/bcrypt/bcrypt.cpp +++ b/src/passhash/bcrypt/bcrypt.cpp @@ -11,11 +11,6 @@ #include <botan/blowfish.h> #include <botan/base64.h> -#include <botan/pipe.h> -#include <botan/b64_filt.h> -#include <iostream> -#include <stdio.h> - namespace Botan { namespace { @@ -89,10 +84,7 @@ MemoryVector<byte> bcrypt_base64_decode(std::string input) for(size_t i = 0; i != input.size(); ++i) input[i] = OPENBSD_BASE64_SUB[static_cast<byte>(input[i])]; - //return base64_decode(input); - Pipe pipe(new Base64_Decoder); - pipe.process_msg(input); - return pipe.read_all(); + return base64_decode(input); } std::string make_bcrypt(const std::string& pass, diff --git a/src/passhash/passhash9/passhash9.cpp b/src/passhash/passhash9/passhash9.cpp index 367583a0a..43bfdd36e 100644 --- a/src/passhash/passhash9/passhash9.cpp +++ b/src/passhash/passhash9/passhash9.cpp @@ -23,8 +23,6 @@ const size_t ALGID_BYTES = 1; const size_t SALT_BYTES = 12; // 96 bits of salt const size_t PASSHASH9_PBKDF_OUTPUT_LEN = 24; // 192 bits output -const byte PASSHASH9_DEFAULT_ALGO = 0; // HMAC(SHA-1) - const size_t WORK_FACTOR_SCALE = 10000; MessageAuthenticationCode* get_pbkdf_prf(byte alg_id) @@ -49,15 +47,8 @@ MessageAuthenticationCode* get_pbkdf_prf(byte alg_id) 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) + u16bit work_factor, + byte alg_id) { MessageAuthenticationCode* prf = get_pbkdf_prf(alg_id); diff --git a/src/passhash/passhash9/passhash9.h b/src/passhash/passhash9/passhash9.h index 92cc391dc..3c0a4be51 100644 --- a/src/passhash/passhash9/passhash9.h +++ b/src/passhash/passhash9/passhash9.h @@ -17,26 +17,16 @@ namespace Botan { * @param password the password * @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, - RandomNumberGenerator& rng, - 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); + u16bit work_factor = 10, + byte alg_id = 0); /** * Check a previously created password hash diff --git a/src/pk_pad/eme1/eme1.cpp b/src/pk_pad/eme1/eme1.cpp index b49fb9af0..1cc0c332d 100644 --- a/src/pk_pad/eme1/eme1.cpp +++ b/src/pk_pad/eme1/eme1.cpp @@ -65,38 +65,47 @@ SecureVector<byte> EME1::unpad(const byte in[], size_t in_length, if(in_length > key_length) in_length = 0; - SecureVector<byte> tmp(key_length); - tmp.copy(key_length - in_length, in, in_length); + SecureVector<byte> input(key_length); + input.copy(key_length - in_length, in, in_length); - mgf->mask(&tmp[Phash.size()], tmp.size() - Phash.size(), - &tmp[0], Phash.size()); - mgf->mask(&tmp[0], Phash.size(), - &tmp[Phash.size()], tmp.size() - Phash.size()); + mgf->mask(&input[Phash.size()], input.size() - Phash.size(), + &input[0], Phash.size()); + mgf->mask(&input[0], Phash.size(), + &input[Phash.size()], input.size() - Phash.size()); - const bool phash_ok = same_mem(&tmp[Phash.size()], &Phash[0], Phash.size()); + bool waiting_for_delim = true; + bool bad_input = false; + size_t delim_idx = 2 * Phash.size(); - bool delim_ok = true; - size_t delim_idx = 0; - - // Is this vulnerable to timing attacks? - for(size_t i = Phash.size() + Phash.size(); i != tmp.size(); ++i) + /* + * GCC 4.5 on x86-64 compiles this in a way that is still vunerable + * to timing analysis. Other compilers, or GCC on other platforms, + * may or may not. + */ + for(size_t i = delim_idx; i != input.size(); ++i) { - if(tmp[i] && !delim_idx) - { - if(tmp[i] == 0x01) - delim_idx = i; - else - delim_ok = false; - } - } + const bool zero_p = !input[i]; + const bool one_p = input[i] == 0x01; - if(delim_idx && delim_ok && phash_ok) - { - return SecureVector<byte>(&tmp[delim_idx + 1], - tmp.size() - delim_idx - 1); + const bool add_1 = waiting_for_delim && zero_p; + + bad_input |= waiting_for_delim && !(zero_p || one_p); + + delim_idx += add_1; + + waiting_for_delim &= zero_p; } - throw Decoding_Error("Invalid EME1 encoding"); + // If we never saw any non-zero byte, then it's not valid input + bad_input |= waiting_for_delim; + + bad_input |= !same_mem(&input[Phash.size()], &Phash[0], Phash.size()); + + if(bad_input) + throw Decoding_Error("Invalid EME1 encoding"); + + return SecureVector<byte>(input + delim_idx + 1, + input.size() - delim_idx - 1); } /* diff --git a/src/pubkey/ec_dompar/ec_dompar.cpp b/src/pubkey/ec_group/ec_group.cpp index deb512518..fe4fae885 100644 --- a/src/pubkey/ec_dompar/ec_dompar.cpp +++ b/src/pubkey/ec_group/ec_group.cpp @@ -7,7 +7,7 @@ * Distributed under the terms of the Botan license */ -#include <botan/ec_dompar.h> +#include <botan/ec_group.h> #include <botan/ber_dec.h> #include <botan/der_enc.h> #include <botan/libstate.h> @@ -16,7 +16,7 @@ namespace Botan { -EC_Domain_Params::EC_Domain_Params(const OID& domain_oid) +EC_Group::EC_Group(const OID& domain_oid) { std::string pem = global_state().get("ec", OIDS::lookup(domain_oid)); @@ -24,31 +24,31 @@ EC_Domain_Params::EC_Domain_Params(const OID& domain_oid) if(pem == "") throw Lookup_Error("No ECC domain data for " + domain_oid.as_string()); - *this = EC_Domain_Params(pem); + *this = EC_Group(pem); oid = domain_oid.as_string(); } -EC_Domain_Params::EC_Domain_Params(const std::string& pem) +EC_Group::EC_Group(const std::string& str) { - if(pem == "") + if(str == "") return; // no initialization / uninitialized try { - DataSource_Memory input(pem); + DataSource_Memory input(str); SecureVector<byte> ber = PEM_Code::decode_check_label(input, "EC PARAMETERS"); - *this = EC_Domain_Params(ber); + *this = EC_Group(ber); } catch(Decoding_Error) // hmm, not PEM? { - *this = EC_Domain_Params(OID(pem)); + *this = EC_Group(OIDS::lookup(str)); } } -EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) +EC_Group::EC_Group(const MemoryRegion<byte>& ber_data) { BER_Decoder ber(ber_data); BER_Object obj = ber.get_next_object(); @@ -59,7 +59,7 @@ EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) { OID dom_par_oid; BER_Decoder(ber_data).decode(dom_par_oid); - *this = EC_Domain_Params(dom_par_oid); + *this = EC_Group(dom_par_oid); } else if(obj.type_tag == SEQUENCE) { @@ -92,7 +92,7 @@ EC_Domain_Params::EC_Domain_Params(const MemoryRegion<byte>& ber_data) } SecureVector<byte> -EC_Domain_Params::DER_encode(EC_Domain_Params_Encoding form) const +EC_Group::DER_encode(EC_Group_Encoding form) const { if(form == EC_DOMPAR_ENC_EXPLICIT) { @@ -125,10 +125,10 @@ EC_Domain_Params::DER_encode(EC_Domain_Params_Encoding form) const else if(form == EC_DOMPAR_ENC_IMPLICITCA) return DER_Encoder().encode_null().get_contents(); else - throw Internal_Error("EC_Domain_Params::DER_encode: Unknown encoding"); + throw Internal_Error("EC_Group::DER_encode: Unknown encoding"); } -std::string EC_Domain_Params::PEM_encode() const +std::string EC_Group::PEM_encode() const { SecureVector<byte> der = DER_encode(EC_DOMPAR_ENC_EXPLICIT); return PEM_Code::encode(der, "EC PARAMETERS"); diff --git a/src/pubkey/ec_dompar/ec_dompar.h b/src/pubkey/ec_group/ec_group.h index 2508d5a2d..b7b09985e 100644 --- a/src/pubkey/ec_dompar/ec_dompar.h +++ b/src/pubkey/ec_group/ec_group.h @@ -19,7 +19,7 @@ namespace Botan { /** * This class represents elliptic curce domain parameters */ -enum EC_Domain_Params_Encoding { +enum EC_Group_Encoding { EC_DOMPAR_ENC_EXPLICIT = 0, EC_DOMPAR_ENC_IMPLICITCA = 1, EC_DOMPAR_ENC_OID = 2 @@ -28,7 +28,7 @@ enum EC_Domain_Params_Encoding { /** * Class representing an elliptic curve */ -class BOTAN_DLL EC_Domain_Params +class BOTAN_DLL EC_Group { public: @@ -39,7 +39,7 @@ class BOTAN_DLL EC_Domain_Params * @param order the order of the base point * @param cofactor the cofactor */ - EC_Domain_Params(const CurveGFp& curve, + EC_Group(const CurveGFp& curve, const PointGFp& base_point, const BigInt& order, const BigInt& cofactor) : @@ -54,27 +54,27 @@ class BOTAN_DLL EC_Domain_Params * Decode a BER encoded ECC domain parameter set * @param ber_encoding the bytes of the BER encoding */ - EC_Domain_Params(const MemoryRegion<byte>& ber_encoding); + EC_Group(const MemoryRegion<byte>& ber_encoding); /** * Create an EC domain by OID (or throw if unknown) * @param oid the OID of the EC domain to create */ - EC_Domain_Params(const OID& oid); + EC_Group(const OID& oid); /** * Create an EC domain from PEM encoding (as from PEM_encode), * or from an OID name (eg "secp16r1", or "1.3.132.0.8") * @param pem_or_oid PEM-encoded data, or an OID */ - EC_Domain_Params(const std::string& pem_or_oid = ""); + EC_Group(const std::string& pem_or_oid = ""); /** * Create the DER encoding of this domain * @param form of encoding to use * @returns bytes encododed as DER */ - SecureVector<byte> DER_encode(EC_Domain_Params_Encoding form) const; + SecureVector<byte> DER_encode(EC_Group_Encoding form) const; /** * Return the PEM encoding (always in explicit form) @@ -114,7 +114,7 @@ class BOTAN_DLL EC_Domain_Params */ std::string get_oid() const { return oid; } - bool operator==(const EC_Domain_Params& other) const + bool operator==(const EC_Group& other) const { return ((get_curve() == other.get_curve()) && (get_base_point() == other.get_base_point()) && @@ -129,12 +129,15 @@ class BOTAN_DLL EC_Domain_Params std::string oid; }; -inline bool operator!=(const EC_Domain_Params& lhs, - const EC_Domain_Params& rhs) +inline bool operator!=(const EC_Group& lhs, + const EC_Group& rhs) { return !(lhs == rhs); } +// For compatability with 1.8 +typedef EC_Group EC_Domain_Params; + } #endif diff --git a/src/pubkey/ec_dompar/info.txt b/src/pubkey/ec_group/info.txt index ae6c328e2..9a686feeb 100644 --- a/src/pubkey/ec_dompar/info.txt +++ b/src/pubkey/ec_group/info.txt @@ -1,9 +1,10 @@ -define ECC_DOMAIN_PARAMATERS +define ECC_GROUP <requires> asn1 -numbertheory -pem +ec_gfp libstate +numbertheory oid_lookup +pem </requires> diff --git a/src/pubkey/ecc_key/ecc_key.cpp b/src/pubkey/ecc_key/ecc_key.cpp index bd04e3197..991446f07 100644 --- a/src/pubkey/ecc_key/ecc_key.cpp +++ b/src/pubkey/ecc_key/ecc_key.cpp @@ -18,7 +18,7 @@ namespace Botan { -EC_PublicKey::EC_PublicKey(const EC_Domain_Params& dom_par, +EC_PublicKey::EC_PublicKey(const EC_Group& dom_par, const PointGFp& pub_point) : domain_params(dom_par), public_key(pub_point), domain_encoding(EC_DOMPAR_ENC_EXPLICIT) @@ -30,7 +30,7 @@ EC_PublicKey::EC_PublicKey(const EC_Domain_Params& dom_par, EC_PublicKey::EC_PublicKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits) { - domain_params = EC_Domain_Params(alg_id.parameters); + domain_params = EC_Group(alg_id.parameters); domain_encoding = EC_DOMPAR_ENC_EXPLICIT; public_key = OS2ECP(key_bits, domain().get_curve()); @@ -52,7 +52,7 @@ MemoryVector<byte> EC_PublicKey::x509_subject_public_key() const return EC2OSP(public_point(), PointGFp::COMPRESSED); } -void EC_PublicKey::set_parameter_encoding(EC_Domain_Params_Encoding form) +void EC_PublicKey::set_parameter_encoding(EC_Group_Encoding form) { if(form != EC_DOMPAR_ENC_EXPLICIT && form != EC_DOMPAR_ENC_IMPLICITCA && @@ -76,32 +76,24 @@ const BigInt& EC_PrivateKey::private_value() const } /** -* EC_PrivateKey generator -*/ -EC_PrivateKey::EC_PrivateKey(const EC_Domain_Params& dom_par, - const BigInt& priv_key) - { - domain_params = dom_par; - domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - - public_key = domain().get_base_point() * priv_key; - private_key = priv_key; - } - -/** -* EC_PrivateKey generator +* EC_PrivateKey constructor */ EC_PrivateKey::EC_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& dom_par) + const EC_Group& ec_group, + const BigInt& x) { - domain_params = dom_par; + domain_params = ec_group; domain_encoding = EC_DOMPAR_ENC_EXPLICIT; - private_key = BigInt::random_integer(rng, 1, domain().get_order()); + if(x == 0) + private_key = BigInt::random_integer(rng, 1, domain().get_order()); + else + private_key = x; + public_key = domain().get_base_point() * private_key; BOTAN_ASSERT(public_key.on_the_curve(), - "generated ECC private key was not on the curve"); + "ECC private key was not on the curve"); } MemoryVector<byte> EC_PrivateKey::pkcs8_private_key() const @@ -118,7 +110,7 @@ MemoryVector<byte> EC_PrivateKey::pkcs8_private_key() const EC_PrivateKey::EC_PrivateKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits) { - domain_params = EC_Domain_Params(alg_id.parameters); + domain_params = EC_Group(alg_id.parameters); domain_encoding = EC_DOMPAR_ENC_EXPLICIT; BER_Decoder(key_bits) diff --git a/src/pubkey/ecc_key/ecc_key.h b/src/pubkey/ecc_key/ecc_key.h index a20516ec6..cccc8d53c 100644 --- a/src/pubkey/ecc_key/ecc_key.h +++ b/src/pubkey/ecc_key/ecc_key.h @@ -10,7 +10,7 @@ #ifndef BOTAN_ECC_PUBLIC_KEY_BASE_H__ #define BOTAN_ECC_PUBLIC_KEY_BASE_H__ -#include <botan/ec_dompar.h> +#include <botan/ec_group.h> #include <botan/pk_keys.h> #include <botan/x509_key.h> #include <botan/pkcs8.h> @@ -18,7 +18,7 @@ namespace Botan { /** -* This class represents abstract EC Public Keys. When encoding a key +* This class represents abstract ECC public keys. When encoding a key * via an encoder that can be accessed via the corresponding member * functions, the key will decide upon its internally stored encoding * information whether to encode itself with or without domain @@ -30,7 +30,7 @@ namespace Botan { class BOTAN_DLL EC_PublicKey : public virtual Public_Key { public: - EC_PublicKey(const EC_Domain_Params& dom_par, + EC_PublicKey(const EC_Group& dom_par, const PointGFp& pub_point); EC_PublicKey(const AlgorithmIdentifier& alg_id, @@ -57,13 +57,13 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * domain parameters of this point are not set * @result the domain parameters of this key */ - const EC_Domain_Params& domain() const { return domain_params; } + const EC_Group& domain() const { return domain_params; } /** * Set the domain parameter encoding to be used when encoding this key. * @param enc the encoding to use */ - void set_parameter_encoding(EC_Domain_Params_Encoding enc); + void set_parameter_encoding(EC_Group_Encoding enc); /** * Return the DER encoding of this keys domain in whatever format @@ -76,28 +76,26 @@ class BOTAN_DLL EC_PublicKey : public virtual Public_Key * Get the domain parameter encoding to be used when encoding this key. * @result the encoding to use */ - EC_Domain_Params_Encoding domain_format() const + EC_Group_Encoding domain_format() const { return domain_encoding; } protected: EC_PublicKey() : domain_encoding(EC_DOMPAR_ENC_EXPLICIT) {} - EC_Domain_Params domain_params; + EC_Group domain_params; PointGFp public_key; - EC_Domain_Params_Encoding domain_encoding; + EC_Group_Encoding domain_encoding; }; /** -* This abstract class represents general EC Private Keys +* This abstract class represents ECC private keys */ class BOTAN_DLL EC_PrivateKey : public virtual EC_PublicKey, public virtual Private_Key { public: - EC_PrivateKey(const EC_Domain_Params& domain, - const BigInt& private_key); - - EC_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain); + EC_PrivateKey(RandomNumberGenerator& rng, + const EC_Group& domain, + const BigInt& private_key); EC_PrivateKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits); diff --git a/src/pubkey/ecc_key/info.txt b/src/pubkey/ecc_key/info.txt index e08a4231d..ceb98a79e 100644 --- a/src/pubkey/ecc_key/info.txt +++ b/src/pubkey/ecc_key/info.txt @@ -4,6 +4,7 @@ define ECC_PUBLIC_KEY_CRYPTO alloc asn1 bigint -ec_dompar +ec_gfp +ec_group numbertheory </requires> diff --git a/src/pubkey/ecdh/ecdh.h b/src/pubkey/ecdh/ecdh.h index 301bb1591..2edbfe86d 100644 --- a/src/pubkey/ecdh/ecdh.h +++ b/src/pubkey/ecdh/ecdh.h @@ -32,7 +32,7 @@ class BOTAN_DLL ECDH_PublicKey : public virtual EC_PublicKey * @param dom_par the domain parameters associated with this key * @param public_point the public point defining this key */ - ECDH_PublicKey(const EC_Domain_Params& dom_par, + ECDH_PublicKey(const EC_Group& dom_par, const PointGFp& public_point) : EC_PublicKey(dom_par, public_point) {} @@ -77,10 +77,12 @@ class BOTAN_DLL ECDH_PrivateKey : public ECDH_PublicKey, * Generate a new private key * @param rng a random number generator * @param domain parameters to used for this key + * @param x the private key; if zero, a new random key is generated */ ECDH_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain) : - EC_PrivateKey(rng, domain) {} + const EC_Group& domain, + const BigInt& x = 0) : + EC_PrivateKey(rng, domain, x) {} MemoryVector<byte> public_value() const { return ECDH_PublicKey::public_value(); } diff --git a/src/pubkey/ecdh/info.txt b/src/pubkey/ecdh/info.txt index 12826c81b..7e7d50fef 100644 --- a/src/pubkey/ecdh/info.txt +++ b/src/pubkey/ecdh/info.txt @@ -3,7 +3,7 @@ define ECDH <requires> alloc asn1 -ec_dompar +ec_group ecc_key libstate numbertheory diff --git a/src/pubkey/ecdsa/ecdsa.cpp b/src/pubkey/ecdsa/ecdsa.cpp index 9a3510c33..5c45c5ed3 100644 --- a/src/pubkey/ecdsa/ecdsa.cpp +++ b/src/pubkey/ecdsa/ecdsa.cpp @@ -80,12 +80,13 @@ bool ECDSA_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt r(sig, sig_len / 2); BigInt s(sig + sig_len / 2, sig_len / 2); - if(r < 0 || r >= order || s < 0 || s >= order) + if(r <= 0 || r >= order || s <= 0 || s >= order) return false; BigInt w = inverse_mod(s, order); - PointGFp R = w * (e * base_point + r * public_point); + PointGFp R = w * multi_exponentiate(base_point, e, + public_point, r); if(R.is_zero()) return false; diff --git a/src/pubkey/ecdsa/ecdsa.h b/src/pubkey/ecdsa/ecdsa.h index 6d62a168d..f0834abd8 100644 --- a/src/pubkey/ecdsa/ecdsa.h +++ b/src/pubkey/ecdsa/ecdsa.h @@ -28,7 +28,7 @@ class BOTAN_DLL ECDSA_PublicKey : public virtual EC_PublicKey * @param dom_par the domain parameters associated with this key * @param public_point the public point defining this key */ - ECDSA_PublicKey(const EC_Domain_Params& dom_par, + ECDSA_PublicKey(const EC_Group& dom_par, const PointGFp& public_point) : EC_PublicKey(dom_par, public_point) {} @@ -66,6 +66,11 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, { public: + /** + * Load a private key + * @param alg_id the X.509 algorithm identifier + * @param key_bits PKCS #8 structure + */ ECDSA_PrivateKey(const AlgorithmIdentifier& alg_id, const MemoryRegion<byte>& key_bits) : EC_PrivateKey(alg_id, key_bits) {} @@ -74,19 +79,12 @@ class BOTAN_DLL ECDSA_PrivateKey : public ECDSA_PublicKey, * Generate a new private key * @param rng a random number generator * @param domain parameters to used for this key + * @param x the private key (if zero, generate a ney random key) */ ECDSA_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain) : - EC_PrivateKey(rng, domain) {} - - /** - * Load a private key - * @param domain parameters - * @param x the private key - */ - ECDSA_PrivateKey(const EC_Domain_Params& domain, - const BigInt& x) : - EC_PrivateKey(domain, x) {} + const EC_Group& domain, + const BigInt& x = 0) : + EC_PrivateKey(rng, domain, x) {} bool check_key(RandomNumberGenerator& rng, bool) const; }; diff --git a/src/pubkey/ecdsa/info.txt b/src/pubkey/ecdsa/info.txt index ca2694ad1..7a2113a30 100644 --- a/src/pubkey/ecdsa/info.txt +++ b/src/pubkey/ecdsa/info.txt @@ -2,7 +2,7 @@ define ECDSA <requires> asn1 -ec_dompar +ec_group ecc_key numbertheory rng diff --git a/src/pubkey/gost_3410/gost_3410.cpp b/src/pubkey/gost_3410/gost_3410.cpp index fa72d0673..f97f83aa0 100644 --- a/src/pubkey/gost_3410/gost_3410.cpp +++ b/src/pubkey/gost_3410/gost_3410.cpp @@ -17,8 +17,8 @@ namespace Botan { MemoryVector<byte> GOST_3410_PublicKey::x509_subject_public_key() const { // Trust CryptoPro to come up with something obnoxious - const BigInt& x = public_point().get_affine_x(); - const BigInt& y = public_point().get_affine_y(); + const BigInt x = public_point().get_affine_x(); + const BigInt y = public_point().get_affine_y(); size_t part_size = std::max(x.bytes(), y.bytes()); @@ -56,7 +56,7 @@ GOST_3410_PublicKey::GOST_3410_PublicKey(const AlgorithmIdentifier& alg_id, // Also includes hash and cipher OIDs... brilliant design guys BER_Decoder(alg_id.parameters).start_cons(SEQUENCE).decode(ecc_param_id); - domain_params = EC_Domain_Params(ecc_param_id); + domain_params = EC_Group(ecc_param_id); SecureVector<byte> bits; BER_Decoder(key_bits).decode(bits, OCTET_STRING); @@ -153,7 +153,7 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt s(sig, sig_len / 2); BigInt r(sig + sig_len / 2, sig_len / 2); - if(r < 0 || r >= order || s < 0 || s >= order) + if(r <= 0 || r >= order || s <= 0 || s >= order) return false; e %= order; @@ -165,7 +165,11 @@ bool GOST_3410_Verification_Operation::verify(const byte msg[], size_t msg_len, BigInt z1 = (s*v) % order; BigInt z2 = (-r*v) % order; - PointGFp R = (z1 * base_point + z2 * public_point); + PointGFp R = multi_exponentiate(base_point, z1, + public_point, z2); + + if(R.is_zero()) + return false; return (R.get_affine_x() == r); } diff --git a/src/pubkey/gost_3410/gost_3410.h b/src/pubkey/gost_3410/gost_3410.h index 4fb7b42c3..7b638d7b5 100644 --- a/src/pubkey/gost_3410/gost_3410.h +++ b/src/pubkey/gost_3410/gost_3410.h @@ -27,7 +27,7 @@ class BOTAN_DLL GOST_3410_PublicKey : public virtual EC_PublicKey * @param dom_par the domain parameters associated with this key * @param public_point the public point defining this key */ - GOST_3410_PublicKey(const EC_Domain_Params& dom_par, + GOST_3410_PublicKey(const EC_Group& dom_par, const PointGFp& public_point) : EC_PublicKey(dom_par, public_point) {} @@ -80,18 +80,12 @@ class BOTAN_DLL GOST_3410_PrivateKey : public GOST_3410_PublicKey, * Generate a new private key * @param rng a random number generator * @param domain parameters to used for this key + * @param x the private key; if zero, a new random key is generated */ GOST_3410_PrivateKey(RandomNumberGenerator& rng, - const EC_Domain_Params& domain) : - EC_PrivateKey(rng, domain) {} - - /** - * Load a private key - * @param domain parameters - * @param x the private key - */ - GOST_3410_PrivateKey(const EC_Domain_Params& domain, const BigInt& x) : - EC_PrivateKey(domain, x) {} + const EC_Group& domain, + const BigInt& x = 0) : + EC_PrivateKey(rng, domain, x) {} AlgorithmIdentifier pkcs8_algorithm_identifier() const { return EC_PublicKey::algorithm_identifier(); } diff --git a/src/pubkey/gost_3410/info.txt b/src/pubkey/gost_3410/info.txt index 05df445ec..9fbc3099f 100644 --- a/src/pubkey/gost_3410/info.txt +++ b/src/pubkey/gost_3410/info.txt @@ -5,7 +5,7 @@ load_on auto <requires> alloc asn1 -ec_dompar +ec_group ecc_key libstate numbertheory diff --git a/src/utils/simd_32/info.txt b/src/simd/info.txt index 362e90235..d0601b141 100644 --- a/src/utils/simd_32/info.txt +++ b/src/simd/info.txt @@ -2,7 +2,8 @@ define SIMD_32 <header:internal> simd_32.h -simd_sse.h -simd_scalar.h -simd_altivec.h </header:internal> + +<requires> +simd_sse2|simd_altivec|simd_scalar +</requires> diff --git a/src/simd/simd_32.h b/src/simd/simd_32.h new file mode 100644 index 000000000..4ef0cea85 --- /dev/null +++ b/src/simd/simd_32.h @@ -0,0 +1,30 @@ +/* +* Lightweight wrappers for SIMD operations +* (C) 2009,2011 Jack Lloyd +* +* Distributed under the terms of the Botan license +*/ + +#ifndef BOTAN_SIMD_32_H__ +#define BOTAN_SIMD_32_H__ + +#include <botan/types.h> + +#if defined(BOTAN_HAS_SIMD_SSE2) + #include <botan/internal/simd_sse2.h> + namespace Botan { typedef SIMD_SSE2 SIMD_32; } + +#elif defined(BOTAN_HAS_SIMD_ALTIVEC) + #include <botan/internal/simd_altivec.h> + namespace Botan { typedef SIMD_Altivec SIMD_32; } + +#elif defined(BOTAN_HAS_SIMD_SCALAR) + #include <botan/internal/simd_scalar.h> + namespace Botan { typedef SIMD_Scalar SIMD_32; } + +#else + #error "No SIMD module defined" + +#endif + +#endif diff --git a/src/simd/simd_altivec/info.txt b/src/simd/simd_altivec/info.txt new file mode 100644 index 000000000..aa2f01c2d --- /dev/null +++ b/src/simd/simd_altivec/info.txt @@ -0,0 +1,9 @@ +define SIMD_ALTIVEC + +need_isa altivec + +load_on dep + +<header:internal> +simd_altivec.h +</header:internal> diff --git a/src/utils/simd_32/simd_altivec.h b/src/simd/simd_altivec/simd_altivec.h index 4c412ddec..4c412ddec 100644 --- a/src/utils/simd_32/simd_altivec.h +++ b/src/simd/simd_altivec/simd_altivec.h diff --git a/src/simd/simd_scalar/info.txt b/src/simd/simd_scalar/info.txt new file mode 100644 index 000000000..6817eab80 --- /dev/null +++ b/src/simd/simd_scalar/info.txt @@ -0,0 +1,7 @@ +define SIMD_SCALAR + +load_on dep + +<header:internal> +simd_scalar.h +</header:internal> diff --git a/src/utils/simd_32/simd_scalar.h b/src/simd/simd_scalar/simd_scalar.h index 2c68622af..2c68622af 100644 --- a/src/utils/simd_32/simd_scalar.h +++ b/src/simd/simd_scalar/simd_scalar.h diff --git a/src/simd/simd_sse2/info.txt b/src/simd/simd_sse2/info.txt new file mode 100644 index 000000000..e56792491 --- /dev/null +++ b/src/simd/simd_sse2/info.txt @@ -0,0 +1,9 @@ +define SIMD_SSE2 + +need_isa sse2 + +load_on dep + +<header:internal> +simd_sse2.h +</header:internal> diff --git a/src/utils/simd_32/simd_sse.h b/src/simd/simd_sse2/simd_sse2.h index 1cb52105c..61fce99a9 100644 --- a/src/utils/simd_32/simd_sse.h +++ b/src/simd/simd_sse2/simd_sse2.h @@ -22,7 +22,7 @@ class SIMD_SSE2 SIMD_SSE2(const u32bit B[4]) { - reg = _mm_loadu_si128((const __m128i*)B); + reg = _mm_loadu_si128(reinterpret_cast<const __m128i*>(B)); } SIMD_SSE2(u32bit B0, u32bit B1, u32bit B2, u32bit B3) @@ -37,7 +37,7 @@ class SIMD_SSE2 static SIMD_SSE2 load_le(const void* in) { - return _mm_loadu_si128((const __m128i*)in); + return _mm_loadu_si128(reinterpret_cast<const __m128i*>(in)); } static SIMD_SSE2 load_be(const void* in) @@ -47,7 +47,7 @@ class SIMD_SSE2 void store_le(byte out[]) const { - _mm_storeu_si128((__m128i*)out, reg); + _mm_storeu_si128(reinterpret_cast<__m128i*>(out), reg); } void store_be(byte out[]) const diff --git a/src/ssl/hello.cpp b/src/ssl/hello.cpp index bec316bb1..2c5a9d2ea 100644 --- a/src/ssl/hello.cpp +++ b/src/ssl/hello.cpp @@ -177,8 +177,9 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf) std::vector<byte> name = reader.get_range_vector<byte>(2, 1, 65535); - requested_hostname.assign((const char*)&name[0], - name.size()); + requested_hostname.assign( + reinterpret_cast<const char*>(&name[0]), + name.size()); name_bytes -= (2 + name.size()); } diff --git a/src/ssl/info.txt b/src/ssl/info.txt index 1f11772cd..910ed7e97 100644 --- a/src/ssl/info.txt +++ b/src/ssl/info.txt @@ -1,7 +1,11 @@ define SSL_TLS +<comment> +The SSL/TLS code is complex, new, and not yet reviewed, there may be +serious bugs or security issues. +</comment> + <header:public> -socket.h tls_client.h tls_connection.h tls_exceptn.h @@ -51,11 +55,11 @@ emsa3 filters hmac md5 +prf_ssl3 +prf_tls rng rsa sha1 ssl3mac -ssl_prf -tls_prf x509cert </requires> diff --git a/src/ssl/rec_read.cpp b/src/ssl/rec_read.cpp index 042aae0c9..4e5b69780 100644 --- a/src/ssl/rec_read.cpp +++ b/src/ssl/rec_read.cpp @@ -223,7 +223,7 @@ size_t Record_Reader::get_record(byte& msg_type, throw Decoding_Error("Record_Reader: Record truncated"); const size_t mac_offset = plaintext.size() - (mac_size + pad_size); - SecureVector<byte> recieved_mac(&plaintext[mac_offset], + SecureVector<byte> received_mac(&plaintext[mac_offset], mac_size); const u16bit plain_length = plaintext.size() - (mac_size + pad_size + iv_size); @@ -242,7 +242,7 @@ size_t Record_Reader::get_record(byte& msg_type, SecureVector<byte> computed_mac = mac->final(); - if(recieved_mac != computed_mac) + if(received_mac != computed_mac) throw TLS_Exception(BAD_RECORD_MAC, "Record_Reader: MAC failure"); msg_type = header[0]; diff --git a/src/ssl/socket.h b/src/ssl/socket.h deleted file mode 100644 index 6d88bd48a..000000000 --- a/src/ssl/socket.h +++ /dev/null @@ -1,46 +0,0 @@ -/* -* Socket Interface -* (C) 2004-2006 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#ifndef BOTAN_TLS_SOCKET_H__ -#define BOTAN_TLS_SOCKET_H__ - -#include <botan/types.h> -#include <string> - -namespace Botan { - -/** -* Socket Base Class -*/ -class BOTAN_DLL Socket - { - public: - virtual size_t read(byte[], size_t) = 0; - virtual void write(const byte[], size_t) = 0; - - virtual std::string peer_id() const = 0; - - virtual void close() = 0; - - virtual ~Socket() {} - }; - -/** -* Server Socket Base Class -*/ -class BOTAN_DLL Server_Socket - { - public: - virtual Socket* accept() = 0; - virtual void close() = 0; - - virtual ~Server_Socket() {} - }; - -} - -#endif diff --git a/src/ssl/tls_alerts.h b/src/ssl/tls_alerts.h index f189cf507..241599aa8 100644 --- a/src/ssl/tls_alerts.h +++ b/src/ssl/tls_alerts.h @@ -15,7 +15,7 @@ namespace Botan { /** * SSL/TLS Alert Message */ -class BOTAN_DLL Alert +class Alert { public: /** diff --git a/src/ssl/tls_client.cpp b/src/ssl/tls_client.cpp index 03c8117cc..eeb99e24d 100644 --- a/src/ssl/tls_client.cpp +++ b/src/ssl/tls_client.cpp @@ -294,7 +294,7 @@ void TLS_Client::state_machine() } } else - throw Unexpected_Message("Unknown message type recieved"); + throw Unexpected_Message("Unknown message type received"); } /** @@ -440,7 +440,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, is_rsa = true; else throw TLS_Exception(UNSUPPORTED_CERTIFICATE, - "Unknown key type recieved in server kex"); + "Unknown key type received in server kex"); if((is_dsa && state->suite.sig_type() != TLS_ALGO_SIGNER_DSA) || (is_rsa && state->suite.sig_type() != TLS_ALGO_SIGNER_RSA)) @@ -469,7 +469,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, is_rsa = true; else throw TLS_Exception(HANDSHAKE_FAILURE, - "Unknown key type recieved in server kex"); + "Unknown key type received in server kex"); if((is_dh && state->suite.kex_type() != TLS_ALGO_KEYEXCH_DH) || (is_rsa && state->suite.kex_type() != TLS_ALGO_KEYEXCH_RSA)) @@ -560,7 +560,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, active = true; } else - throw Unexpected_Message("Unknown handshake message recieved"); + throw Unexpected_Message("Unknown handshake message received"); } /** diff --git a/src/ssl/tls_exceptn.h b/src/ssl/tls_exceptn.h index a9efc718a..37b9c0d27 100644 --- a/src/ssl/tls_exceptn.h +++ b/src/ssl/tls_exceptn.h @@ -32,7 +32,7 @@ class BOTAN_DLL TLS_Exception : public Exception /** * Unexpected_Message Exception */ -struct Unexpected_Message : public TLS_Exception +struct BOTAN_DLL Unexpected_Message : public TLS_Exception { Unexpected_Message(const std::string& err) : TLS_Exception(UNEXPECTED_MESSAGE, err) {} diff --git a/src/ssl/tls_handshake_hash.h b/src/ssl/tls_handshake_hash.h index ceaa55584..cea612a71 100644 --- a/src/ssl/tls_handshake_hash.h +++ b/src/ssl/tls_handshake_hash.h @@ -17,7 +17,7 @@ using namespace Botan; /** * TLS Handshake Hash */ -class BOTAN_DLL HandshakeHash +class HandshakeHash { public: void update(const byte in[], size_t length) diff --git a/src/ssl/tls_messages.h b/src/ssl/tls_messages.h index c5d4d8cb8..0b3553ac0 100644 --- a/src/ssl/tls_messages.h +++ b/src/ssl/tls_messages.h @@ -21,7 +21,7 @@ namespace Botan { /** * TLS Handshake Message Base Class */ -class BOTAN_DLL HandshakeMessage +class HandshakeMessage { public: void send(Record_Writer&, HandshakeHash&) const; @@ -38,7 +38,7 @@ class BOTAN_DLL HandshakeMessage /** * Client Hello Message */ -class BOTAN_DLL Client_Hello : public HandshakeMessage +class Client_Hello : public HandshakeMessage { public: Handshake_Type type() const { return CLIENT_HELLO; } @@ -80,7 +80,7 @@ class BOTAN_DLL Client_Hello : public HandshakeMessage /** * Client Key Exchange Message */ -class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage +class Client_Key_Exchange : public HandshakeMessage { public: Handshake_Type type() const { return CLIENT_KEX; } @@ -112,7 +112,7 @@ class BOTAN_DLL Client_Key_Exchange : public HandshakeMessage /** * Certificate Message */ -class BOTAN_DLL Certificate : public HandshakeMessage +class Certificate : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE; } @@ -130,7 +130,7 @@ class BOTAN_DLL Certificate : public HandshakeMessage /** * Certificate Request Message */ -class BOTAN_DLL Certificate_Req : public HandshakeMessage +class Certificate_Req : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE_REQUEST; } @@ -157,7 +157,7 @@ class BOTAN_DLL Certificate_Req : public HandshakeMessage /** * Certificate Verify Message */ -class BOTAN_DLL Certificate_Verify : public HandshakeMessage +class Certificate_Verify : public HandshakeMessage { public: Handshake_Type type() const { return CERTIFICATE_VERIFY; } @@ -179,7 +179,7 @@ class BOTAN_DLL Certificate_Verify : public HandshakeMessage /** * Finished Message */ -class BOTAN_DLL Finished : public HandshakeMessage +class Finished : public HandshakeMessage { public: Handshake_Type type() const { return FINISHED; } @@ -205,7 +205,7 @@ class BOTAN_DLL Finished : public HandshakeMessage /** * Hello Request Message */ -class BOTAN_DLL Hello_Request : public HandshakeMessage +class Hello_Request : public HandshakeMessage { public: Handshake_Type type() const { return HELLO_REQUEST; } @@ -220,7 +220,7 @@ class BOTAN_DLL Hello_Request : public HandshakeMessage /** * Server Hello Message */ -class BOTAN_DLL Server_Hello : public HandshakeMessage +class Server_Hello : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_HELLO; } @@ -250,7 +250,7 @@ class BOTAN_DLL Server_Hello : public HandshakeMessage /** * Server Key Exchange Message */ -class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage +class Server_Key_Exchange : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_KEX; } @@ -277,7 +277,7 @@ class BOTAN_DLL Server_Key_Exchange : public HandshakeMessage /** * Server Hello Done Message */ -class BOTAN_DLL Server_Hello_Done : public HandshakeMessage +class Server_Hello_Done : public HandshakeMessage { public: Handshake_Type type() const { return SERVER_HELLO_DONE; } diff --git a/src/ssl/tls_record.h b/src/ssl/tls_record.h index b4c052a1c..7d3bc4c6a 100644 --- a/src/ssl/tls_record.h +++ b/src/ssl/tls_record.h @@ -1,3 +1,4 @@ +1 /* * TLS Record Handling * (C) 2004-2010 Jack Lloyd diff --git a/src/ssl/tls_server.cpp b/src/ssl/tls_server.cpp index 20e98797f..1f301e6b1 100644 --- a/src/ssl/tls_server.cpp +++ b/src/ssl/tls_server.cpp @@ -262,7 +262,7 @@ void TLS_Server::state_machine() } } else - throw Unexpected_Message("Unknown message type recieved"); + throw Unexpected_Message("Unknown message type received"); } /* @@ -471,7 +471,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, active = true; } else - throw Unexpected_Message("Unknown handshake message recieved"); + throw Unexpected_Message("Unknown handshake message received"); } /* diff --git a/src/ssl/unix_socket/info.txt b/src/ssl/unix_socket/info.txt deleted file mode 100644 index 15fc50f5b..000000000 --- a/src/ssl/unix_socket/info.txt +++ /dev/null @@ -1,20 +0,0 @@ -define UNIX_SOCKET - -<source> -unx_sock.cpp -</source> - -<header:public> -unx_sock.h -</header:public> - -<requires> -ssl -</requires> - -<os> -linux -freebsd -netbsd -solaris -</os> diff --git a/src/ssl/unix_socket/unx_sock.cpp b/src/ssl/unix_socket/unx_sock.cpp deleted file mode 100644 index a7c19b70c..000000000 --- a/src/ssl/unix_socket/unx_sock.cpp +++ /dev/null @@ -1,206 +0,0 @@ -/* -* Unix Socket -* (C) 2004-2010 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#include <botan/unx_sock.h> -#include <botan/exceptn.h> - -#include <sys/types.h> -#include <sys/socket.h> -#include <sys/time.h> -#include <netinet/in.h> -#include <netdb.h> -#include <unistd.h> -#include <errno.h> -#include <string.h> - -namespace Botan { - -/** -* Unix Socket Constructor -*/ -Unix_Socket::Unix_Socket(const std::string& host, u16bit port) : peer(host) - { - sockfd = -1; - - hostent* host_addr = ::gethostbyname(host.c_str()); - - if(host_addr == 0) - throw Stream_IO_Error("Unix_Socket: gethostbyname failed for " + host); - if(host_addr->h_addrtype != AF_INET) // FIXME - throw Stream_IO_Error("Unix_Socket: " + host + " has IPv6 address"); - - int fd = ::socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) - throw Stream_IO_Error("Unix_Socket: Unable to acquire socket"); - - sockaddr_in socket_info; - ::memset(&socket_info, 0, sizeof(socket_info)); - socket_info.sin_family = AF_INET; - socket_info.sin_port = htons(port); - - ::memcpy(&socket_info.sin_addr, - host_addr->h_addr, - host_addr->h_length); - - socket_info.sin_addr = *(struct in_addr*)host_addr->h_addr; // FIXME - - if(::connect(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0) - { - ::close(fd); - throw Stream_IO_Error("Unix_Socket: connect failed"); - } - - sockfd = fd; - } - -/** -* Unix Socket Constructor -*/ -Unix_Socket::Unix_Socket(int fd, const std::string& peer_id) - { - sockfd = fd; - peer = peer_id; - } - -/** -* Read from a Unix socket -*/ -size_t Unix_Socket::read(byte buf[], size_t length) - { - if(sockfd == -1) - throw Stream_IO_Error("Unix_Socket::read: Socket not connected"); - - size_t got = 0; - - while(length) - { - ssize_t this_time = ::recv(sockfd, buf + got, length, MSG_NOSIGNAL); - - if(this_time == 0) - break; - - if(this_time == -1) - { - if(errno == EINTR) - this_time = 0; - else - throw Stream_IO_Error("Unix_Socket::read: Socket read failed"); - } - - got += this_time; - length -= this_time; - } - return got; - } - -/** -* Write to a Unix socket -*/ -void Unix_Socket::write(const byte buf[], size_t length) - { - if(sockfd == -1) - throw Stream_IO_Error("Unix_Socket::write: Socket not connected"); - - size_t offset = 0; - while(length) - { - ssize_t sent = ::send(sockfd, buf + offset, length, MSG_NOSIGNAL); - - if(sent == -1) - { - if(errno == EINTR) - sent = 0; - else - throw Stream_IO_Error("Unix_Socket::write: Socket write failed"); - } - - offset += sent; - length -= sent; - } - } - -/** -* Close a Unix socket -*/ -void Unix_Socket::close() - { - if(sockfd != -1) - { - if(::close(sockfd) != 0) - throw Stream_IO_Error("Unix_Socket::close failed"); - sockfd = -1; - } - } - -/** -* Return the peer's name -*/ -std::string Unix_Socket::peer_id() const - { - return peer; - } - -/** -* Unix Server Socket Constructor -*/ -Unix_Server_Socket::Unix_Server_Socket(u16bit port) - { - sockfd = -1; - - int fd = ::socket(PF_INET, SOCK_STREAM, 0); - if(fd == -1) - throw Stream_IO_Error("Unix_Server_Socket: Unable to acquire socket"); - - sockaddr_in socket_info; - ::memset(&socket_info, 0, sizeof(socket_info)); - socket_info.sin_family = AF_INET; - socket_info.sin_port = htons(port); - - // FIXME: support limiting listeners - socket_info.sin_addr.s_addr = INADDR_ANY; - - if(::bind(fd, (sockaddr*)&socket_info, sizeof(struct sockaddr)) != 0) - { - ::close(fd); - throw Stream_IO_Error("Unix_Server_Socket: bind failed"); - } - - if(listen(fd, 100) != 0) // FIXME: totally arbitrary - { - ::close(fd); - throw Stream_IO_Error("Unix_Server_Socket: listen failed"); - } - - sockfd = fd; - } - -/** -* Close a Unix socket -*/ -void Unix_Server_Socket::close() - { - if(sockfd != -1) - { - if(::close(sockfd) != 0) - throw Stream_IO_Error("Unix_Server_Socket::close failed"); - sockfd = -1; - } - } - -/** -* Accept a new connection -*/ -Socket* Unix_Server_Socket::accept() - { - // FIXME: grab IP of remote side, use gethostbyaddr, store as peer_id - int retval = ::accept(sockfd, 0, 0); - if(retval == -1) - throw Stream_IO_Error("Unix_Server_Socket: accept failed"); - return new Unix_Socket(retval); - } - -} diff --git a/src/ssl/unix_socket/unx_sock.h b/src/ssl/unix_socket/unx_sock.h deleted file mode 100644 index 58c7ada69..000000000 --- a/src/ssl/unix_socket/unx_sock.h +++ /dev/null @@ -1,62 +0,0 @@ -/* -* Unix Socket -* (C) 2004-2006 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#ifndef BOTAN_TLS_SOCKET_UNIX_H__ -#define BOTAN_TLS_SOCKET_UNIX_H__ - -#include <botan/socket.h> - -namespace Botan { - -/** - FIXME: the current socket interface is totally unusable - It has to handle (cleanly): - - TCP, UDP, and SCTP, where UDP is only usable with DTLS and - TCP/SCTP is only usable with TLS. - - Alternate socket interfaces (ACE, Netxx, whatever) with - minimal wrapping needed. -*/ - - -/** -* Unix Socket Base Class -*/ -class BOTAN_DLL Unix_Socket : public Socket - { - public: - size_t read(byte[], size_t); - void write(const byte[], size_t); - - std::string peer_id() const; - - void close(); - Unix_Socket(int, const std::string& = ""); - Unix_Socket(const std::string&, u16bit); - ~Unix_Socket() { close(); } - private: - std::string peer; - int sockfd; - }; - -/** -* Unix Server Socket Base Class -*/ -class BOTAN_DLL Unix_Server_Socket : public Server_Socket - { - public: - Socket* accept(); - void close(); - - Unix_Server_Socket(u16bit); - ~Unix_Server_Socket() { close(); } - private: - int sockfd; - }; - -} - -#endif diff --git a/src/stream/ctr/ctr.cpp b/src/stream/ctr/ctr.cpp index d221dc441..3a370eca3 100644 --- a/src/stream/ctr/ctr.cpp +++ b/src/stream/ctr/ctr.cpp @@ -1,6 +1,6 @@ /* * Counter mode -* (C) 1999-2010 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * * Distributed under the terms of the Botan license */ @@ -85,20 +85,21 @@ void CTR_BE::set_iv(const byte iv[], size_t iv_len) if(!valid_iv_length(iv_len)) throw Invalid_IV_Length(name(), iv_len); - const size_t BLOCK_SIZE = permutation->block_size(); + const size_t bs = permutation->block_size(); zeroise(counter); counter.copy(0, iv, iv_len); + /* + * Set counter blocks to IV, IV + 1, ... IV + 255 + */ for(size_t i = 1; i != 256; ++i) { - counter.copy(i*BLOCK_SIZE, - &counter[(i-1)*BLOCK_SIZE], - BLOCK_SIZE); + counter.copy(i*bs, &counter[(i-1)*bs], bs); - for(size_t j = 0; j != BLOCK_SIZE; ++j) - if(++counter[i*BLOCK_SIZE + (BLOCK_SIZE-1-j)]) + for(size_t j = 0; j != bs; ++j) + if(++counter[i*bs + (bs - 1 - j)]) break; } @@ -111,12 +112,17 @@ void CTR_BE::set_iv(const byte iv[], size_t iv_len) */ void CTR_BE::increment_counter() { - const size_t BLOCK_SIZE = permutation->block_size(); + const size_t bs = permutation->block_size(); + /* + * Each counter value always needs to be incremented by 256, + * so we don't touch the lowest byte and instead treat it as + * an increment of one starting with the next byte. + */ for(size_t i = 0; i != 256; ++i) { - for(size_t j = 1; j != BLOCK_SIZE; ++j) - if(++counter[i*BLOCK_SIZE + (BLOCK_SIZE-1-j)]) + for(size_t j = 1; j != bs; ++j) + if(++counter[i*bs + (bs - 1 - j)]) break; } diff --git a/src/utils/asm_ia32/asm_macr_ia32.h b/src/utils/asm_x86_32/asm_x86_32.h index 2ea69512b..d5482c419 100644 --- a/src/utils/asm_ia32/asm_macr_ia32.h +++ b/src/utils/asm_x86_32/asm_x86_32.h @@ -1,12 +1,12 @@ /* -* Assembly Macros +* Assembly Macros for 32-bit x86 * (C) 1999-2008 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_IA32_ASM_MACROS_H__ -#define BOTAN_IA32_ASM_MACROS_H__ +#ifndef BOTAN_ASM_MACROS_X86_32_H__ +#define BOTAN_ASM_MACROS_X86_32_H__ /* * General/Global Macros diff --git a/src/utils/asm_ia32/info.txt b/src/utils/asm_x86_32/info.txt index 997d51b8c..21244968f 100644 --- a/src/utils/asm_ia32/info.txt +++ b/src/utils/asm_x86_32/info.txt @@ -1,11 +1,11 @@ load_on dep <header:internal> -asm_macr_ia32.h +asm_x86_32.h </header:internal> <arch> -ia32 +x86_32 </arch> # ELF systems @@ -19,7 +19,6 @@ solaris </os> <cc> -clang gcc icc </cc> diff --git a/src/utils/asm_amd64/asm_macr_amd64.h b/src/utils/asm_x86_64/asm_x86_64.h index 287fa3e88..7abc1f392 100644 --- a/src/utils/asm_amd64/asm_macr_amd64.h +++ b/src/utils/asm_x86_64/asm_x86_64.h @@ -1,12 +1,12 @@ /* -* Assembly Macros +* Assembly Macros for 64-bit x86 * (C) 1999-2008 Jack Lloyd * * Distributed under the terms of the Botan license */ -#ifndef BOTAN_AMD64_ASM_MACROS_H__ -#define BOTAN_AMD64_ASM_MACROS_H__ +#ifndef BOTAN_ASM_MACROS_X86_64_H__ +#define BOTAN_ASM_MACROS_X86_64_H__ /* * General/Global Macros diff --git a/src/utils/asm_amd64/info.txt b/src/utils/asm_x86_64/info.txt index 404aeca7b..3173f3b14 100644 --- a/src/utils/asm_amd64/info.txt +++ b/src/utils/asm_x86_64/info.txt @@ -1,11 +1,11 @@ load_on dep <header:internal> -asm_macr_amd64.h +asm_x86_64.h </header:internal> <arch> -amd64 +x86_64 </arch> <cc> diff --git a/src/utils/bswap.h b/src/utils/bswap.h index 6dfed0ba9..9d2c9bc28 100644 --- a/src/utils/bswap.h +++ b/src/utils/bswap.h @@ -1,6 +1,6 @@ /* * Byte Swapping Operations -* (C) 1999-2008 Jack Lloyd +* (C) 1999-2011 Jack Lloyd * (C) 2007 Yves Jerschow * * Distributed under the terms of the Botan license @@ -21,38 +21,55 @@ namespace Botan { /** * Swap a 16 bit integer */ -inline u16bit reverse_bytes(u16bit input) +inline u16bit reverse_bytes(u16bit val) { - return rotate_left(input, 8); + return rotate_left(val, 8); } /** * Swap a 32 bit integer */ -inline u32bit reverse_bytes(u32bit input) +inline u32bit reverse_bytes(u32bit val) { -#if BOTAN_GCC_VERSION >= 430 +#if BOTAN_GCC_VERSION >= 430 && !defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + /* + GCC intrinsic added in 4.3, works for a number of CPUs - // GCC intrinsic added in 4.3, works for a number of CPUs - return __builtin_bswap32(input); + However avoid under ARM, as it branches to a function in libgcc + instead of generating inline asm, so slower even than the generic + rotate version below. + */ + return __builtin_bswap32(val); #elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_X86_FAMILY) // GCC-style inline assembly for x86 or x86-64 - asm("bswapl %0" : "=r" (input) : "0" (input)); - return input; + asm("bswapl %0" : "=r" (val) : "0" (val)); + return val; + +#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_CPU_IS_ARM_FAMILY) + + asm ("eor r3, %1, %1, ror #16\n\t" + "bic r3, r3, #0x00FF0000\n\t" + "mov %0, %1, ror #8\n\t" + "eor %0, %0, r3, lsr #8" + : "=r" (val) + : "0" (val) + : "r3", "cc"); + + return val; -#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_IA32) +#elif defined(_MSC_VER) && defined(BOTAN_TARGET_ARCH_IS_X86_32) // Visual C++ inline asm for 32-bit x86, by Yves Jerschow - __asm mov eax, input; + __asm mov eax, val; __asm bswap eax; #else // Generic implementation - return (rotate_right(input, 8) & 0xFF00FF00) | - (rotate_left (input, 8) & 0x00FF00FF); + return (rotate_right(val, 8) & 0xFF00FF00) | + (rotate_left (val, 8) & 0x00FF00FF); #endif } @@ -60,17 +77,17 @@ inline u32bit reverse_bytes(u32bit input) /** * Swap a 64 bit integer */ -inline u64bit reverse_bytes(u64bit input) +inline u64bit reverse_bytes(u64bit val) { #if BOTAN_GCC_VERSION >= 430 // GCC intrinsic added in 4.3, works for a number of CPUs - return __builtin_bswap64(input); + return __builtin_bswap64(val); -#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_AMD64) +#elif BOTAN_USE_GCC_INLINE_ASM && defined(BOTAN_TARGET_ARCH_IS_X86_64) // GCC-style inline assembly for x86-64 - asm("bswapq %0" : "=r" (input) : "0" (input)); - return input; + asm("bswapq %0" : "=r" (val) : "0" (val)); + return val; #else /* Generic implementation. Defined in terms of 32-bit bswap so any @@ -78,8 +95,8 @@ inline u64bit reverse_bytes(u64bit input) * useful for 32-bit x86). */ - u32bit hi = static_cast<u32bit>(input >> 32); - u32bit lo = static_cast<u32bit>(input); + u32bit hi = static_cast<u32bit>(val >> 32); + u32bit lo = static_cast<u32bit>(val); hi = reverse_bytes(hi); lo = reverse_bytes(lo); diff --git a/src/utils/cpuid.cpp b/src/utils/cpuid.cpp index 9ea9e82ad..cb6fdaba5 100644 --- a/src/utils/cpuid.cpp +++ b/src/utils/cpuid.cpp @@ -30,8 +30,21 @@ // Only available starting in GCC 4.3 #include <cpuid.h> - #define CALL_CPUID(type, out) \ - do { __get_cpuid(type, out, out+1, out+2, out+3); } while(0); + +namespace { + + /* + * Prevent inlining to work around GCC bug 44174 + */ + void __attribute__((__noinline__)) call_gcc_cpuid(Botan::u32bit type, + Botan::u32bit out[4]) + { + __get_cpuid(type, out, out+1, out+2, out+3); + } + + #define CALL_CPUID call_gcc_cpuid + +} #else #warning "No method of calling CPUID for this compiler" @@ -149,9 +162,9 @@ void CPUID::initialize() u32bit cpuid[4] = { 0 }; CALL_CPUID(1, cpuid); - x86_processor_flags = ((u64bit)cpuid[2] << 32) | cpuid[3]; + x86_processor_flags = (static_cast<u64bit>(cpuid[2]) << 32) | cpuid[3]; -#if defined(BOTAN_TARGET_ARCH_IS_AMD64) +#if defined(BOTAN_TARGET_ARCH_IS_X86_64) /* * If we don't have access to CPUID, we can still safely assume that * any x86-64 processor has SSE2. diff --git a/src/utils/dyn_load/info.txt b/src/utils/dyn_load/info.txt index 512410460..6d74acb86 100644 --- a/src/utils/dyn_load/info.txt +++ b/src/utils/dyn_load/info.txt @@ -1,10 +1,11 @@ define DYNAMIC_LOADER <os> -linux freebsd -openbsd +linux netbsd +openbsd +qnx solaris windows </os> diff --git a/src/utils/mlock.cpp b/src/utils/mlock.cpp index cd92860df..800425665 100644 --- a/src/utils/mlock.cpp +++ b/src/utils/mlock.cpp @@ -31,7 +31,7 @@ bool has_mlock() bool lock_mem(void* ptr, size_t bytes) { #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - return (::mlock((char*)ptr, bytes) == 0); + return (::mlock(static_cast<char*>(ptr), bytes) == 0); #elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK) return (::VirtualLock(ptr, bytes) != 0); #else @@ -45,7 +45,7 @@ bool lock_mem(void* ptr, size_t bytes) void unlock_mem(void* ptr, size_t bytes) { #if defined(BOTAN_TARGET_OS_HAS_POSIX_MLOCK) - ::munlock((char*)ptr, bytes); + ::munlock(static_cast<char*>(ptr), bytes); #elif defined(BOTAN_TARGET_OS_HAS_WIN32_VIRTUAL_LOCK) ::VirtualUnlock(ptr, bytes); #endif diff --git a/src/utils/simd_32/simd_32.h b/src/utils/simd_32/simd_32.h deleted file mode 100644 index e2c483d20..000000000 --- a/src/utils/simd_32/simd_32.h +++ /dev/null @@ -1,49 +0,0 @@ -/* -* Lightweight wrappers for SIMD operations -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - -#ifndef BOTAN_SIMD_32_H__ -#define BOTAN_SIMD_32_H__ - -#include <botan/types.h> -#include <botan/rotate.h> - -#if defined(BOTAN_TARGET_CPU_HAS_SSE2) && !defined(BOTAN_NO_SSE_INTRINSICS) - - #include <botan/internal/simd_sse.h> - namespace Botan { typedef SIMD_SSE2 SIMD_32; } - -#elif defined(BOTAN_TARGET_CPU_HAS_ALTIVEC) - - #include <botan/internal/simd_altivec.h> - namespace Botan { typedef SIMD_Altivec SIMD_32; } - -#else - - #include <botan/internal/simd_scalar.h> - namespace Botan { typedef SIMD_Scalar SIMD_32; } - -#endif - -namespace Botan { - -template<> -inline SIMD_32 rotate_left(SIMD_32 x, size_t rot) - { - x.rotate_left(rot); - return x; - } - -template<> -inline SIMD_32 rotate_right(SIMD_32 x, size_t rot) - { - x.rotate_right(rot); - return x; - } - -} - -#endif diff --git a/src/wrap/python/rsa.cpp b/src/wrap/python/rsa.cpp index 5e2e0ba30..dc6053503 100644 --- a/src/wrap/python/rsa.cpp +++ b/src/wrap/python/rsa.cpp @@ -27,6 +27,8 @@ class Py_RSA_PrivateKey Py_RSA_PrivateKey(std::string pem_str, Python_RandomNumberGenerator& rng, std::string pass); + Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng); Py_RSA_PrivateKey(u32bit bits, Python_RandomNumberGenerator& rng); ~Py_RSA_PrivateKey() { delete rsa_key; } @@ -87,6 +89,21 @@ Py_RSA_PrivateKey::Py_RSA_PrivateKey(u32bit bits, } Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, + Python_RandomNumberGenerator& rng) + { + DataSource_Memory in(pem_str); + + Private_Key* pkcs8_key = + PKCS8::load_key(in, + rng.get_underlying_rng()); + + rsa_key = dynamic_cast<RSA_PrivateKey*>(pkcs8_key); + + if(!rsa_key) + throw std::invalid_argument("Key is not an RSA key"); + } + +Py_RSA_PrivateKey::Py_RSA_PrivateKey(std::string pem_str, Python_RandomNumberGenerator& rng, std::string passphrase) { @@ -195,6 +212,7 @@ void export_rsa() python::class_<Py_RSA_PrivateKey> ("RSA_PrivateKey", python::init<std::string, Python_RandomNumberGenerator&, std::string>()) + .def(python::init<std::string, Python_RandomNumberGenerator&>()) .def(python::init<u32bit, Python_RandomNumberGenerator&>()) .def("to_string", &Py_RSA_PrivateKey::to_string) .def("to_ber", &Py_RSA_PrivateKey::to_ber) |