proxy/rom_verify: 17.05 release upgrades, log ROM hashes

Ref #74
This commit is contained in:
Emery Hemingway
2017-05-29 23:44:24 -05:00
parent 4e006e0423
commit 681f8f1a79

View File

@@ -14,6 +14,7 @@
/* Crypto++ includes */
#include <sha3.h>
#include <sha.h>
#include <hex.h>
/* Genode includes */
#include <os/session_policy.h>
@@ -25,11 +26,6 @@
#include <libc/component.h>
#include <base/log.h>
static char const alph[0x10] = {
'0','1','2','3','4','5','6','7',
'8','9','a','b','c','d','e','f'
};
namespace Rom_hash {
using namespace Genode;
@@ -49,44 +45,73 @@ struct Rom_hash::Session :
Id_space<Parent::Client>::Element client_id;
Id_space<Parent::Server>::Element server_id;
void verify(CryptoPP::HashTransformation &hash,
void verify(Session_label const &label,
CryptoPP::HashTransformation &hash,
Genode::Xml_attribute &attr);
Session(Id_space<Parent::Client> &client_space,
Id_space<Parent::Server> &server_space,
Parent::Server::Id server_id,
Genode::Env &env, Args const &args,
Session_policy const &policy);
Genode::Env &env,
Session_label const &label,
Session_policy const &policy,
Args const &args);
};
void Rom_hash::Session::verify(CryptoPP::HashTransformation &hash,
void Rom_hash::Session::verify(Session_label const &label,
CryptoPP::HashTransformation &hash,
Genode::Xml_attribute &attr)
{
unsigned const digest_size = hash.DigestSize();
using namespace CryptoPP;
std::string const hex_target(attr.value_base(), attr.value_size());
std::string bin_target;
{
HexDecoder decoder;
decoder.Put((byte*)hex_target.data(), hex_target.size());
decoder.MessageEnd();
bin_target.resize(decoder.MaxRetrievable());
decoder.Get((byte*)bin_target.data(), bin_target.size());
}
log(label, " ", hex_target.c_str());
unsigned const digest_size = hash.DigestSize();
uint8_t digest[digest_size];
/* read the connection dataspace */
Rom_session_client rom(cap());
Attached_dataspace ds(_env.rm(), rom.dataspace());
Genode::log("'", ds.local_addr<const char>(), "'");
hash.CalculateDigest(digest, ds.local_addr<const byte>(), ds.size());
/* compare with hexadecimal */
char const *text = attr.value_base();
for (unsigned i = 0, j = 0; i < digest_size && j < attr.value_size(); ++i)
if ((alph[digest[i] >> 4] != text[j++]) ||
(alph[digest[i]&0x0F] != text[j++]))
throw ~0;
for (unsigned i = 0; i < bin_target.size(); ++i) {
if ((uint8_t)digest[i] != (uint8_t)bin_target[i]) {
Genode::log("mismatch at index ", i);
std::string encoded;
HexEncoder encoder;
encoder.Put((byte*)digest, digest_size);
encoded.resize(encoder.MaxRetrievable());
encoder.Get((byte*)encoded.data(), encoded.size());
error(label, " ", encoded.c_str());
throw Service_denied();
}
}
}
Rom_hash::Session::Session(Id_space<Parent::Client> &client_space,
Id_space<Parent::Server> &server_space,
Parent::Server::Id server_id,
Genode::Env &env, Args const &args,
Session_policy const &policy)
Genode::Env &env,
Session_label const &label,
Session_policy const &policy,
Args const &args)
:
Connection<Rom_session>(env, session(env.parent(), args.string())),
client_id(parent_client, client_space),
@@ -95,33 +120,33 @@ Rom_hash::Session::Session(Id_space<Parent::Client> &client_space,
try {
Xml_attribute attr = policy.attribute("sha3");
CryptoPP::SHA3 hash(attr.value_size()/2);
verify(hash, attr);
verify(label, hash, attr);
return;
} catch (Xml_node::Nonexistent_attribute) { }
try {
Xml_attribute attr = policy.attribute("sha512");
CryptoPP::SHA512 hash;
verify(hash, attr);
verify(label, hash, attr);
return;
} catch (Xml_node::Nonexistent_attribute) { }
try {
Xml_attribute attr = policy.attribute("sha256");
CryptoPP::SHA256 hash;
verify(hash, attr);
verify(label, hash, attr);
return;
} catch (Xml_node::Nonexistent_attribute) { }
try {
Xml_attribute attr = policy.attribute("sha1");
CryptoPP::SHA1 hash;
verify(hash, attr);
verify(label, hash, attr);
return;
} catch (Xml_node::Nonexistent_attribute) { }
error("no hash policy found");
throw ~0;
throw Service_denied();
}
@@ -198,7 +223,7 @@ void Rom_hash::Main::handle_session_request(Xml_node request)
Session_policy const policy(label, config_rom.xml());
Session *session = new (alloc)
Session(env.id_space(), server_id_space, server_id, env, args, policy);
Session(env.id_space(), server_id_space, server_id, env, label, policy, args);
if (session) {
env.parent().deliver_session_cap(server_id, session->cap());
return;
@@ -208,7 +233,7 @@ void Rom_hash::Main::handle_session_request(Xml_node request)
warning("no policy for '",label,"'");
} catch (...) { }
env.parent().session_response(server_id, Parent::INVALID_ARGS);
env.parent().session_response(server_id, Parent::SERVICE_DENIED);
}
if (request.has_type("upgrade")) {