예제 #1
0
      std::string tls_policy_string(const std::string& policy_str)
         {
         std::unique_ptr<Botan::TLS::Policy> policy;
         if(policy_str == "default")
            {
            policy.reset(new Botan::TLS::Policy);
            }
         else if(policy_str == "suiteb_128")
            {
            policy.reset(new Botan::TLS::NSA_Suite_B_128);
            }
         else if(policy_str == "suiteb_192")
            {
            policy.reset(new Botan::TLS::NSA_Suite_B_192);
            }
         else if(policy_str == "bsi")
            {
            policy.reset(new Botan::TLS::BSI_TR_02102_2);
            }
         else if(policy_str == "strict")
            {
            policy.reset(new Botan::TLS::Strict_Policy);
            }
         else if(policy_str == "datagram")
            {
            policy.reset(new Botan::TLS::Datagram_Policy);
            }
         else
            {
            throw Test_Error("Unknown TLS policy type '" + policy_str + "'");
            }

         return policy->to_string();
         }
예제 #2
0
      std::string read_tls_policy(const std::string& policy_str)
         {
         const std::string fspath = Test::data_file("tls-policy/" + policy_str + ".txt");

         std::ifstream is(fspath.c_str());
         if(!is.good())
            {
            throw Test_Error("Missing policy file " + fspath);
            }

         Botan::TLS::Text_Policy policy(is);
         return policy.to_string();
         }
예제 #3
0
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
         {
         const std::vector<uint8_t> key      = get_req_bin(vars, "Key");
         const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
         const std::vector<uint8_t> nonce    = get_opt_bin(vars, "Nonce");
         const size_t seek                   = get_opt_sz(vars, "Seek", 0);
         std::vector<uint8_t> input          = get_opt_bin(vars, "In");

         if(input.empty())
            input.resize(expected.size());

         Test::Result result(algo);

         const std::vector<std::string> providers =
            provider_filter(Botan::StreamCipher::providers(algo));

         if(providers.empty())
            {
            result.note_missing("block cipher " + algo);
            return result;
            }

         for(auto&& provider_ask : providers)
            {
            std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider_ask));

            if(!cipher)
               {
               result.test_failure("Stream " + algo + " supported by " + provider_ask + " but not found");
               continue;
               }

            const std::string provider(cipher->provider());
            result.test_is_nonempty("provider", provider);
            result.test_eq(provider, cipher->name(), algo);
            cipher->set_key(key);

            if(nonce.size())
               {
               if(!cipher->valid_iv_length(nonce.size()))
                  throw Test_Error("Invalid nonce for " + algo);
               cipher->set_iv(nonce.data(), nonce.size());
               }
            else
               {
               /*
               * If no nonce was set then implicitly the cipher is using a
               * null/empty nonce. Call set_iv with such a nonce to make sure
               * set_iv accepts it.
               */
               if(!cipher->valid_iv_length(0))
                  throw Test_Error("Stream cipher " + algo + " requires nonce but none provided");
               cipher->set_iv(nullptr, 0);
               }

            if (seek != 0)
               cipher->seek(seek);

            // Test that clone works and does not affect parent object
            std::unique_ptr<Botan::StreamCipher> clone(cipher->clone());
            result.confirm("Clone has different pointer", cipher.get() != clone.get());
            result.test_eq("Clone has same name", cipher->name(), clone->name());
            clone->set_key(Test::rng().random_vec(cipher->maximum_keylength()));

            std::vector<uint8_t> buf = input;
            cipher->encrypt(buf);

            cipher->clear();

            result.test_eq(provider, "encrypt", buf, expected);
            }

         return result;
         }
예제 #4
0
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
         {
         Test::Result result("OCB wide block long test");

         const std::vector<uint8_t> expected = vars.get_req_bin("Output");

         std::unique_ptr<Botan::BlockCipher> cipher;
         size_t bs = 0;

         if(algo == "SHACAL2")
            {
#if defined(BOTAN_HAS_SHACAL2)
            cipher = Botan::BlockCipher::create_or_throw("SHACAL2");
            bs = 32;
#else
            return {result};
#endif
            }
         else
            {
            if(algo == "Toy128")
               bs = 16;
            else if(algo == "Toy192")
               bs = 24;
            else if(algo == "Toy256")
               bs = 32;
            else if(algo == "Toy512")
               bs = 64;
            else
               throw Test_Error("Unknown cipher for OCB wide block long test");
            cipher.reset(new OCB_Wide_Test_Block_Cipher(bs));
            }

         Botan::OCB_Encryption enc(cipher.release(), std::min<size_t>(bs, 32));

         /*
         Y, string of length min(B, 256) bits

         Y is defined as follows.

         K = (0xA0 || 0xA1 || 0xA2 || ...)[1..B]
         C = <empty string>
         for i = 0 to 127 do
           S = (0x50 || 0x51 || 0x52 || ...)[1..8i]
           N = num2str(3i+1,16)
           C = C || OCB-ENCRYPT(K,N,S,S)
           N = num2str(3i+2,16)
           C = C || OCB-ENCRYPT(K,N,<empty string>,S)
           N = num2str(3i+3,16)
           C = C || OCB-ENCRYPT(K,N,S,<empty string>)
         end for
         N = num2str(385,16)
         Y = OCB-ENCRYPT(K,N,C,<empty string>)
         */

         std::vector<uint8_t> key(bs);
         for(size_t i = 0; i != bs; ++i)
            key[i] = 0xA0 + i;

         enc.set_key(key);

         const std::vector<uint8_t> empty;
         std::vector<uint8_t> N(2);
         std::vector<uint8_t> C;

         for(size_t i = 0; i != 128; ++i)
            {
            std::vector<uint8_t> S(i);
            for(size_t j = 0; j != S.size(); ++j)
               S[j] = 0x50 + j;

            Botan::store_be(static_cast<uint16_t>(3 * i + 1), &N[0]);

            ocb_encrypt(result, C, enc, N, S, S);
            Botan::store_be(static_cast<uint16_t>(3 * i + 2), &N[0]);
            ocb_encrypt(result, C, enc, N, S, empty);
            Botan::store_be(static_cast<uint16_t>(3 * i + 3), &N[0]);
            ocb_encrypt(result, C, enc, N, empty, S);
            }

         Botan::store_be(static_cast<uint16_t>(385), &N[0]);
         std::vector<uint8_t> final_result;
         ocb_encrypt(result, final_result, enc, N, empty, C);

         result.test_eq("correct value", final_result, expected);

         return result;
         }
      Test::Result run_one_test(const std::string& algo, const VarMap& vars) override
         {
         const std::vector<uint8_t> key      = get_req_bin(vars, "Key");
         const std::vector<uint8_t> expected = get_req_bin(vars, "Out");
         const std::vector<uint8_t> nonce    = get_opt_bin(vars, "Nonce");
         const size_t seek                   = get_opt_sz(vars, "Seek", 0);
         std::vector<uint8_t> input          = get_opt_bin(vars, "In");

         if(input.empty())
            {
            input.resize(expected.size());
            }

         Test::Result result(algo);

         const std::vector<std::string> providers =
            provider_filter(Botan::StreamCipher::providers(algo));

         if(providers.empty())
            {
            result.note_missing("block cipher " + algo);
            return result;
            }

         for(auto const& provider_ask : providers)
            {
            std::unique_ptr<Botan::StreamCipher> cipher(Botan::StreamCipher::create(algo, provider_ask));

            if(!cipher)
               {
               result.test_failure("Stream " + algo + " supported by " + provider_ask + " but not found");
               continue;
               }

            const std::string provider(cipher->provider());
            result.test_is_nonempty("provider", provider);
            result.test_eq(provider, cipher->name(), algo);

            try
               {
               std::vector<uint8_t> buf(128);
               cipher->cipher1(buf.data(), buf.size());
               result.test_failure("Was able to encrypt without a key being set");
               }
            catch(Botan::Invalid_State&)
               {
               result.test_success("Trying to encrypt with no key set fails");
               }

            try
               {
               cipher->seek(0);
               result.test_failure("Was able to seek without a key being set");
               }
            catch(Botan::Invalid_State&)
               {
               result.test_success("Trying to seek with no key set fails");
               }
            catch(Botan::Not_Implemented&)
               {
               result.test_success("Trying to seek failed because not implemented");
               }

            cipher->set_key(key);

            /*
            Test invalid nonce sizes. this assumes no implemented cipher supports a nonce of 65000
            */
            const size_t large_nonce_size = 65000;
            result.confirm("Stream cipher does not support very large nonce", cipher->valid_iv_length(large_nonce_size) == false);

            result.test_throws("Throws if invalid nonce size given",
                               [&]() { cipher->set_iv(nullptr, large_nonce_size); });

            if(nonce.size())
               {
               if(!cipher->valid_iv_length(nonce.size()))
                  {
                  throw Test_Error("Invalid nonce for " + algo);
                  }
               cipher->set_iv(nonce.data(), nonce.size());
               }
            else
               {
               /*
               * If no nonce was set then implicitly the cipher is using a
               * null/empty nonce. Call set_iv with such a nonce to make sure
               * set_iv accepts it.
               */
               if(!cipher->valid_iv_length(0))
                  {
                  throw Test_Error("Stream cipher " + algo + " requires nonce but none provided");
                  }
               cipher->set_iv(nullptr, 0);
               }

            if(seek != 0)
               {
               cipher->seek(seek);
               }

            // Test that clone works and does not affect parent object
            std::unique_ptr<Botan::StreamCipher> clone(cipher->clone());
            result.confirm("Clone has different pointer", cipher.get() != clone.get());
            result.test_eq("Clone has same name", cipher->name(), clone->name());
            clone->set_key(Test::rng().random_vec(cipher->maximum_keylength()));

            {
            std::vector<uint8_t> buf = input;
            cipher->encrypt(buf);
            result.test_eq(provider, "encrypt", buf, expected);
            }

            cipher->clear();

            try
               {
               std::vector<uint8_t> buf(128);
               cipher->cipher1(buf.data(), buf.size());
               result.test_failure("Was able to encrypt without a key being set (after clear)");
               }
            catch(Botan::Invalid_State&)
               {
               result.test_success("Trying to encrypt with no key set (after clear) fails");
               }
            }

         return result;
         }