summaryrefslogtreecommitdiffstats
path: root/trusty
diff options
context:
space:
mode:
authorJocelyn Bohr <bohr@google.com>2017-02-09 17:32:47 -0800
committerJocelyn Bohr <bohr@google.com>2017-04-10 17:33:49 -0700
commita256198b92f39dd93a20a2599990c087f7dbba73 (patch)
tree9128b885e77897ff4a7b8fb56d4205de347d13d3 /trusty
parent4cbfa7f2f0dcbea559b46487c1d9f4560eba4f0b (diff)
downloadsystem_core-a256198b92f39dd93a20a2599990c087f7dbba73.tar.gz
system_core-a256198b92f39dd93a20a2599990c087f7dbba73.tar.bz2
system_core-a256198b92f39dd93a20a2599990c087f7dbba73.zip
trusty: keymaster: Implement attest_key
Test: builds Change-Id: Ic5bf59db43b4301cbc2fa216470b9f07de8336b0
Diffstat (limited to 'trusty')
-rw-r--r--trusty/keymaster/keymaster_ipc.h1
-rw-r--r--trusty/keymaster/trusty_keymaster_device.cpp58
2 files changed, 59 insertions, 0 deletions
diff --git a/trusty/keymaster/keymaster_ipc.h b/trusty/keymaster/keymaster_ipc.h
index f970e363c..6a7378c31 100644
--- a/trusty/keymaster/keymaster_ipc.h
+++ b/trusty/keymaster/keymaster_ipc.h
@@ -42,6 +42,7 @@ enum keymaster_command : uint32_t {
KM_GET_SUPPORTED_IMPORT_FORMATS = (13 << KEYMASTER_REQ_SHIFT),
KM_GET_SUPPORTED_EXPORT_FORMATS = (14 << KEYMASTER_REQ_SHIFT),
KM_GET_KEY_CHARACTERISTICS = (15 << KEYMASTER_REQ_SHIFT),
+ KM_ATTEST_KEY = (16 << KEYMASTER_REQ_SHIFT),
KM_CONFIGURE = (18 << KEYMASTER_REQ_SHIFT),
};
diff --git a/trusty/keymaster/trusty_keymaster_device.cpp b/trusty/keymaster/trusty_keymaster_device.cpp
index 361045624..08a1c6ac7 100644
--- a/trusty/keymaster/trusty_keymaster_device.cpp
+++ b/trusty/keymaster/trusty_keymaster_device.cpp
@@ -39,6 +39,8 @@
const uint32_t RECV_BUF_SIZE = PAGE_SIZE;
const uint32_t SEND_BUF_SIZE = (PAGE_SIZE - sizeof(struct keymaster_message) - 16 /* tipc header */);
+const size_t kMaximumAttestationChallengeLength = 128;
+
namespace keymaster {
static keymaster_error_t translate_error(int err) {
@@ -361,6 +363,62 @@ keymaster_error_t TrustyKeymasterDevice::attest_key(const keymaster_key_blob_t*
const keymaster_key_param_set_t* attest_params,
keymaster_cert_chain_t* cert_chain) {
ALOGD("Device received attest_key");
+
+ if (error_ != KM_ERROR_OK) {
+ return error_;
+ }
+ if (!key_to_attest || !attest_params) {
+ return KM_ERROR_UNEXPECTED_NULL_POINTER;
+ }
+ if (!cert_chain) {
+ return KM_ERROR_OUTPUT_PARAMETER_NULL;
+ }
+
+ cert_chain->entry_count = 0;
+ cert_chain->entries = nullptr;
+
+ AttestKeyRequest request;
+ request.SetKeyMaterial(*key_to_attest);
+ request.attest_params.Reinitialize(*attest_params);
+
+ keymaster_blob_t attestation_challenge = {};
+ request.attest_params.GetTagValue(TAG_ATTESTATION_CHALLENGE, &attestation_challenge);
+ if (attestation_challenge.data_length > kMaximumAttestationChallengeLength) {
+ ALOGE("%zu-byte attestation challenge; only %zu bytes allowed",
+ attestation_challenge.data_length, kMaximumAttestationChallengeLength);
+ return KM_ERROR_INVALID_INPUT_LENGTH;
+ }
+
+ AttestKeyResponse response;
+ keymaster_error_t err = Send(KM_ATTEST_KEY, request, &response);
+ if (err != KM_ERROR_OK) {
+ return err;
+ }
+
+ // Allocate and clear storage for cert_chain.
+ keymaster_cert_chain_t& rsp_chain = response.certificate_chain;
+ cert_chain->entries = reinterpret_cast<keymaster_blob_t*>(
+ malloc(rsp_chain.entry_count * sizeof(*cert_chain->entries)));
+ if (!cert_chain->entries) {
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ cert_chain->entry_count = rsp_chain.entry_count;
+ for (keymaster_blob_t& entry : array_range(cert_chain->entries, cert_chain->entry_count)) {
+ entry = {};
+ }
+
+ // Copy cert_chain contents
+ size_t i = 0;
+ for (keymaster_blob_t& entry : array_range(rsp_chain.entries, rsp_chain.entry_count)) {
+ cert_chain->entries[i].data = DuplicateBuffer(entry.data, entry.data_length);
+ if (!cert_chain->entries[i].data) {
+ keymaster_free_cert_chain(cert_chain);
+ return KM_ERROR_MEMORY_ALLOCATION_FAILED;
+ }
+ cert_chain->entries[i].data_length = entry.data_length;
+ ++i;
+ }
+
return KM_ERROR_OK;
}