diff options
author | nagendra modadugu <ngm@google.com> | 2018-06-06 17:31:12 -0700 |
---|---|---|
committer | Nagendra Modadugu <ngm@google.com> | 2018-06-26 21:01:50 +0000 |
commit | cf3c154a081326e4d8e3ed84ed966471e687b0fb (patch) | |
tree | 0905187cfc14be43eb5b4d78db13468867a89aca | |
parent | fcf47acccf4c98316ed23988b1377f123d2bcc77 (diff) | |
download | android-cf3c154a081326e4d8e3ed84ed966471e687b0fb.tar.gz |
keymaster: fill in attest rpc's
Grab necessary key param info, etc.
and marshall out attest related rpc's.
Bug: 38428944
Change-Id: I3ee789ee70f5a21cf5725f26e0e064d3f43f6ade
-rw-r--r-- | hals/keymaster/KeymasterDevice.cpp | 109 |
1 files changed, 99 insertions, 10 deletions
diff --git a/hals/keymaster/KeymasterDevice.cpp b/hals/keymaster/KeymasterDevice.cpp index 6303599..677bc65 100644 --- a/hals/keymaster/KeymasterDevice.cpp +++ b/hals/keymaster/KeymasterDevice.cpp @@ -32,6 +32,8 @@ #include <algorithm> +#include <time.h> + namespace android { namespace hardware { namespace keymaster { @@ -184,6 +186,9 @@ using ::nugget::app::keymaster::GetBootInfoResponse; using ::nugget::app::keymaster::ImportWrappedKeyRequest; namespace nosapp = ::nugget::app::keymaster; +// KM internal types +using ::nugget::app::keymaster::AttestationSelector; + static ErrorCode status_to_error_code(uint32_t status) { switch (status) { @@ -525,6 +530,9 @@ Return<void> KeymasterDevice::exportKey( return Void(); } +#define ATTESTATION_APPLICATION_ID_MAX_SIZE 1024 +#define UTCTIME_STR_WITH_NUL_SIZE 14 + Return<void> KeymasterDevice::attestKey( const hidl_vec<uint8_t>& keyToAttest, const hidl_vec<KeyParameter>& attestParams, @@ -535,18 +543,96 @@ Return<void> KeymasterDevice::attestKey( StartAttestKeyRequest startRequest; StartAttestKeyResponse startResponse; - startRequest.mutable_blob()->set_blob(&keyToAttest[0], keyToAttest.size()); + // Ensure that required parameters are present. + tag_map_t attest_tag_map; + if (hidl_params_to_map(attestParams, &attest_tag_map) != ErrorCode::OK) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, hidl_vec<hidl_vec<uint8_t> >{}); + return Void(); + } + if (attest_tag_map.find(Tag::ATTESTATION_APPLICATION_ID) == + attest_tag_map.end()) { + _hidl_cb(ErrorCode::ATTESTATION_APPLICATION_ID_MISSING, + hidl_vec<hidl_vec<uint8_t> >{}); + return Void(); + } - vector<hidl_vec<uint8_t> > chain; + hidl_vec<uint8_t> client_id; + if (attest_tag_map.find(Tag::APPLICATION_ID) != attest_tag_map.end()) { + client_id = attest_tag_map.find(Tag::APPLICATION_ID)->second[0].blob; + } + hidl_vec<uint8_t> app_data; + if (attest_tag_map.find(Tag::APPLICATION_DATA) != attest_tag_map.end()) { + app_data = attest_tag_map.find( + Tag::APPLICATION_DATA)->second[0].blob; + } + + GetKeyCharacteristicsRequest charRequest; + GetKeyCharacteristicsResponse charResponse; + + charRequest.mutable_blob()->set_blob(&keyToAttest[0], keyToAttest.size()); + charRequest.set_client_id(&client_id[0], client_id.size()); + charRequest.set_app_data(&app_data[0], app_data.size()); + + // Call device. + KM_CALLV(GetKeyCharacteristics, charRequest, + charResponse, hidl_vec<hidl_vec<uint8_t> >{}); + + KeyCharacteristics characteristics; + pb_to_hidl_params(charResponse.characteristics().software_enforced(), + &characteristics.softwareEnforced); + pb_to_hidl_params(charResponse.characteristics().tee_enforced(), + &characteristics.hardwareEnforced); + + tag_map_t char_tag_map; + if (hidl_params_to_map(characteristics.softwareEnforced, + &attest_tag_map) != ErrorCode::OK) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, hidl_vec<hidl_vec<uint8_t> >{}); + return Void(); + } + + time_t not_before = 0; + if (char_tag_map.find(Tag::ACTIVE_DATETIME) != char_tag_map.end()) { + not_before = char_tag_map.find( + Tag::ACTIVE_DATETIME)->second[0].f.dateTime; + } else if (char_tag_map.find(Tag::CREATION_DATETIME) != + char_tag_map.end()) { + not_before = char_tag_map.find( + Tag::CREATION_DATETIME)->second[0].f.dateTime; + } + // TODO: else: both ACTIVE and CREATION datetime are absent, is + // this an error? + time_t not_after = 0; + if (char_tag_map.find(Tag::USAGE_EXPIRE_DATETIME) != char_tag_map.end()) { + not_after = char_tag_map.find( + Tag::USAGE_EXPIRE_DATETIME)->second[0].f.dateTime; + } else { + not_after = 1842739199; // Batch cert expiry date: 2028-05-23:23:59:59. + } + + char not_before_str[UTCTIME_STR_WITH_NUL_SIZE] = {}; + char not_after_str[UTCTIME_STR_WITH_NUL_SIZE] = {}; + if (::strftime(not_before_str, sizeof(not_before_str), + "%y%m%d%H%M%SZ", gmtime(¬_before)) == 0 || + ::strftime(not_after_str, sizeof(not_after_str), + "%y%m%d%H%M%SZ", gmtime(¬_after)) == 0) { + _hidl_cb(ErrorCode::UNKNOWN_ERROR, hidl_vec<hidl_vec<uint8_t> >{}); + } + + startRequest.mutable_blob()->set_blob(&keyToAttest[0], keyToAttest.size()); if (hidl_params_to_pb( attestParams, startRequest.mutable_params()) != ErrorCode::OK) { - _hidl_cb(ErrorCode::INVALID_ARGUMENT, chain); + _hidl_cb(ErrorCode::INVALID_ARGUMENT, hidl_vec<hidl_vec<uint8_t> >{}); return Void(); } + startRequest.set_selector(AttestationSelector::ATTEST_BATCH); + startRequest.set_not_before(not_before_str, + sizeof(not_before_str) - 1); + startRequest.set_not_after(not_after_str, + sizeof(not_after_str) - 1); - // TODO: - // startRequest.set_attestation_app_id_len( - // attestation_app_id_len(attestParams)); + // TODO: as an optimization, avoid sending the + // ATTESTATION_APPLICATION_ID to Start, since only the length of + // this field is needed at this stage. KM_CALLV(StartAttestKey, startRequest, startResponse, hidl_vec<hidl_vec<uint8_t> >{}); @@ -556,9 +642,11 @@ Return<void> KeymasterDevice::attestKey( ContinueAttestKeyResponse continueResponse; continueRequest.mutable_handle()->set_handle(operationHandle); - // TODO - // continueRequest.set_attestation_app_id( - // attestation_app_id(attestParams)); + if (hidl_params_to_pb( + attestParams, continueRequest.mutable_params()) != ErrorCode::OK) { + _hidl_cb(ErrorCode::INVALID_ARGUMENT, hidl_vec<hidl_vec<uint8_t> >{}); + return Void(); + } KM_CALLV(ContinueAttestKey, continueRequest, continueResponse, hidl_vec<hidl_vec<uint8_t> >{}); @@ -582,6 +670,7 @@ Return<void> KeymasterDevice::attestKey( const_cast<char*>(ss.str().data())), ss.str().size(), false); + vector<hidl_vec<uint8_t> > chain; chain.push_back(attestation_certificate); // TODO: // chain.push_back(intermediate_certificate()); @@ -676,7 +765,6 @@ Return<void> KeymasterDevice::begin( request.mutable_blob()->set_blob(&key[0], key.size()); hidl_vec<KeyParameter> params; - tag_map_t tag_map; if (translate_auth_token( authToken, request.mutable_auth_token()) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, params, @@ -689,6 +777,7 @@ Return<void> KeymasterDevice::begin( response.handle().handle()); return Void(); } + tag_map_t tag_map; if (hidl_params_to_map(inParams, &tag_map) != ErrorCode::OK) { _hidl_cb(ErrorCode::INVALID_ARGUMENT, params, response.handle().handle()); |