# # delete_file "botan/base_eng.h" # # delete_file "botan/def_eng.cpp" # # delete_file "botan/dl_get.cpp" # # delete_file "botan/fips_rng.cpp" # # delete_file "botan/fips_rng.h" # # delete_file "botan/secalloc.h" # # delete_file "botan/x917_rng.cpp" # # delete_file "botan/x917_rng.h" # # add_file "botan/def_alg.cpp" # # add_file "botan/def_mode.cpp" # # add_file "botan/x931_rng.cpp" # # add_file "botan/x931_rng.h" # # patch "ChangeLog" # from [54073c6fe47f02b9eccaac4f8c10adf34948db2b] # to [9732c2da22342d073b8540ea3a7ff22c4eb43826] # # patch "Makefile.am" # from [5f3e4aae1a4f7f3de4b7336190009b720b04432c] # to [7455afb9ba6b28c47aaee7517eb6cb892074e45f] # # patch "botan/algolist.cpp" # from [e73a701e948afdcb723a29f89e88dbc793764d76] # to [59b2c8ae247e6e6791f5bf1f17fa447c2f887fc6] # # patch "botan/algolist.h" # from [ef9d8f0eb6210c1b316298d4ca6f53013db1cef0] # to [09a35cd375bf11ebeb7b6231db219ef73e9ee645] # # patch "botan/base.cpp" # from [3fcd48a2b31dc404fcc861f0c1150d764f276e1f] # to [782844d8ab6ab22b787eadda7392a3e23445662e] # # patch "botan/base.h" # from [7223b306fb862c20a89c03a1460c366aca16fc6f] # to [de06367b6bc1d60bfe3dbaeee2eb958757dbd0d1] # # patch "botan/def_alg.cpp" # from [] # to [899abd4469df860e8025d1fa14dca295eda71196] # # patch "botan/def_mode.cpp" # from [] # to [a06fee4078dafe7958ae460df501247ad6788178] # # patch "botan/engine.h" # from [e564fba257a1af6a72dfb4e68dfa387846189ee0] # to [bf1afaedad957edbc26e34b4a0490cc156e6789c] # # patch "botan/init.cpp" # from [2b67a947e2133a4a9fbd93774c2a67a5d7cf5344] # to [e654bf9fc3a87be25a40bf183a843d6be139de98] # # patch "botan/mem_pool.cpp" # from [e2303f64ab0a279072bdbe59313ed10842702c20] # to [cc72eb332ab2c10e96d65332b22dec4d46fc5621] # # patch "botan/mem_pool.h" # from [79cc34c1b88e2ab2419e609d8c0c208a490f913e] # to [96e6c390b555075bc0335932142680360ef49f8b] # # patch "botan/mode_pad.h" # from [d33d5fd3116799e3acc4510bbe8ec00b9ecf203a] # to [0ec59170055c96be7b3e7a70aa3a4e25baefbfcd] # # patch "botan/pipe_rw.cpp" # from [a26836077fabc8d34bc89c1b96876391494fca1e] # to [d93a14d30e1feb8c498c90ddf0c4596716994536] # # patch "botan/pkcs8.cpp" # from [6d12f636a9d038c815ba1a19ed4b5dafa2f4a052] # to [7f055238216229a265c733ab7e79edc252a54d93] # # patch "botan/pubkey.cpp" # from [a79e182ed1aabf231ff5fd910240fd9e2fc517c3] # to [ab5b94948a910abe6d83b35148ac6c460f790a11] # # patch "botan/pubkey.h" # from [eb5a007ee85161d484036b2325def6afa731be7c] # to [dfcf36d1bc7eb006d8a593eb5f5a4a7e876171b8] # # patch "botan/randpool.cpp" # from [5d45a17b8b6f6311a3dd39fa0e1e8825164d8204] # to [4cd57635f9b7a10426ff4ce53e630dbe86358083] # # patch "botan/randpool.h" # from [8c3837ac3ca62bdbf5e584ca350aee650df6dd56] # to [9e5e53dac9493dd855fa05a563fb80769d5b8988] # # patch "botan/rng.cpp" # from [a87b1336b2275f4083f991b28ec602681eb17e1b] # to [6241291f961c12f562c194b7cd2a57a7fa41e3f9] # # patch "botan/sha160.cpp" # from [f3c39163a2977d63f172f75ffe1891f2a2832239] # to [283762dff556d9a03a0921634c178e7d5e84bda5] # # patch "botan/sha160.h" # from [e2ad1d38fddf6502076da1b95be4eafbbc7a54a2] # to [ed9b5ecfb4120f6b0c8f5c930705c56959944ef9] # # patch "botan/x931_rng.cpp" # from [] # to [7f93d680b7e6c71a3b9fcf1f8af051062cdddb16] # # patch "botan/x931_rng.h" # from [] # to [867850aff3df63007e12886ed6d00c338496b93e] # ======================================================================== --- ChangeLog 54073c6fe47f02b9eccaac4f8c10adf34948db2b +++ ChangeLog 9732c2da22342d073b8540ea3a7ff22c4eb43826 @@ -1,3 +1,7 @@ +2005-10-04 Matt Johnston + + * botan/, Makefile.am: update to Botan 1.4.7 + 2005-10-03 Nathaniel Smith * monotone.texi (Automation): Clean up formatting and description ======================================================================== --- Makefile.am 5f3e4aae1a4f7f3de4b7336190009b720b04432c +++ Makefile.am 7455afb9ba6b28c47aaee7517eb6cb892074e45f @@ -79,17 +79,17 @@ botan/buf_filt.cpp botan/cbc.cpp botan/certstore.cpp \ botan/cfb.cpp botan/charset.cpp botan/conf.cpp botan/crc32.cpp \ botan/crl_ent.cpp botan/ctr.cpp botan/cts.cpp \ - botan/data_snk.cpp botan/data_src.cpp botan/def_eng.cpp \ + botan/data_snk.cpp botan/data_src.cpp \ botan/def_ops.cpp botan/defalloc.cpp botan/der_code.cpp \ botan/der_enc.cpp botan/divide.cpp botan/dl_algo.cpp \ - botan/dl_get.cpp botan/dl_group.cpp botan/dl_param.cpp \ + botan/dl_group.cpp botan/dl_param.cpp \ botan/dl_cache.cpp \ botan/dlies.cpp botan/eax.cpp botan/ecb.cpp botan/eme1.cpp \ botan/eme_pkcs.cpp botan/emsa1.cpp botan/emsa2.cpp \ botan/emsa3.cpp botan/emsa4.cpp botan/emsa_raw.cpp \ botan/eng_base.cpp botan/engine.cpp botan/es_file.cpp \ botan/exceptn.cpp botan/filter.cpp botan/filters.cpp \ - botan/fips140.cpp botan/fips_rng.cpp botan/fused.cpp \ + botan/fips140.cpp botan/fused.cpp \ botan/get_algo.cpp botan/get_enc.cpp botan/get_pbe.cpp \ botan/gzip.cpp botan/hash_id.cpp botan/hex.cpp botan/hmac.cpp \ botan/if_algo.cpp botan/inifile.cpp botan/init.cpp \ @@ -113,7 +113,8 @@ botan/ui.cpp botan/util.cpp botan/x509_ca.cpp \ botan/x509_crl.cpp botan/x509_key.cpp botan/x509_obj.cpp \ botan/x509cert.cpp botan/x509find.cpp botan/x509opt.cpp \ - botan/x509self.cpp botan/x509stor.cpp botan/x917_rng.cpp \ + botan/x509self.cpp botan/x509stor.cpp \ + botan/def_alg.cpp botan/def_mode.cpp \ \ botan/aes.h botan/botan.h botan/def_eng.h botan/es_win32.h \ botan/lookup.h botan/omac.h botan/randpool.h botan/version.h \ @@ -127,14 +128,14 @@ botan/certstor.h botan/dlies.h botan/fips140.h botan/mgf1.h \ botan/pem.h botan/s2k.h botan/x509_key.h botan/asn1_obj.h \ botan/cfb.h botan/dl_param.h botan/fips_rng.h botan/modebase.h \ - botan/pipe.h botan/secalloc.h botan/x509_obj.h \ + botan/pipe.h botan/x509_obj.h \ botan/asn1_oid.h botan/conf.h botan/eax.h botan/gzip.h \ botan/mode_pad.h botan/pk_algs.h botan/secmem.h \ botan/x509self.h botan/barrett.h botan/config.h botan/ecb.h \ botan/hex.h botan/mod_exp.h botan/pk_core.h botan/secqueue.h \ botan/x509stor.h botan/base64.h botan/crc32.h botan/eme.h \ botan/hmac.h botan/mp_core.h botan/pkcs10.h botan/sha160.h \ - botan/x917_rng.h botan/base_eng.h botan/crl_ent.h botan/emsa.h \ + botan/crl_ent.h botan/emsa.h \ botan/if_algo.h botan/mp_madd.h botan/pkcs8.h botan/socket.h \ botan/x919_mac.h botan/basefilt.h botan/ctr.h botan/engine.h \ botan/init.h botan/mp_types.h botan/pk_filts.h botan/symkey.h \ @@ -145,7 +146,8 @@ botan/data_src.h botan/es_egd.h botan/look_add.h botan/ofb.h \ botan/pk_util.h botan/ui.h botan/blinding.h botan/defalloc.h \ botan/es_file.h botan/look_pk.h botan/oids.h botan/pubkey.h \ - botan/util.h botan/charset.h botan/hash_id.h + botan/util.h botan/charset.h botan/hash_id.h \ + botan/x931_rng.cpp botan/x931_rng.h BOOST_SANDBOX_SOURCES = \ ======================================================================== --- botan/algolist.cpp e73a701e948afdcb723a29f89e88dbc793764d76 +++ botan/algolist.cpp 59b2c8ae247e6e6791f5bf1f17fa447c2f887fc6 @@ -1,19 +1,10 @@ /************************************************* * Algorithms List Source File * -* (C) 1999-2004 The Botan Project * +* (C) 1999-2005 The Botan Project * *************************************************/ #include -#include - -#include - -#include -#include - -#include - #include namespace Botan { @@ -21,125 +12,27 @@ namespace Algolist { /************************************************* -* Some macros to simplify control flow * +* Attempt to get a string to key object * *************************************************/ -#define HANDLE_TYPE_NO_ARGS(NAME, TYPE) \ - if(algo_name == NAME) \ - { \ - if(name.size() == 1) \ - return new TYPE; \ - throw Invalid_Algorithm_Name(algo_spec); \ - } - -#define HANDLE_TYPE_ONE_U32BIT(NAME, TYPE, DEFAULT) \ - if(algo_name == NAME) \ - { \ - if(name.size() == 1) \ - return new TYPE(DEFAULT); \ - if(name.size() == 2) \ - return new TYPE(to_u32bit(name[1])); \ - throw Invalid_Algorithm_Name(algo_spec); \ - } - -#define HANDLE_TYPE_TWO_U32BIT(NAME, TYPE, DEFAULT) \ - if(algo_name == NAME) \ - { \ - if(name.size() == 1) \ - return new TYPE(DEFAULT); \ - if(name.size() == 2) \ - return new TYPE(to_u32bit(name[1])); \ - if(name.size() == 3) \ - return new TYPE(to_u32bit(name[1]), to_u32bit(name[2])); \ - throw Invalid_Algorithm_Name(algo_spec); \ - } - -#define HANDLE_TYPE_ONE_STRING(NAME, TYPE) \ - if(algo_name == NAME) \ - { \ - if(name.size() == 2) \ - return new TYPE(name[1]); \ - throw Invalid_Algorithm_Name(algo_spec); \ - } - -/************************************************* -* Attempt to get a block cipher object * -*************************************************/ -BlockCipher* get_block_cipher(const std::string& algo_spec) +S2K* get_s2k(const std::string& algo_spec) { std::vector name = parse_algorithm_name(algo_spec); if(name.size() == 0) return 0; - const std::string algo_name = deref_alias(name[0]); + if(name.size() != 2) + throw Invalid_Algorithm_Name(algo_spec); - HANDLE_TYPE_NO_ARGS("AES", AES); - HANDLE_TYPE_NO_ARGS("AES-128", AES_128); - HANDLE_TYPE_NO_ARGS("AES-192", AES_192); - HANDLE_TYPE_NO_ARGS("AES-256", AES_256); - - return 0; - } - -/************************************************* -* Attempt to get a stream cipher object * -*************************************************/ -StreamCipher* get_stream_cipher(const std::string& algo_spec) - { - std::vector name = parse_algorithm_name(algo_spec); - if(name.size() == 0) - return 0; const std::string algo_name = deref_alias(name[0]); - HANDLE_TYPE_ONE_U32BIT("ARC4", ARC4, 0); - HANDLE_TYPE_ONE_U32BIT("RC4_drop", ARC4, 768); + // removed in monotone + //if(algo_name == "OpenPGP-S2K") return new OpenPGP_S2K(name[1]); + //if(algo_name == "PBKDF1") return new PKCS5_PBKDF1(name[1]); + //if(algo_name == "PBKDF2") return new PKCS5_PBKDF2(name[1]); return 0; } /************************************************* -* Attempt to get a hash function object * -*************************************************/ -HashFunction* get_hash(const std::string& algo_spec) - { - std::vector name = parse_algorithm_name(algo_spec); - if(name.size() == 0) - return 0; - const std::string algo_name = deref_alias(name[0]); - - HANDLE_TYPE_NO_ARGS("CRC32", CRC32); - HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160); - - return 0; - } - -/************************************************* -* Attempt to get an authentication code object * -*************************************************/ -MessageAuthenticationCode* get_mac(const std::string& algo_spec) - { - std::vector name = parse_algorithm_name(algo_spec); - if(name.size() == 0) - return 0; - const std::string algo_name = deref_alias(name[0]); - - HANDLE_TYPE_ONE_STRING("HMAC", HMAC); - - return 0; - } - -/************************************************* -* Attempt to get a string to key object * -*************************************************/ -S2K* get_s2k(const std::string& algo_spec) - { - std::vector name = parse_algorithm_name(algo_spec); - if(name.size() == 0) - return 0; - const std::string algo_name = deref_alias(name[0]); - - return 0; - } - -/************************************************* * Attempt to get a block cipher padding method * *************************************************/ BlockCipherModePaddingMethod* get_bc_pad(const std::string& algo_spec) @@ -147,12 +40,15 @@ std::vector name = parse_algorithm_name(algo_spec); if(name.size() == 0) return 0; + if(name.size() != 1) + throw Invalid_Algorithm_Name(algo_spec); + const std::string algo_name = deref_alias(name[0]); - HANDLE_TYPE_NO_ARGS("PKCS7", PKCS7_Padding); - HANDLE_TYPE_NO_ARGS("OneAndZeros", OneAndZeros_Padding); - HANDLE_TYPE_NO_ARGS("X9.23", ANSI_X923_Padding); - HANDLE_TYPE_NO_ARGS("NoPadding", Null_Padding); + if(algo_name == "PKCS7") return new PKCS7_Padding; + if(algo_name == "OneAndZeros") return new OneAndZeros_Padding; + if(algo_name == "X9.23") return new ANSI_X923_Padding; + if(algo_name == "NoPadding") return new Null_Padding; return 0; } ======================================================================== --- botan/algolist.h ef9d8f0eb6210c1b316298d4ca6f53013db1cef0 +++ botan/algolist.h 09a35cd375bf11ebeb7b6231db219ef73e9ee645 @@ -17,10 +17,6 @@ /************************************************* * Lookup an algorithm in the table * *************************************************/ -BlockCipher* get_block_cipher(const std::string&); -StreamCipher* get_stream_cipher(const std::string&); -HashFunction* get_hash(const std::string&); -MessageAuthenticationCode* get_mac(const std::string&); S2K* get_s2k(const std::string&); BlockCipherModePaddingMethod* get_bc_pad(const std::string&); ======================================================================== --- botan/base.cpp 3fcd48a2b31dc404fcc861f0c1150d764f276e1f +++ botan/base.cpp 782844d8ab6ab22b787eadda7392a3e23445662e @@ -227,18 +227,6 @@ } /************************************************* -* Update the internal entropy count * -*************************************************/ -void RandomNumberGenerator::update_entropy(const byte data[], u32bit length, - u32bit state_size) throw() - { - if(entropy == 8*state_size) - return; - entropy += entropy_estimate(data, length); - entropy = std::min(entropy, 8*state_size); - } - -/************************************************* * Return the version as a string * *************************************************/ std::string version_string() ======================================================================== --- botan/base.h 7223b306fb862c20a89c03a1460c366aca16fc6f +++ botan/base.h de06367b6bc1d60bfe3dbaeee2eb958757dbd0d1 @@ -27,7 +27,9 @@ virtual void clear() throw() {}; virtual std::string name() const = 0; virtual ~Algorithm() {} + Algorithm() {} private: + Algorithm(const Algorithm&) {} Algorithm& operator=(const Algorithm&) { return (*this); } }; @@ -159,11 +161,8 @@ void add_entropy(const byte[], u32bit); void add_entropy(EntropySource&, bool = true); virtual ~RandomNumberGenerator() {} - protected: - void update_entropy(const byte[], u32bit, u32bit) throw(); - u32bit entropy; private: - virtual void add_randomness(const byte[], u32bit) throw() = 0; + virtual void add_randomness(const byte[], u32bit) = 0; }; } ======================================================================== --- botan/def_alg.cpp +++ botan/def_alg.cpp 899abd4469df860e8025d1fa14dca295eda71196 @@ -0,0 +1,127 @@ +/************************************************* +* Default Engine Algorithms Source File * +* (C) 1999-2005 The Botan Project * +*************************************************/ + +#include +#include + +#include + +#include + +#include +#include + +#include + +namespace Botan { + +/************************************************* +* Some macros to simplify control flow * +*************************************************/ +#define HANDLE_TYPE_NO_ARGS(NAME, TYPE) \ + if(algo_name == NAME) \ + { \ + if(name.size() == 1) \ + return new TYPE; \ + throw Invalid_Algorithm_Name(algo_spec); \ + } + +#define HANDLE_TYPE_ONE_U32BIT(NAME, TYPE, DEFAULT) \ + if(algo_name == NAME) \ + { \ + if(name.size() == 1) \ + return new TYPE(DEFAULT); \ + if(name.size() == 2) \ + return new TYPE(to_u32bit(name[1])); \ + throw Invalid_Algorithm_Name(algo_spec); \ + } + +#define HANDLE_TYPE_TWO_U32BIT(NAME, TYPE, DEFAULT) \ + if(algo_name == NAME) \ + { \ + if(name.size() == 1) \ + return new TYPE(DEFAULT); \ + if(name.size() == 2) \ + return new TYPE(to_u32bit(name[1])); \ + if(name.size() == 3) \ + return new TYPE(to_u32bit(name[1]), to_u32bit(name[2])); \ + throw Invalid_Algorithm_Name(algo_spec); \ + } + +#define HANDLE_TYPE_ONE_STRING(NAME, TYPE) \ + if(algo_name == NAME) \ + { \ + if(name.size() == 2) \ + return new TYPE(name[1]); \ + throw Invalid_Algorithm_Name(algo_spec); \ + } + +/************************************************* +* Look for an algorithm with this name * +*************************************************/ +BlockCipher* +Default_Engine::find_block_cipher(const std::string& algo_spec) const + { + std::vector name = parse_algorithm_name(algo_spec); + if(name.size() == 0) + return 0; + const std::string algo_name = deref_alias(name[0]); + + HANDLE_TYPE_NO_ARGS("AES", AES); + HANDLE_TYPE_NO_ARGS("AES-128", AES_128); + HANDLE_TYPE_NO_ARGS("AES-192", AES_192); + HANDLE_TYPE_NO_ARGS("AES-256", AES_256); + return 0; + } + +/************************************************* +* Look for an algorithm with this name * +*************************************************/ +StreamCipher* +Default_Engine::find_stream_cipher(const std::string& algo_spec) const + { + std::vector name = parse_algorithm_name(algo_spec); + if(name.size() == 0) + return 0; + const std::string algo_name = deref_alias(name[0]); + + HANDLE_TYPE_ONE_U32BIT("ARC4", ARC4, 0); + + return 0; + } + +/************************************************* +* Look for an algorithm with this name * +*************************************************/ +HashFunction* +Default_Engine::find_hash(const std::string& algo_spec) const + { + std::vector name = parse_algorithm_name(algo_spec); + if(name.size() == 0) + return 0; + const std::string algo_name = deref_alias(name[0]); + + HANDLE_TYPE_NO_ARGS("CRC32", CRC32); + HANDLE_TYPE_NO_ARGS("SHA-160", SHA_160); + return 0; + } + +/************************************************* +* Look for an algorithm with this name * +*************************************************/ +MessageAuthenticationCode* +Default_Engine::find_mac(const std::string& algo_spec) const + { + std::vector name = parse_algorithm_name(algo_spec); + if(name.size() == 0) + return 0; + const std::string algo_name = deref_alias(name[0]); + + HANDLE_TYPE_ONE_STRING("HMAC", HMAC); + + return 0; + } + +} ======================================================================== --- botan/def_mode.cpp +++ botan/def_mode.cpp a06fee4078dafe7958ae460df501247ad6788178 @@ -0,0 +1,121 @@ +/************************************************* +* Default Engine Source File * +* (C) 1999-2005 The Botan Project * +*************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace Botan { + +namespace { + +/************************************************* +* Simply return a mode object of choice * +*************************************************/ +Keyed_Filter* get_mode(Cipher_Dir direction, const std::string& cipher, + const std::string& mode, const std::string& pad = "", + u32bit bits = 0) + { + if(mode == "ECB") + { + if(direction == ENCRYPTION) return new ECB_Encryption(cipher, pad); + else return new ECB_Decryption(cipher, pad); + } + else if(mode == "CFB") + { + if(direction == ENCRYPTION) return new CFB_Encryption(cipher, bits); + else return new CFB_Decryption(cipher, bits); + } + else if(mode == "CBC") + { + if(pad == "CTS") + { + if(direction == ENCRYPTION) return new CTS_Encryption(cipher); + else return new CTS_Decryption(cipher); + } + if(direction == ENCRYPTION) return new CBC_Encryption(cipher, pad); + else return new CBC_Decryption(cipher, pad); + } + else if(mode == "EAX") + { + if(direction == ENCRYPTION) return new EAX_Encryption(cipher, bits); + else return new EAX_Decryption(cipher, bits); + } + else + throw Internal_Error("get_mode: " + cipher + "/" + mode + "/" + pad); + } + +} +/************************************************* +* Get a cipher object * +*************************************************/ +Keyed_Filter* Default_Engine::get_cipher(const std::string& algo_spec, + Cipher_Dir direction) + { + std::vector algo_parts = split_on(algo_spec, '/'); + if(algo_parts.size() == 0) + throw Invalid_Algorithm_Name(algo_spec); + + const std::string cipher = algo_parts[0]; + + if(have_stream_cipher(cipher)) + { + if(algo_parts.size() == 1) + return new StreamCipher_Filter(cipher); + return 0; + } + else if(have_block_cipher(cipher)) + { + if(algo_parts.size() != 2 && algo_parts.size() != 3) + return 0; + + std::string mode = algo_parts[1]; + u32bit bits = 0; + + if(mode.find("CFB") != std::string::npos || + mode.find("EAX") != std::string::npos) + { + std::vector algo_info = parse_algorithm_name(mode); + mode = algo_info[0]; + if(algo_info.size() == 1) + bits = 8*block_size_of(cipher); + else if(algo_info.size() == 2) + bits = to_u32bit(algo_info[1]); + else + throw Invalid_Algorithm_Name(algo_spec); + } + + std::string padding; + if(algo_parts.size() == 3) + padding = algo_parts[2]; + else + padding = (mode == "CBC") ? "PKCS7" : "NoPadding"; + + if(mode == "ECB" && padding == "CTS") + return 0; + else if((mode != "CBC" && mode != "ECB") && padding != "NoPadding") + throw Invalid_Algorithm_Name(algo_spec); + + if(mode == "OFB") return new OFB(cipher); + else if(mode == "CTR-BE") return new CTR_BE(cipher); + else if(mode == "ECB" || mode == "CBC" || mode == "CTS" || + mode == "CFB" || mode == "EAX") + return get_mode(direction, cipher, mode, padding, bits); + else + return 0; + } + + return 0; + } + +} ======================================================================== --- botan/engine.h e564fba257a1af6a72dfb4e68dfa387846189ee0 +++ botan/engine.h bf1afaedad957edbc26e34b4a0490cc156e6789c @@ -8,6 +8,7 @@ #include #include +#include #include #include #include ======================================================================== --- botan/init.cpp 2b67a947e2133a4a9fbd93774c2a67a5d7cf5344 +++ botan/init.cpp e654bf9fc3a87be25a40bf183a843d6be139de98 @@ -9,9 +9,7 @@ #include #include #include -#include -#include -#include +#include #include #include #include @@ -261,11 +259,7 @@ set_engines(); init_rng_subsystem(); - if(arg_set(args, "fips140")) - set_global_rngs(new FIPS_186_RNG, new FIPS_186_RNG); - else - set_global_rngs(new Randpool, new ANSI_X917_RNG); - + set_global_rngs(new ANSI_X931_RNG, new ANSI_X931_RNG); add_entropy_sources(); if(!FIPS140::passes_self_tests()) ======================================================================== --- botan/mem_pool.cpp e2303f64ab0a279072bdbe59313ed10842702c20 +++ botan/mem_pool.cpp cc72eb332ab2c10e96d65332b22dec4d46fc5621 @@ -36,14 +36,6 @@ } /************************************************* -* Buffer Comparison * -*************************************************/ -bool Pooling_Allocator::is_empty_buffer(const Buffer& block) - { - return (block.length == 0); - } - -/************************************************* * Allocate some initial buffers * *************************************************/ void Pooling_Allocator::init() @@ -86,6 +78,14 @@ } /************************************************* +* Buffer Comparison * +*************************************************/ +bool Pooling_Allocator::is_empty_buffer(const Buffer& block) + { + return (block.length == 0); + } + +/************************************************* * Return true if these buffers are contiguous * *************************************************/ bool Pooling_Allocator::are_contiguous(const Buffer& a, const Buffer& b) ======================================================================== --- botan/mem_pool.h 79cc34c1b88e2ab2419e609d8c0c208a490f913e +++ botan/mem_pool.h 96e6c390b555075bc0335932142680360ef49f8b @@ -58,12 +58,12 @@ void* find_free_block(u32bit) const; void defrag_free_list() const; - static bool are_contiguous(const Buffer&, const Buffer&); u32bit find_block(void*) const; bool same_buffer(Buffer&, Buffer&) const; void remove_empty_buffers(std::vector&) const; static bool is_empty_buffer(const Buffer&); + static bool are_contiguous(const Buffer&, const Buffer&); const u32bit PREF_SIZE, ALIGN_TO; mutable std::vector real_mem, free_list; ======================================================================== --- botan/mode_pad.h d33d5fd3116799e3acc4510bbe8ec00b9ecf203a +++ botan/mode_pad.h 0ec59170055c96be7b3e7a70aa3a4e25baefbfcd @@ -17,12 +17,12 @@ class BlockCipherModePaddingMethod { public: - virtual ~BlockCipherModePaddingMethod() {} virtual void pad(byte[], u32bit, u32bit) const = 0; virtual u32bit unpad(const byte[], u32bit) const = 0; virtual u32bit pad_bytes(u32bit, u32bit) const; virtual bool valid_blocksize(u32bit) const = 0; virtual std::string name() const = 0; + virtual ~BlockCipherModePaddingMethod() {} }; /************************************************* ======================================================================== --- botan/pipe_rw.cpp a26836077fabc8d34bc89c1b96876391494fca1e +++ botan/pipe_rw.cpp d93a14d30e1feb8c498c90ddf0c4596716994536 @@ -123,13 +123,15 @@ SecureVector buffer(DEFAULT_BUFFERSIZE); std::string str; str.reserve(remaining(msg)); - while (true) + + while(true) { u32bit got = read(buffer, buffer.size(), msg); - if (got == 0) - break; + if(got == 0) + break; str.append((const char*)buffer.begin(), got); } + return str; } ======================================================================== --- botan/pkcs8.cpp 6d12f636a9d038c815ba1a19ed4b5dafa2f4a052 +++ botan/pkcs8.cpp 7f055238216229a265c733ab7e79edc252a54d93 @@ -132,11 +132,12 @@ if(!is_encrypted) key = key_data; + const u32bit max_tries = Config::get_u32bit("base/pkcs8_tries"); u32bit tries = 0; while(true) { try { - if(tries >= Config::get_u32bit("base/pkcs8_tries")) + if(max_tries && tries >= max_tries) break; if(is_encrypted) ======================================================================== --- botan/pubkey.cpp a79e182ed1aabf231ff5fd910240fd9e2fc517c3 +++ botan/pubkey.cpp ab5b94948a910abe6d83b35148ac6c460f790a11 @@ -256,14 +256,6 @@ /************************************************* * Check a signature * *************************************************/ -bool PK_Verifier::valid_signature(const byte sig[], u32bit length) - { - return check_signature(sig, length); - } - -/************************************************* -* Check a signature * -*************************************************/ bool PK_Verifier::check_signature(const MemoryRegion& sig) { return check_signature(sig, sig.size()); ======================================================================== --- botan/pubkey.h eb5a007ee85161d484036b2325def6afa731be7c +++ botan/pubkey.h dfcf36d1bc7eb006d8a593eb5f5a4a7e876171b8 @@ -77,9 +77,6 @@ bool check_signature(const byte[], u32bit); bool check_signature(const MemoryRegion&); - // DEPRECATED FUNCTION - bool valid_signature(const byte[], u32bit); - void set_input_format(Signature_Format); PK_Verifier(const PK_Key&, const std::string&); ======================================================================== --- botan/randpool.cpp 5d45a17b8b6f6311a3dd39fa0e1e8825164d8204 +++ botan/randpool.cpp 4cd57635f9b7a10426ff4ce53e630dbe86358083 @@ -16,49 +16,54 @@ if(!is_seeded()) throw PRNG_Unseeded(name()); - generate(system_clock()); - while(length >= output.size()) + update_buffer(); + while(length) { - xor_buf(out, output, output.size()); - length -= output.size(); - out += output.size(); - generate(system_clock()); + const u32bit copied = std::min(length, buffer.size()); + copy_mem(out, buffer.begin(), copied); + out += copied; + length -= copied; + update_buffer(); } - xor_buf(out, output, length); } /************************************************* * Refill the output buffer * *************************************************/ -void Randpool::generate(u64bit input) throw() +void Randpool::update_buffer() { + const u64bit timestamp = system_clock(); + counter++; + for(u32bit j = 0; j != 4; j++) hash->update(get_byte(j, counter)); for(u32bit j = 0; j != 8; j++) - hash->update(get_byte(j, input)); - hash->update(pool); + hash->update(get_byte(j, timestamp)); + hash->update(poolhash); - SecureVector poolhash = hash->final(); + SecureVector outerhash = hash->final(); - for(u32bit j = 0; j != poolhash.size(); j++) - output[j % output.size()] ^= poolhash[j]; - cipher->encrypt(output); + for(u32bit j = 0; j != outerhash.size(); j++) + buffer[j % buffer.size()] ^= outerhash[j]; + cipher->encrypt(buffer); if(counter % ITERATIONS_BEFORE_RESEED == 0) + { mix_pool(); - counter++; + update_buffer(); + } } /************************************************* -* Mix the randomness pool * +* Mix the entropy pool * *************************************************/ -void Randpool::mix_pool() throw() +void Randpool::mix_pool() { const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; - cipher->set_key(output, output.size()); + cipher->set_key(poolhash); - xor_buf(pool, pool + BLOCK_SIZE*(POOL_BLOCKS-1), BLOCK_SIZE); + xor_buf(pool, buffer, BLOCK_SIZE); cipher->encrypt(pool); for(u32bit j = 1; j != POOL_BLOCKS; j++) { @@ -68,29 +73,29 @@ cipher->encrypt(this_block); } - for(u32bit j = 0; j != output.size(); j++) - output[j] ^= 0xFF; - cipher->encrypt(output); + poolhash = hash->process(pool); } /************************************************* * Add entropy to the internal state * *************************************************/ -void Randpool::add_randomness(const byte data[], u32bit length) throw() +void Randpool::add_randomness(const byte data[], u32bit length) { - update_entropy(data, length, pool.size()); + u32bit this_entropy = entropy_estimate(data, length); + entropy += std::min(this_entropy, 8*hash->OUTPUT_LENGTH); + entropy = std::min(entropy, 8 * pool.size()); while(length) { u32bit added = std::min(pool.size() / 2, length); + xor_buf(pool, data, added); - generate(system_clock()); + poolhash = hash->process(pool); mix_pool(); + length -= added; data += added; } - generate(system_time()); - mix_pool(); } /************************************************* @@ -109,7 +114,8 @@ cipher->clear(); hash->clear(); pool.clear(); - output.clear(); + poolhash.clear(); + buffer.clear(); entropy = counter = 0; } @@ -118,29 +124,37 @@ *************************************************/ std::string Randpool::name() const { - return "Randpool"; + return "Randpool(" + cipher->name() + "," + hash->name() + ")"; } /************************************************* * Randpool Constructor * *************************************************/ -Randpool::Randpool() : ITERATIONS_BEFORE_RESEED(8), POOL_BLOCKS(64) +Randpool::Randpool() : ITERATIONS_BEFORE_RESEED(8), POOL_BLOCKS(32) { - cipher = get_block_cipher("AES-128"); - hash = get_hash("SHA-1"); + const std::string CIPHER_NAME = "AES-256"; + const std::string HASH_NAME = "SHA-256"; + cipher = get_block_cipher(CIPHER_NAME); + hash = get_hash(HASH_NAME); + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; - output.create(BLOCK_SIZE); - pool.create(POOL_BLOCKS * BLOCK_SIZE); - entropy = counter = 0; + const u32bit OUTPUT_LENGTH = hash->OUTPUT_LENGTH; - if(hash->OUTPUT_LENGTH < BLOCK_SIZE || !cipher->valid_keylength(BLOCK_SIZE)) + if(OUTPUT_LENGTH < BLOCK_SIZE || !cipher->valid_keylength(OUTPUT_LENGTH)) + { + delete cipher; + delete hash; throw Internal_Error("Randpool: Invalid algorithm combination " + - cipher->name() + "/" + hash->name()); + CIPHER_NAME + "/" + HASH_NAME); + } - cipher->set_key(output, output.size()); - for(u32bit j = 0; j != ITERATIONS_BEFORE_RESEED + 1; j++) - generate(system_clock()); + poolhash = hash->process(pool); + buffer.create(BLOCK_SIZE); + pool.create(POOL_BLOCKS * BLOCK_SIZE); + entropy = counter = 0; + + mix_pool(); } /************************************************* @@ -150,6 +164,7 @@ { delete cipher; delete hash; + entropy = counter = 0; } } ======================================================================== --- botan/randpool.h 8c3837ac3ca62bdbf5e584ca350aee650df6dd56 +++ botan/randpool.h 9e5e53dac9493dd855fa05a563fb80769d5b8988 @@ -20,17 +20,19 @@ bool is_seeded() const; void clear() throw(); std::string name() const; + Randpool(); ~Randpool(); private: - void add_randomness(const byte[], u32bit) throw(); - void generate(u64bit) throw(); - void mix_pool() throw(); + void add_randomness(const byte[], u32bit); + void update_buffer(); + void mix_pool(); + const u32bit ITERATIONS_BEFORE_RESEED, POOL_BLOCKS; BlockCipher* cipher; HashFunction* hash; - SecureVector pool, output; - u32bit counter; + SecureVector pool, poolhash, buffer; + u32bit entropy, counter; }; } ======================================================================== --- botan/rng.cpp a87b1336b2275f4083f991b28ec602681eb17e1b +++ botan/rng.cpp 6241291f961c12f562c194b7cd2a57a7fa41e3f9 @@ -290,7 +290,7 @@ void set_global_rngs(RandomNumberGenerator* rng1, RandomNumberGenerator* rng2) { if(!rng_state) - throw Internal_Error("Global_RNG::seed: RNG state never created"); + throw Internal_Error("set_global_rngs: RNG state never created"); rng_state->set_rngs(rng1, rng2); } ======================================================================== --- botan/sha160.cpp f3c39163a2977d63f172f75ffe1891f2a2832239 +++ botan/sha160.cpp 283762dff556d9a03a0921634c178e7d5e84bda5 @@ -7,136 +7,115 @@ namespace Botan { - namespace { +namespace { - /************************************************* - * SHA-160 F1 Function * - *************************************************/ - inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += rotate_left(A, 5) + (D ^ (B & (C ^ D))) + msg + 0x5A827999; - B = rotate_left(B, 30); - } +/************************************************* +* SHA-160 F1 Function * +*************************************************/ +inline void F1(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (D ^ (B & (C ^ D))) + msg + 0x5A827999 + rotate_left(A, 5); + B = rotate_left(B, 30); + } - /************************************************* - * SHA-160 F2 Function * - *************************************************/ - inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += rotate_left(A, 5) + (B ^ C ^ D) + msg + 0x6ED9EBA1; - B = rotate_left(B, 30); - } +/************************************************* +* SHA-160 F2 Function * +*************************************************/ +inline void F2(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (B ^ C ^ D) + msg + 0x6ED9EBA1 + rotate_left(A, 5); + B = rotate_left(B, 30); + } - /************************************************* - * SHA-160 F3 Function * - *************************************************/ - inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += rotate_left(A, 5) + ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC; - B = rotate_left(B, 30); - } +/************************************************* +* SHA-160 F3 Function * +*************************************************/ +inline void F3(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += ((B & C) | ((B | C) & D)) + msg + 0x8F1BBCDC + rotate_left(A, 5); + B = rotate_left(B, 30); + } - /************************************************* - * SHA-160 F4 Function * - *************************************************/ - inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) - { - E += rotate_left(A, 5) + (B ^ C ^ D) + msg + 0xCA62C1D6; - B = rotate_left(B, 30); - } +/************************************************* +* SHA-160 F4 Function * +*************************************************/ +inline void F4(u32bit A, u32bit& B, u32bit C, u32bit D, u32bit& E, u32bit msg) + { + E += (B ^ C ^ D) + msg + 0xCA62C1D6 + rotate_left(A, 5); + B = rotate_left(B, 30); + } - } +} - /************************************************* - * SHA-160 Compression Function * - *************************************************/ - void SHA_160::hash(const byte input[]) - { - class SHA_Expander - { - public: - u32bit operator[](u32bit i) - { - if(i < 16) - W[i] = make_u32bit(in[4*i], in[4*i+1], in[4*i+2], in[4*i+3]); - else - W[i%16] = rotate_left(W[(i+13)%16] ^ W[(i+8)%16] ^ - W[(i+2)%16] ^ W[i%16], 1); +/************************************************* +* SHA-160 Compression Function * +*************************************************/ +void SHA_160::hash(const byte input[]) + { + for(u32bit j = 0; j != 16; j++) + W[j] = make_u32bit(input[4*j], input[4*j+1], input[4*j+2], input[4*j+3]); + for(u32bit j = 16; j != 80; j++) + W[j] = rotate_left((W[j-3] ^ W[j-8] ^ W[j-14] ^ W[j-16]), 1); - return W[i%16]; - } + u32bit A = digest[0], B = digest[1], C = digest[2], + D = digest[3], E = digest[4]; - void set_input(const byte* x) { in = x; } + F1(A,B,C,D,E,W[ 0]); F1(E,A,B,C,D,W[ 1]); F1(D,E,A,B,C,W[ 2]); + F1(C,D,E,A,B,W[ 3]); F1(B,C,D,E,A,W[ 4]); F1(A,B,C,D,E,W[ 5]); + F1(E,A,B,C,D,W[ 6]); F1(D,E,A,B,C,W[ 7]); F1(C,D,E,A,B,W[ 8]); + F1(B,C,D,E,A,W[ 9]); F1(A,B,C,D,E,W[10]); F1(E,A,B,C,D,W[11]); + F1(D,E,A,B,C,W[12]); F1(C,D,E,A,B,W[13]); F1(B,C,D,E,A,W[14]); + F1(A,B,C,D,E,W[15]); F1(E,A,B,C,D,W[16]); F1(D,E,A,B,C,W[17]); + F1(C,D,E,A,B,W[18]); F1(B,C,D,E,A,W[19]); - ~SHA_Expander() { clear_mem(W, 16); } - private: - const byte* in; - u32bit W[16]; - }; + F2(A,B,C,D,E,W[20]); F2(E,A,B,C,D,W[21]); F2(D,E,A,B,C,W[22]); + F2(C,D,E,A,B,W[23]); F2(B,C,D,E,A,W[24]); F2(A,B,C,D,E,W[25]); + F2(E,A,B,C,D,W[26]); F2(D,E,A,B,C,W[27]); F2(C,D,E,A,B,W[28]); + F2(B,C,D,E,A,W[29]); F2(A,B,C,D,E,W[30]); F2(E,A,B,C,D,W[31]); + F2(D,E,A,B,C,W[32]); F2(C,D,E,A,B,W[33]); F2(B,C,D,E,A,W[34]); + F2(A,B,C,D,E,W[35]); F2(E,A,B,C,D,W[36]); F2(D,E,A,B,C,W[37]); + F2(C,D,E,A,B,W[38]); F2(B,C,D,E,A,W[39]); - SHA_Expander W; - W.set_input(input); + F3(A,B,C,D,E,W[40]); F3(E,A,B,C,D,W[41]); F3(D,E,A,B,C,W[42]); + F3(C,D,E,A,B,W[43]); F3(B,C,D,E,A,W[44]); F3(A,B,C,D,E,W[45]); + F3(E,A,B,C,D,W[46]); F3(D,E,A,B,C,W[47]); F3(C,D,E,A,B,W[48]); + F3(B,C,D,E,A,W[49]); F3(A,B,C,D,E,W[50]); F3(E,A,B,C,D,W[51]); + F3(D,E,A,B,C,W[52]); F3(C,D,E,A,B,W[53]); F3(B,C,D,E,A,W[54]); + F3(A,B,C,D,E,W[55]); F3(E,A,B,C,D,W[56]); F3(D,E,A,B,C,W[57]); + F3(C,D,E,A,B,W[58]); F3(B,C,D,E,A,W[59]); - u32bit A = digest[0], B = digest[1], C = digest[2], - D = digest[3], E = digest[4]; + F4(A,B,C,D,E,W[60]); F4(E,A,B,C,D,W[61]); F4(D,E,A,B,C,W[62]); + F4(C,D,E,A,B,W[63]); F4(B,C,D,E,A,W[64]); F4(A,B,C,D,E,W[65]); + F4(E,A,B,C,D,W[66]); F4(D,E,A,B,C,W[67]); F4(C,D,E,A,B,W[68]); + F4(B,C,D,E,A,W[69]); F4(A,B,C,D,E,W[70]); F4(E,A,B,C,D,W[71]); + F4(D,E,A,B,C,W[72]); F4(C,D,E,A,B,W[73]); F4(B,C,D,E,A,W[74]); + F4(A,B,C,D,E,W[75]); F4(E,A,B,C,D,W[76]); F4(D,E,A,B,C,W[77]); + F4(C,D,E,A,B,W[78]); F4(B,C,D,E,A,W[79]); - F1(A,B,C,D,E,W[ 0]); F1(E,A,B,C,D,W[ 1]); F1(D,E,A,B,C,W[ 2]); - F1(C,D,E,A,B,W[ 3]); F1(B,C,D,E,A,W[ 4]); F1(A,B,C,D,E,W[ 5]); - F1(E,A,B,C,D,W[ 6]); F1(D,E,A,B,C,W[ 7]); F1(C,D,E,A,B,W[ 8]); - F1(B,C,D,E,A,W[ 9]); F1(A,B,C,D,E,W[10]); F1(E,A,B,C,D,W[11]); - F1(D,E,A,B,C,W[12]); F1(C,D,E,A,B,W[13]); F1(B,C,D,E,A,W[14]); - F1(A,B,C,D,E,W[15]); F1(E,A,B,C,D,W[16]); F1(D,E,A,B,C,W[17]); - F1(C,D,E,A,B,W[18]); F1(B,C,D,E,A,W[19]); + digest[0] += A; digest[1] += B; digest[2] += C; + digest[3] += D; digest[4] += E; + } - F2(A,B,C,D,E,W[20]); F2(E,A,B,C,D,W[21]); F2(D,E,A,B,C,W[22]); - F2(C,D,E,A,B,W[23]); F2(B,C,D,E,A,W[24]); F2(A,B,C,D,E,W[25]); - F2(E,A,B,C,D,W[26]); F2(D,E,A,B,C,W[27]); F2(C,D,E,A,B,W[28]); - F2(B,C,D,E,A,W[29]); F2(A,B,C,D,E,W[30]); F2(E,A,B,C,D,W[31]); - F2(D,E,A,B,C,W[32]); F2(C,D,E,A,B,W[33]); F2(B,C,D,E,A,W[34]); - F2(A,B,C,D,E,W[35]); F2(E,A,B,C,D,W[36]); F2(D,E,A,B,C,W[37]); - F2(C,D,E,A,B,W[38]); F2(B,C,D,E,A,W[39]); - - F3(A,B,C,D,E,W[40]); F3(E,A,B,C,D,W[41]); F3(D,E,A,B,C,W[42]); - F3(C,D,E,A,B,W[43]); F3(B,C,D,E,A,W[44]); F3(A,B,C,D,E,W[45]); - F3(E,A,B,C,D,W[46]); F3(D,E,A,B,C,W[47]); F3(C,D,E,A,B,W[48]); - F3(B,C,D,E,A,W[49]); F3(A,B,C,D,E,W[50]); F3(E,A,B,C,D,W[51]); - F3(D,E,A,B,C,W[52]); F3(C,D,E,A,B,W[53]); F3(B,C,D,E,A,W[54]); - F3(A,B,C,D,E,W[55]); F3(E,A,B,C,D,W[56]); F3(D,E,A,B,C,W[57]); - F3(C,D,E,A,B,W[58]); F3(B,C,D,E,A,W[59]); - - F4(A,B,C,D,E,W[60]); F4(E,A,B,C,D,W[61]); F4(D,E,A,B,C,W[62]); - F4(C,D,E,A,B,W[63]); F4(B,C,D,E,A,W[64]); F4(A,B,C,D,E,W[65]); - F4(E,A,B,C,D,W[66]); F4(D,E,A,B,C,W[67]); F4(C,D,E,A,B,W[68]); - F4(B,C,D,E,A,W[69]); F4(A,B,C,D,E,W[70]); F4(E,A,B,C,D,W[71]); - F4(D,E,A,B,C,W[72]); F4(C,D,E,A,B,W[73]); F4(B,C,D,E,A,W[74]); - F4(A,B,C,D,E,W[75]); F4(E,A,B,C,D,W[76]); F4(D,E,A,B,C,W[77]); - F4(C,D,E,A,B,W[78]); F4(B,C,D,E,A,W[79]); - - digest[0] += A; digest[1] += B; digest[2] += C; - digest[3] += D; digest[4] += E; - } - - /************************************************* - * Copy out the digest * - *************************************************/ - void SHA_160::copy_out(byte output[]) - { - for(u32bit j = 0; j != OUTPUT_LENGTH; j++) +/************************************************* +* Copy out the digest * +*************************************************/ +void SHA_160::copy_out(byte output[]) + { + for(u32bit j = 0; j != OUTPUT_LENGTH; j++) output[j] = get_byte(j % 4, digest[j/4]); - } + } - /************************************************* - * Clear memory of sensitive data * - *************************************************/ - void SHA_160::clear() throw() - { - MDx_HashFunction::clear(); - digest[0] = 0x67452301; - digest[1] = 0xEFCDAB89; - digest[2] = 0x98BADCFE; - digest[3] = 0x10325476; - digest[4] = 0xC3D2E1F0; - } +/************************************************* +* Clear memory of sensitive data * +*************************************************/ +void SHA_160::clear() throw() + { + MDx_HashFunction::clear(); + digest[0] = 0x67452301; + digest[1] = 0xEFCDAB89; + digest[2] = 0x98BADCFE; + digest[3] = 0x10325476; + digest[4] = 0xC3D2E1F0; + } } - ======================================================================== --- botan/sha160.h e2ad1d38fddf6502076da1b95be4eafbbc7a54a2 +++ botan/sha160.h ed9b5ecfb4120f6b0c8f5c930705c56959944ef9 @@ -28,9 +28,9 @@ void copy_out(byte[]); SecureBuffer digest; + SecureBuffer W; }; } #endif - ======================================================================== --- botan/x931_rng.cpp +++ botan/x931_rng.cpp 7f93d680b7e6c71a3b9fcf1f8af051062cdddb16 @@ -0,0 +1,133 @@ +/************************************************* +* ANSI X9.31 RNG Source File * +* (C) 1999-2005 The Botan Project * +*************************************************/ + +#include +#include +#include + +namespace Botan { + +/************************************************* +* Generate a buffer of random bytes * +*************************************************/ +void ANSI_X931_RNG::randomize(byte out[], u32bit length) throw(PRNG_Unseeded) + { + if(!is_seeded()) + throw PRNG_Unseeded(name()); + + while(length) + { + const u32bit copied = std::min(length, R.size() - position); + + copy_mem(out, R + position, copied); + out += copied; + length -= copied; + position += copied; + + if(position == R.size()) + { + update_buffer(); + position = 0; + } + } + } + +/************************************************* +* Refill the internal state * +*************************************************/ +void ANSI_X931_RNG::update_buffer() + { + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + SecureVector DT(BLOCK_SIZE); + + prng->randomize(DT, DT.size()); + cipher->encrypt(DT); + + xor_buf(R, V, DT, BLOCK_SIZE); + cipher->encrypt(R); + + xor_buf(V, R, DT, BLOCK_SIZE); + cipher->encrypt(V); + } + +/************************************************* +* Add entropy to internal state * +*************************************************/ +void ANSI_X931_RNG::add_randomness(const byte data[], u32bit length) + { + prng->add_entropy(data, length); + + if(is_seeded()) + { + SecureVector key(cipher->MAXIMUM_KEYLENGTH); + prng->randomize(key, key.size()); + cipher->set_key(key, key.size()); + + prng->randomize(V, V.size()); + + update_buffer(); + } + } + +/************************************************* +* Check if the the PRNG is seeded * +*************************************************/ +bool ANSI_X931_RNG::is_seeded() const + { + return prng->is_seeded(); + } + +/************************************************* +* Clear memory of sensitive data * +*************************************************/ +void ANSI_X931_RNG::clear() throw() + { + cipher->clear(); + prng->clear(); + R.clear(); + V.clear(); + + position = 0; + } + +/************************************************* +* Return the name of this type * +*************************************************/ +std::string ANSI_X931_RNG::name() const + { + return "X9.31(" + cipher->name() + ")"; + } + +/************************************************* +* ANSI X931 RNG Constructor * +*************************************************/ +ANSI_X931_RNG::ANSI_X931_RNG(RandomNumberGenerator* prng_ptr) + { + cipher = get_block_cipher("AES-256"); + + const u32bit BLOCK_SIZE = cipher->BLOCK_SIZE; + + V.create(BLOCK_SIZE); + R.create(BLOCK_SIZE); + + if(prng_ptr) + prng = prng_ptr; + else + prng = new Randpool; + + position = 0; + } + +/************************************************* +* ANSI X931 RNG Destructor * +*************************************************/ +ANSI_X931_RNG::~ANSI_X931_RNG() + { + delete cipher; + delete prng; + } + +} ======================================================================== --- botan/x931_rng.h +++ botan/x931_rng.h 867850aff3df63007e12886ed6d00c338496b93e @@ -0,0 +1,37 @@ +/************************************************* +* ANSI X9.31 RNG Header File * +* (C) 1999-2005 The Botan Project * +*************************************************/ + +#ifndef BOTAN_ANSI_X931_RNG_H__ +#define BOTAN_ANSI_X931_RNG_H__ + +#include + +namespace Botan { + +/************************************************* +* ANSI X9.31 RNG * +*************************************************/ +class ANSI_X931_RNG : public RandomNumberGenerator + { + public: + void randomize(byte[], u32bit) throw(PRNG_Unseeded); + bool is_seeded() const; + void clear() throw(); + std::string name() const; + ANSI_X931_RNG(RandomNumberGenerator* = 0); + ~ANSI_X931_RNG(); + private: + void add_randomness(const byte[], u32bit); + void update_buffer(); + + BlockCipher* cipher; + RandomNumberGenerator* prng; + SecureVector V, R; + u32bit position; + }; + +} + +#endif