diff options
| author | Jocelyn Bohr <bohr@google.com> | 2017-02-09 17:32:47 -0800 |
|---|---|---|
| committer | Jocelyn Bohr <bohr@google.com> | 2017-04-10 17:33:49 -0700 |
| commit | a256198b92f39dd93a20a2599990c087f7dbba73 (patch) | |
| tree | 9128b885e77897ff4a7b8fb56d4205de347d13d3 /trusty | |
| parent | 4cbfa7f2f0dcbea559b46487c1d9f4560eba4f0b (diff) | |
| download | system_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.h | 1 | ||||
| -rw-r--r-- | trusty/keymaster/trusty_keymaster_device.cpp | 58 |
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; } |
