/* * TLS Handshake Hash * (C) 2004-2006,2011,2012 Jack Lloyd * * Released under the terms of the Botan license */ #include #include #include #include #include namespace Botan { namespace TLS { /** * Return a TLS Handshake Hash */ secure_vector Handshake_Hash::final(Protocol_Version version, const std::string& mac_algo) { Algorithm_Factory& af = global_state().algorithm_factory(); std::unique_ptr hash; if(version == Protocol_Version::TLS_V10 || version == Protocol_Version::TLS_V11) { hash.reset(af.make_hash_function("TLS.Digest.0")); } else if(version == Protocol_Version::TLS_V12) { if(mac_algo == "MD5" || mac_algo == "SHA-1" || mac_algo == "SHA-256") hash.reset(af.make_hash_function("SHA-256")); else hash.reset(af.make_hash_function(mac_algo)); } else throw TLS_Exception(Alert::PROTOCOL_VERSION, "Unknown version for handshake hashes"); hash->update(data); return hash->final(); } /** * Return a SSLv3 Handshake Hash */ secure_vector Handshake_Hash::final_ssl3(const secure_vector& secret) { const byte PAD_INNER = 0x36, PAD_OUTER = 0x5C; Algorithm_Factory& af = global_state().algorithm_factory(); std::unique_ptr md5(af.make_hash_function("MD5")); std::unique_ptr sha1(af.make_hash_function("SHA-1")); md5->update(data); sha1->update(data); md5->update(secret); sha1->update(secret); for(size_t i = 0; i != 48; ++i) md5->update(PAD_INNER); for(size_t i = 0; i != 40; ++i) sha1->update(PAD_INNER); secure_vector inner_md5 = md5->final(), inner_sha1 = sha1->final(); md5->update(secret); sha1->update(secret); for(size_t i = 0; i != 48; ++i) md5->update(PAD_OUTER); for(size_t i = 0; i != 40; ++i) sha1->update(PAD_OUTER); md5->update(inner_md5); sha1->update(inner_sha1); secure_vector output; output += md5->final(); output += sha1->final(); return output; } } }