#include #include #include #include #include #include #include #include using namespace Botan; std::vector > read_file(const std::string&); SecureVector decode_hex(const std::string& in) { SecureVector result; try { Botan::Pipe pipe(new Botan::Hex_Decoder); pipe.process_msg(in); result = pipe.read_all(); } catch(std::exception& e) { result.destroy(); } return result; } std::string hex_encode(const byte in[], u32bit len) { Botan::Pipe pipe(new Botan::Hex_Encoder); pipe.process_msg(in, len); return pipe.read_all_as_string(); } class Fixed_Output_RNG : public RandomNumberGenerator { public: bool is_seeded() const { return !buf.empty(); } byte random() { if(buf.empty()) throw std::runtime_error("Out of bytes"); byte out = buf.front(); buf.pop_front(); return out; } void randomize(byte out[], u32bit len) throw() { for(u32bit j = 0; j != len; j++) out[j] = random(); } std::string name() const { return "Fixed_Output_RNG"; } void reseed(u32bit) {} void clear() throw() {} void add_entropy(const byte in[], u32bit len) { buf.insert(buf.end(), in, in + len); } void add_entropy_source(EntropySource* es) { delete es; } Fixed_Output_RNG() {} private: std::deque buf; }; void x931_tests(std::vector > vecs, const std::string& cipher) { for(size_t j = 0; j != vecs.size(); ++j) { const std::string result = vecs[j].first; const std::string input = vecs[j].second; ANSI_X931_RNG prng(get_block_cipher(cipher), new Fixed_Output_RNG); SecureVector x = decode_hex(input); prng.add_entropy(x.begin(), x.size()); SecureVector output(result.size() / 2); prng.randomize(output, output.size()); if(decode_hex(result) != output) std::cout << "FAIL"; else std::cout << "PASS"; std::cout << " Seed " << input << " " << "Got " << hex_encode(output, output.size()) << " " << "Exp " << result << "\n"; } } int main() { Botan::LibraryInitializer init; x931_tests(read_file("ANSI931_AES128VST.txt.vst"), "AES-128"); x931_tests(read_file("ANSI931_AES192VST.txt.vst"), "AES-192"); x931_tests(read_file("ANSI931_AES256VST.txt.vst"), "AES-256"); x931_tests(read_file("ANSI931_TDES2VST.txt.vst"), "TripleDES"); x931_tests(read_file("ANSI931_TDES3VST.txt.vst"), "TripleDES"); } std::vector > read_file(const std::string& fsname) { std::ifstream in(fsname.c_str()); std::vector > out; while(in.good()) { std::string line; std::getline(in, line); if(line == "") break; std::vector l; boost::split(l, line, boost::is_any_of(":")); if(l.size() != 2) throw std::runtime_error("Bad line " + line); out.push_back(std::make_pair(l[0], l[1])); } return out; }