Test::Result run_one_test(const std::string&, const VarMap& vars) override { Test::Result result("OCB wide block KAT"); const std::vector<uint8_t> key = vars.get_req_bin("Key"); const std::vector<uint8_t> nonce = vars.get_req_bin("Nonce"); const std::vector<uint8_t> ad = vars.get_req_bin("AD"); const std::vector<uint8_t> input = vars.get_req_bin("In"); const std::vector<uint8_t> expected = vars.get_req_bin("Out"); const size_t bs = key.size(); Botan::secure_vector<uint8_t> buf(input.begin(), input.end()); Botan::OCB_Encryption enc(new OCB_Wide_Test_Block_Cipher(bs), std::min<size_t>(bs, 32)); enc.set_key(key); enc.set_ad(ad); enc.start(nonce); enc.finish(buf); result.test_eq("Ciphertext matches", buf, expected); Botan::OCB_Decryption dec(new OCB_Wide_Test_Block_Cipher(bs), std::min<size_t>(bs, 32)); dec.set_key(key); dec.set_ad(ad); dec.start(nonce); dec.finish(buf); result.test_eq("Decryption correct", buf, input); return result; }
Test::Result run_one_test(const std::string&, const VarMap& vars) override { const std::vector<uint8_t> record = vars.get_req_bin("Record"); const size_t output = vars.get_req_sz("Output"); uint16_t res = Botan::TLS::check_tls_cbc_padding(record.data(), record.size()); Test::Result result("TLS CBC padding check"); result.test_eq("Expected", res, output); return result; }
Test::Result run_one_test(const std::string&, const VarMap& vars) override { const size_t keylen = vars.get_req_sz("Keylen"); const size_t taglen = vars.get_req_sz("Taglen"); const std::vector<uint8_t> expected = vars.get_req_bin("Output"); // Test from RFC 7253 Appendix A const std::string algo = "AES-" + std::to_string(keylen); Test::Result result("OCB long"); std::unique_ptr<Botan::BlockCipher> aes(Botan::BlockCipher::create(algo)); if(!aes) { result.note_missing(algo); return result; } Botan::OCB_Encryption enc(aes->clone(), taglen / 8); Botan::OCB_Decryption dec(aes->clone(), taglen / 8); std::vector<uint8_t> key(keylen / 8); key[keylen / 8 - 1] = static_cast<uint8_t>(taglen); enc.set_key(key); dec.set_key(key); const std::vector<uint8_t> empty; std::vector<uint8_t> N(12); std::vector<uint8_t> C; for(size_t i = 0; i != 128; ++i) { const std::vector<uint8_t> S(i); Botan::store_be(static_cast<uint32_t>(3 * i + 1), &N[8]); ocb_encrypt(result, C, enc, dec, N, S, S); Botan::store_be(static_cast<uint32_t>(3 * i + 2), &N[8]); ocb_encrypt(result, C, enc, dec, N, S, empty); Botan::store_be(static_cast<uint32_t>(3 * i + 3), &N[8]); ocb_encrypt(result, C, enc, dec, N, empty, S); } Botan::store_be(static_cast<uint32_t>(385), &N[8]); std::vector<uint8_t> final_result; ocb_encrypt(result, final_result, enc, dec, 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 { Test::Result result(algo + " Decoding"); std::unique_ptr<Botan::EME> eme; try { eme.reset(Botan::get_eme(algo)); } catch(Botan::Lookup_Error&) { result.note_missing(algo); return result; } const std::vector<uint8_t> ciphertext = vars.get_req_bin("RawCiphertext"); const std::vector<uint8_t> plaintext = vars.get_opt_bin("Plaintext"); const bool is_valid = vars.get_req_bool("ValidInput"); if(is_valid == false) { result.test_eq("Plaintext value is empty for invalid EME inputs", plaintext.size(), 0); } uint8_t valid_mask = 0; Botan::secure_vector<uint8_t> decoded = eme->unpad(valid_mask, ciphertext.data(), ciphertext.size()); result.confirm("EME valid_mask has expected value", valid_mask == 0x00 || valid_mask == 0xFF); result.test_eq("EME decoding valid/invalid matches", valid_mask == 0xFF, is_valid); if(is_valid && valid_mask == 0xFF) { result.test_eq("EME decoded plaintext correct", decoded, plaintext); } // TODO: also test that encoding is accepted return result; }
Test::Result run_one_test(const std::string&, const VarMap& vars) override { Test::Result result("TLS CBC"); const size_t block_size = vars.get_req_sz("Blocksize"); const size_t mac_len = vars.get_req_sz("MACsize"); const std::vector<uint8_t> record = vars.get_req_bin("Record"); const bool is_valid = vars.get_req_sz("Valid") == 1; // todo test permutations bool encrypt_then_mac = false; Botan::TLS::TLS_CBC_HMAC_AEAD_Decryption tls_cbc( std::unique_ptr<Botan::BlockCipher>(new Noop_Block_Cipher(block_size)), std::unique_ptr<Botan::MessageAuthenticationCode>(new ZeroMac(mac_len)), 0, 0, Botan::TLS::Protocol_Version::TLS_V11, encrypt_then_mac); tls_cbc.set_key(std::vector<uint8_t>(0)); std::vector<uint8_t> ad(13); tls_cbc.set_associated_data(ad.data(), ad.size()); Botan::secure_vector<uint8_t> vec(record.begin(), record.end()); try { tls_cbc.finish(vec, 0); if(is_valid) result.test_success("Accepted valid TLS-CBC ciphertext"); else result.test_failure("Accepted invalid TLS-CBC ciphertext"); } catch(std::exception&) { if(is_valid) result.test_failure("Rejected valid TLS-CBC ciphertext"); else result.test_success("Accepted invalid TLS-CBC ciphertext"); } return result; }
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; }