aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornagendra modadugu <ngm@google.com>2018-06-06 17:31:12 -0700
committerNagendra Modadugu <ngm@google.com>2018-06-26 21:01:50 +0000
commitcf3c154a081326e4d8e3ed84ed966471e687b0fb (patch)
tree0905187cfc14be43eb5b4d78db13468867a89aca
parentfcf47acccf4c98316ed23988b1377f123d2bcc77 (diff)
downloadandroid-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.cpp109
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(&not_before)) == 0 ||
+ ::strftime(not_after_str, sizeof(not_after_str),
+ "%y%m%d%H%M%SZ", gmtime(&not_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());