diff options
Diffstat (limited to 'checks')
-rw-r--r-- | checks/block.cpp | 115 | ||||
-rw-r--r-- | checks/common.h | 12 | ||||
-rw-r--r-- | checks/ecdsa.cpp | 71 | ||||
-rw-r--r-- | checks/pk_valid.dat | 120 | ||||
-rw-r--r-- | checks/validate.cpp | 138 |
5 files changed, 283 insertions, 173 deletions
diff --git a/checks/block.cpp b/checks/block.cpp deleted file mode 100644 index 5d275615e..000000000 --- a/checks/block.cpp +++ /dev/null @@ -1,115 +0,0 @@ -/* -* (C) 2009 Jack Lloyd -* -* Distributed under the terms of the Botan license -*/ - - -/* - We don't use the standard issue ECB filter, because we also want to check - that the encryption and decryption operations are inverses (ie, it works). - - This class only works with NoPadding mode, unlike the regular ECB filters -*/ - -#include <iostream> -#include <string> -#include <cstdlib> -#include <botan/filter.h> -#include <botan/lookup.h> -using namespace Botan; - -#include "common.h" - -class ECB_Encryption_ErrorCheck : public Filter - { - public: - std::string name() const - { return "ECB_ErrCheck(" + cipher->name() + ")"; } - - void write(const byte[], size_t); - - void end_msg(); - - ECB_Encryption_ErrorCheck(const std::string& cipher_name, - const std::string&, - const SymmetricKey& key) : - BLOCKSIZE(block_size_of(cipher_name)) - { - const std::string HASH = "CRC32"; - - cipher = get_block_cipher(cipher_name); - input_hash = get_hash(HASH); - decrypt_hash = get_hash(HASH); - buffer.resize(BLOCKSIZE); - cipher->set_key(key); - position = 0; - } - - ~ECB_Encryption_ErrorCheck() - { - delete cipher; - delete input_hash; - delete decrypt_hash; - } - - private: - const size_t BLOCKSIZE; - BlockCipher* cipher; - SecureVector<byte> buffer; - size_t position; - HashFunction* input_hash, *decrypt_hash; - }; - -void ECB_Encryption_ErrorCheck::write(const byte input[], size_t length) - { - input_hash->update(input, length); - buffer.copy(position, input, length); - if(position + length >= BLOCKSIZE) - { - cipher->encrypt(buffer); - send(buffer, BLOCKSIZE); - cipher->decrypt(buffer); - decrypt_hash->update(&buffer[0], BLOCKSIZE); - input += (BLOCKSIZE - position); - length -= (BLOCKSIZE - position); - while(length >= BLOCKSIZE) - { - cipher->encrypt(input, &buffer[0]); - send(buffer, BLOCKSIZE); - cipher->decrypt(buffer); - decrypt_hash->update(&buffer[0], BLOCKSIZE); - input += BLOCKSIZE; - length -= BLOCKSIZE; - } - buffer.copy(input, length); - position = 0; - } - position += length; - } - -void ECB_Encryption_ErrorCheck::end_msg() - { - SecureVector<byte> hash1 = input_hash->final(); - SecureVector<byte> hash2 = decrypt_hash->final(); - - if(hash1 != hash2) - { - std::cout << "In " << cipher->name() - << " decryption check failed." << std::endl; - } - - if(position) - throw Encoding_Error("ECB: input was not in full blocks"); - } - -Filter* lookup_block(const std::string& algname, const std::string& key) - { - Filter* cipher = 0; - try { - cipher = new ECB_Encryption_ErrorCheck(algname, "NoPadding", key); - } - catch(Algorithm_Not_Found) {} - - return cipher; - } diff --git a/checks/common.h b/checks/common.h index 148b89d93..33499a99d 100644 --- a/checks/common.h +++ b/checks/common.h @@ -25,18 +25,6 @@ std::vector<std::string> parse(const std::string& line); Botan::Filter* lookup(const std::string& algname, const std::vector<std::string>& params); -Botan::Filter* lookup_block(const std::string&, const std::string&); -Botan::Filter* lookup_cipher(const std::string&, const std::string&, - const std::string&, bool); -Botan::Filter* lookup_hash(const std::string&); -Botan::Filter* lookup_mac(const std::string&, const std::string&); -Botan::Filter* lookup_rng(const std::string&, const std::string&); -Botan::Filter* lookup_encoder(const std::string&); -Botan::Filter* lookup_pbkdf(const std::string&, - const std::vector<std::string>&); -Botan::Filter* lookup_kdf(const std::string&, const std::string&, - const std::string&); - class Fixed_Output_RNG : public Botan::RandomNumberGenerator { public: diff --git a/checks/ecdsa.cpp b/checks/ecdsa.cpp index 1fa845094..346c0441c 100644 --- a/checks/ecdsa.cpp +++ b/checks/ecdsa.cpp @@ -48,55 +48,37 @@ void test_hash_larger_than_n(RandomNumberGenerator& rng) { std::cout << "." << std::flush; - EC_Domain_Params dom_pars(OID("1.3.132.0.8")); - // n: - // 0x0100000000000000000001f4c8f927aed3ca752257 // 21 bytes - // -> shouldn't work with SHA224 which outputs 23 bytes + EC_Domain_Params dom_pars(OID("1.3.132.0.8")); // secp160r1 + // n = 0x0100000000000000000001f4c8f927aed3ca752257 (21 bytes) + // -> shouldn't work with SHA224 which outputs 28 bytes + ECDSA_PrivateKey priv_key(rng, dom_pars); + SecureVector<byte> message(20); - for (unsigned i = 0; i != 20; ++i) + for(size_t i = 0; i != message.size(); ++i) message[i] = i; - for (int i = 0; i<3; i++) - { - //cout << "i = " << i << endl; - std::string format; - if(i==1) - { - format = "EMSA1_BSI(SHA-224)"; - } - else - { - format = "EMSA1_BSI(SHA-1)"; - } - PK_Signer pk_signer(priv_key, format); - SecureVector<byte> signature; - bool sig_exc = false; - try - { - signature = pk_signer.sign_message(message, rng); - } - catch(Encoding_Error e) - { - sig_exc = true; - } - if(i==1) - { - CHECK(sig_exc); - } - if(i==0) - { - CHECK(!sig_exc); - } + PK_Signer pk_signer_160(priv_key, "EMSA1_BSI(SHA-1)"); + PK_Verifier pk_verifier_160(priv_key, "EMSA1_BSI(SHA-1)"); - if(i==0) // makes no sense to check for sha224 - { - PK_Verifier pk_verifier(priv_key, format); - bool ver = pk_verifier.verify_message(message, signature); - CHECK(ver); - } + PK_Signer pk_signer_224(priv_key, "EMSA1_BSI(SHA-224)"); + + // Verify we can sign and verify with SHA-160 + SecureVector<byte> signature_160 = pk_signer_160.sign_message(message, rng); + + CHECK(pk_verifier_160.verify_message(message, signature_160)); - } // for + bool signature_failed = false; + try + { + SecureVector<byte> signature_224 = pk_signer_224.sign_message(message, rng); + } + catch(Encoding_Error) + { + signature_failed = true; + } + + CHECK(signature_failed); // now check that verification alone fails @@ -107,9 +89,6 @@ void test_hash_larger_than_n(RandomNumberGenerator& rng) PK_Verifier pk_verifier(priv_key, "EMSA1_BSI(SHA-224)"); // verify against EMSA1_BSI - // we make sure it doesn't fail because of the invalid signature, - // but because of the Encoding_Error - if(pk_verifier.verify_message(message, signature)) std::cout << "Corrupt ECDSA signature verified, should not have\n"; } diff --git a/checks/pk_valid.dat b/checks/pk_valid.dat index bce2b0e04..7298b3730 100644 --- a/checks/pk_valid.dat +++ b/checks/pk_valid.dat @@ -4249,6 +4249,126 @@ x962_p239v1:\ 2CB7F36803EBB9C427C58D8265F11FC5084747133078FC279DE874FBECB0\ 2EEAE988104E9C2234A3C2BEB1F53BFA5DC11FF36A875D1E3CCB1F7E45CF +brainpool160r1:\ +1CA8A0ACE60292D2813D992C4EC7A4BCDF611C0:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +9CB692B33F02179D1A6F2A0669FD8DAAF17E4FC4:\ +672EAFD043D30BAE7CA826828333FA70F10A14C7\ +0F49C076BB26178277D8E490D0C77F7A9649DE31 + +[ECDSA/EMSA1(SHA-224)] +secp224r1:\ +42D126D0E51F3D6AA9B4D60BD1290853AA964A9C8698D5D5BDBAADEB:\ +45434453412074657374206D657373616765203230313130323135:\ +E1F6B207B4FC896879A51F65E85DB94CEB633FEC765739E689847D64:\ +A4C80AAF3D7B61200E66D6F41EC66D3D65E9E38DC06A88FE3B7F6C4C\ +8A5CEE4E04FE240464EA2DBB52489D3FAC1CDE6DA24A0E4C6598BCD2 + +brainpool224r1:\ +47B5CCE9EED463CED28666DA57DA9D0A8BDD3F000CCFC0AE6054F1AD:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +9E9D0C9E67FF5785C3AD89195567CD3990D54C628788F26DB926F5B6:\ +40369F41BD0D15C92DFB855779DBF439376FB6EDC4153E9B99019B79\ +40FEF076FC8D610EC12AFC9CC43A150BD0190E507622E6623906D6B8 + +[ECDSA/EMSA1(SHA-256)] +secp256r1:\ +368E89CC30AE7A3B4B4903C30C238C010257FE97DB85AF35982A7960A0DBD2F3:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +E2AAB3BD3AB1999651CD903F5385B8EC2EDA84C43B7801F08608C179DD373369:\ +CBED1CE0D581020D2F89174EC2DE450C1D547BAC3DCEECCDD476A6AADF46D24F\ +C456F43F351605CC40FC2A000B4D291042B5AEEA7A783DF89FC86666D832DACF + +secp256r1:\ +6CC691616D2C996A8F00A31C2EBF4E35C5EFFEAAFA2266F800768D5BF8EA2C1B:\ +45434453412074657374206D657373616765203230313130323135:\ +C1DDAA59A4E0B5D95EB873C33BC465C6782EBF7BC43DB18058C9EC4816AD2A11:\ +A8369164EF54A67303760B77AA62C4DE8122396908EA5B06DBCC2BC48264C832\ +ADB3A8855019D5AFF789EC1F276AD38A03AAF41F88593B74E5CB9DF7E4BD4922 + +brainpool256r1:\ +4EC702404A8047A08206721DE33F02E1F06B14E09A5582171EA9BB8AB3C9BC14:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +A9952A1B896FB2C2AEA88EA578E2A5323114978A765E03E397969DC0F282708C:\ +54F843E89B084EEE1CFFED09F222DF041CD46DB0C48833667BA0790ECD603089\ +5304039A927714E79E5FCDB1D043E093FD85C8DD98B835CD6C7BB492C05357E5 + +brainpool256r1:\ +416D7FCEB966DF966CAE7BE2608C5C4D8939A7B5B3CF6D3E441A64886AC5FAD7:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +A07978494C1B301C1E44467853CD367624549E0E9F5092C0100A53F877AD2EF6:\ +93935B733CCC6A8702191664346135D1D6320D86A2346DFCA41AEDFBC4260435\ +A4A9C66485C02BC2DCC858364173FAE00EA02529BA21B56BBBB2EAA4B811416D + +[ECDSA/EMSA1(SHA-384)] +secp384r1:\ +100CC52F0263DCB12FDB9E50D44A4C84831A98756265DF0CBFD092D27A739821\ +043BFE282E2C8FAD46948C1F0365DD0C:\ +45434453412074657374206D657373616765203230313130323135:\ +C27CC4947F7CA7AF386AF5BEA88582685A043BB3C83C0C8B2A4BB1E53A3971FA\ +8161168E332B2F3735A50BB3E8694F43:\ +C8B93B3C4B97B87A918522F423E26194F1AEA2B83FE890893C15928B79BCAC75\ +F66AB47309378A54771ED46AF6AA453BFD2404EECFCCE19ACE11E5D5883EE40A\ +300A42BD9AC79E77E507DE9EAE0B54034DB17355EE2111990ED226701D4ED7EC + +secp384r1:\ +4AF67D00B7A8D964B38CC52CBC808D4693595A5B330E0B3EA52BDCD619D41B85\ +6961BDAC571D9BC93D16A9B1C4D5CC2F:\ +45434453412074657374206D657373616765203230313130323135:\ +8C5D8DDCF8AF127174577A60F9B5512813E33EA8E45B471F343806FBF68663E9\ +915B81A33F6AD22007D57818023AF982:\ +FF83C10E8D84777D17B724957B83E1500F578F1096C48BE2BCACE73E6681CDD6\ +A34F66CA2AF31241FAF85AEE2528438DA6BED934D75ACCF2E41176D8B661AB58\ +B7B867D802C38B39E8227F9CF0865072D381948FFFF637D8FB9B37BEC6AE0772 + +brainpool384r1:\ +19AD48ECFB30F115AEF41CAFD29B265A586399C0F95166017AA7DB894413A2AE\ +821B7BE4F4E7B6BBC22A4E2EB1CC0865:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +83928FD1219F1C6D5B128C0ECD2E39A83399CE609382D41890D43FD476318E0C\ +26264E98E0D5A0DBCC28A8C01C2D63D7:\ +4B800A206ED7807C0F15798509164709E94ED73B5E02B10D65F45B6C2B7FD694\ +37F3B5D1342DAF0988CA100B8875C739\ +2CFA819E10B76CFE12B2C6485D8326B66E6256CD2F4A6DFEB9B2B7BDD732EA9E\ +9D5398DDECCBEAAF3FD53D554AA1FADD + +[ECDSA/EMSA1(SHA-512)] + +secp521r1:\ +1511908E830069DAD59E8BA8F1BD4045612A4844805F61F7ECD92A1DEE1877B7\ +E62A57860314820C97FFC972732E3C4C0AE837103692E85B3A11B49EB3E20EF1599:\ +45434453412F53484128353132292074657374206D6573736167652032303131\ +30323135:\ +01C352020AAA6D14B6FC2B78FD46209A9EEF6A357CD8B5D53738E3D655FE7A80\ +8396E1DC5742058D05F2D76C8CBF4832BE0580A6FD7B4C7426656D17680DEAAEEEC2:\ +0138A515C79EECAAB50139FB5D9EF5A771CC1C0999F2E54B5A1A9370EA8ADCFD\ +DDD6E9933A39EDA0862F3ECAEBD49EA5ED58D93DA8F72B1CFB11E52A1528AEC8\ +63870060D717B29AD6D36DE953A4753FAC58629429EF4DD8F98B5A4F5504C5B2\ +29C23C609905632CD8D839DC472693698D7A149E8F3F17462F86BA0A7A895D80\ +583A46E9 + +brainpool512r1:\ +1433AE89858BE7DD9346AF015FEC69F0556982FFEB9CCEF7FB1CE71155F7620C\ +ED4A6ACD0F35461A17C8370C4E600BECBACC0F7C1D2D1A2C00203A0E6626C21C:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +AA72BC70ABD9E078DDE47F5440E75A93F136F6EAA5267F591E0D3F562DE48BD8\ +FED21B9E3F6F5560250566A00C7AAE7E57770BFC7D18A3E7750DC6C7083CC5B0:\ +A058CD406C7F2D87FBBDDDD1870C67D1ACBD222D45A929565101842EDFAEFB89\ +3CF07AD22CAC0F3350A7D1300741AB5ECE38498F196690CBCEDBF8C866995E5C\ +17F48EA66EB70ADE68F6C16103BE54DD004230270E1F8CAC2D6BD47F717C0D1B\ +1E335FA4AAA5212321EE93E55FED129D781912A0D87B78A5B569DA272B3C9469 + +brainpool512r1:\ +83DBEFECAF8CFF78C575BE9659C1A104767979497AD9B589B1B13705C71F1DEF\ +AF5CA76C8700236CE2392268E0133CAADE358E3D4F2E64CB4AB8517079E3EFA0:\ +43727970746F2B2B20352E362E312045434453412074657374206D7367:\ +A110CC7BEF64F5C0349344025B97B151C735408BD2BC0D0CC4E54642EA0DF33E\ +829E85916086B51624B830BB2CDF53DAD9003A6D194115051139DBC3E81DF197:\ +3254388208915E0EEB99DA89AA198C6FDB1A31B21D3B69EF8EFE4848AE78C32A\ +4C489347510A9DD04125BBE95F847E14A2DF3267A0A6D1B5EC442B130C9B5DD1\ +924FCD9F365897570329BFEC41FBAF42961210F3FF850DE5736FFBAAB09C5C03\ +E0058BD51C8A8EF0FF221F31CF93FE59572ADA3CFEC7016085258A45D1E8544C + # ECC verification format is group name:public key:message:signature [GOST_3410_VA/EMSA1(GOST-34.11)] gost_256A:\ diff --git a/checks/validate.cpp b/checks/validate.cpp index dd23eadc3..9acf73419 100644 --- a/checks/validate.cpp +++ b/checks/validate.cpp @@ -23,10 +23,18 @@ #include <botan/passhash9.h> #endif +#if defined(BOTAN_HAS_BCRYPT) + #include <botan/bcrypt.h> +#endif + #if defined(BOTAN_HAS_CRYPTO_BOX) #include <botan/cryptobox.h> #endif +#if defined(BOTAN_HAS_RFC3394_KEYWRAP) + #include <botan/rfc3394.h> +#endif + using namespace Botan; #include "validate.h" @@ -94,6 +102,124 @@ bool test_cryptobox(RandomNumberGenerator& rng) return true; } +bool keywrap_test(const char* key_str, + const char* expected_str, + const char* kek_str) + { + std::cout << '.' << std::flush; + + bool ok = true; + + try + { + SymmetricKey key(key_str); + SymmetricKey expected(expected_str); + SymmetricKey kek(kek_str); + + Algorithm_Factory& af = global_state().algorithm_factory(); + + SecureVector<byte> enc = rfc3394_keywrap(key.bits_of(), kek, af); + + if(enc != expected.bits_of()) + { + std::cout << "NIST key wrap encryption failure: " + << hex_encode(enc) << " != " << hex_encode(expected.bits_of()) << "\n"; + ok = false; + } + + SecureVector<byte> dec = rfc3394_keyunwrap(expected.bits_of(), kek, af); + + if(dec != key.bits_of()) + { + std::cout << "NIST key wrap decryption failure: " + << hex_encode(dec) << " != " << hex_encode(key.bits_of()) << "\n"; + ok = false; + } + } + catch(std::exception& e) + { + std::cout << e.what() << "\n"; + } + + return ok; + } + +bool test_keywrap() + { + std::cout << "Testing NIST keywrap: " << std::flush; + + bool ok = true; + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF", + "1FA68B0A8112B447AEF34BD8FB5A7B829D3E862371D2CFE5", + "000102030405060708090A0B0C0D0E0F"); + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF", + "96778B25AE6CA435F92B5B97C050AED2468AB8A17AD84E5D", + "000102030405060708090A0B0C0D0E0F1011121314151617"); + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF", + "64E8C3F9CE0F5BA263E9777905818A2A93C8191E7D6E8AE7", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF0001020304050607", + "031D33264E15D33268F24EC260743EDCE1C6C7DDEE725A936BA814915C6762D2", + "000102030405060708090A0B0C0D0E0F1011121314151617"); + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF0001020304050607", + "A8F9BC1612C68B3FF6E6F4FBE30E71E4769C8B80A32CB8958CD5D17D6B254DA1", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + + ok &= keywrap_test("00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F", + "28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21", + "000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F"); + + std::cout << "\n"; + return ok; + } + +bool test_bcrypt(RandomNumberGenerator& rng) + { +#if defined(BOTAN_HAS_BCRYPT) + std::cout << "Testing Bcrypt: " << std::flush; + + const std::string input = "abc"; + + // Generated by jBCrypt 0.3 + const std::string fixed_hash = + "$2a$05$DfPyLs.G6.To9fXEFgUL1O6HpYw3jIXgPcl/L3Qt3jESuWmhxtmpS"; + + std::cout << "." << std::flush; + + bool ok = true; + + if(!check_bcrypt(input, fixed_hash)) + { + std::cout << "Fixed bcrypt test failed\n"; + ok = false; + } + + std::cout << "." << std::flush; + + for(u16bit level = 1; level != 5; ++level) + { + std::string gen_hash = generate_bcrypt(input, rng, level); + + if(!check_bcrypt(input, gen_hash)) + { + std::cout << "Gen and check for bcrypt failed: " + << gen_hash << " not valid\n"; + ok = false; + } + + std::cout << "." << std::flush; + } + + std::cout << std::endl; + return ok; +#endif + } + bool test_passhash(RandomNumberGenerator& rng) { #if defined(BOTAN_HAS_PASSHASH9) @@ -265,6 +391,18 @@ u32bit do_validation_tests(const std::string& filename, errors++; } + if(should_pass && !test_bcrypt(rng)) + { + std::cout << "BCrypt tests failed" << std::endl; + errors++; + } + + if(should_pass && !test_keywrap()) + { + std::cout << "NIST keywrap tests failed" << std::endl; + errors++; + } + if(should_pass && !test_cryptobox(rng)) { std::cout << "Cryptobox tests failed" << std::endl; |