diff options
author | Shawn Willden <swillden@google.com> | 2016-01-05 18:01:46 -0700 |
---|---|---|
committer | Shawn Willden <swillden@google.com> | 2016-01-27 16:14:07 -0700 |
commit | 3d68cf64fb4bcea55406c3b6844b397ad264d8b2 (patch) | |
tree | 44c9245cb540e21ced75caf7e7480bb9a25a19a0 | |
parent | 239c1664173c941038a1d1d13626e58ce3cef819 (diff) | |
download | keymaster-3d68cf64fb4bcea55406c3b6844b397ad264d8b2.tar.gz |
Add attestation request/response messages
Bug: 22914603
Change-Id: I6f21da2bd7050519dd2b58a10ecacfef71d174c4
-rw-r--r-- | android_keymaster_messages.cpp | 84 | ||||
-rw-r--r-- | android_keymaster_messages_test.cpp | 38 | ||||
-rw-r--r-- | include/keymaster/android_keymaster_messages.h | 65 |
3 files changed, 173 insertions, 14 deletions
diff --git a/android_keymaster_messages.cpp b/android_keymaster_messages.cpp index bedb058..ddac3b6 100644 --- a/android_keymaster_messages.cpp +++ b/android_keymaster_messages.cpp @@ -414,4 +414,88 @@ bool GetVersionResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint return true; } +AttestKeyRequest::~AttestKeyRequest() { + delete[] key_blob.key_material; +} + +void AttestKeyRequest::SetKeyMaterial(const void* key_material, size_t length) { + set_key_blob(&key_blob, key_material, length); +} + +size_t AttestKeyRequest::SerializedSize() const { + return key_blob_size(key_blob) + attest_params.SerializedSize(); +} + +uint8_t* AttestKeyRequest::Serialize(uint8_t* buf, const uint8_t* end) const { + buf = serialize_key_blob(key_blob, buf, end); + return attest_params.Serialize(buf, end); +} + +bool AttestKeyRequest::Deserialize(const uint8_t** buf_ptr, const uint8_t* end) { + return deserialize_key_blob(&key_blob, buf_ptr, end) && attest_params.Deserialize(buf_ptr, end); +} + +AttestKeyResponse::~AttestKeyResponse() { + for (size_t i = 0; i < certificate_chain.entry_count; ++i) + delete[] certificate_chain.entries[i].data; + delete[] certificate_chain.entries; +} + +const size_t kMaxChainEntryCount = 10; +bool AttestKeyResponse::AllocateChain(size_t entry_count) { + if (entry_count > kMaxChainEntryCount) + return false; + + if (certificate_chain.entries) { + for (size_t i = 0; i < certificate_chain.entry_count; ++i) + delete[] certificate_chain.entries[i].data; + delete[] certificate_chain.entries; + } + + certificate_chain.entry_count = entry_count; + certificate_chain.entries = new keymaster_blob_t[entry_count]; + if (!certificate_chain.entries) { + certificate_chain.entry_count = 0; + return false; + } + + memset(certificate_chain.entries, 0, sizeof(certificate_chain.entries[0]) * entry_count); + return true; +} + +size_t AttestKeyResponse::NonErrorSerializedSize() const { + size_t result = sizeof(uint32_t); /* certificate_chain.entry_count */ + for (size_t i = 0; i < certificate_chain.entry_count; ++i) { + result += sizeof(uint32_t); /* certificate_chain.entries[i].data_length */ + result += certificate_chain.entries[i].data_length; + } + return result; +} + +uint8_t* AttestKeyResponse::NonErrorSerialize(uint8_t* buf, const uint8_t* end) const { + buf = append_uint32_to_buf(buf, end, certificate_chain.entry_count); + for (size_t i = 0; i < certificate_chain.entry_count; ++i) { + buf = append_size_and_data_to_buf(buf, end, certificate_chain.entries[i].data, + certificate_chain.entries[i].data_length); + } + return buf; +} + +bool AttestKeyResponse::NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) { + size_t entry_count; + if (!copy_uint32_from_buf(buf_ptr, end, &entry_count) || !AllocateChain(entry_count)) + return false; + + for (size_t i = 0; i < certificate_chain.entry_count; ++i) { + UniquePtr<uint8_t[]> data; + size_t data_length; + if (!copy_size_and_data_from_buf(buf_ptr, end, &data_length, &data)) + return false; + certificate_chain.entries[i].data = data.release(); + certificate_chain.entries[i].data_length = data_length; + } + + return true; +} + } // namespace keymaster diff --git a/android_keymaster_messages_test.cpp b/android_keymaster_messages_test.cpp index 913dd1c..d987af0 100644 --- a/android_keymaster_messages_test.cpp +++ b/android_keymaster_messages_test.cpp @@ -532,6 +532,42 @@ TEST(RoundTrip, AbortOperationResponse) { } } +TEST(RoundTrip, AttestKeyRequest) { + for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { + AttestKeyRequest msg(ver); + msg.SetKeyMaterial("foo", 3); + msg.attest_params.Reinitialize(params, array_length(params)); + + UniquePtr<AttestKeyRequest> deserialized(round_trip(ver, msg, 85)); + EXPECT_EQ(3U, deserialized->key_blob.key_material_size); + EXPECT_EQ(0, memcmp("foo", deserialized->key_blob.key_material, 3)); + EXPECT_EQ(msg.attest_params, deserialized->attest_params); + } +} + +TEST(RoundTrip, AttestKeyResponse) { + for (int ver = 0; ver <= MAX_MESSAGE_VERSION; ++ver) { + AttestKeyResponse msg(ver); + msg.error = KM_ERROR_OK; + EXPECT_TRUE(msg.AllocateChain(3)); + msg.certificate_chain.entries[0] = {dup_buffer("foo", 3), 3}; + msg.certificate_chain.entries[1] = {dup_buffer("bar", 3), 3}; + msg.certificate_chain.entries[2] = {dup_buffer("baz", 3), 3}; + + UniquePtr<AttestKeyResponse> deserialized(round_trip(ver, msg, 29)); + keymaster_cert_chain_t* chain = &deserialized->certificate_chain; + + EXPECT_NE(nullptr, chain->entries); + EXPECT_EQ(3U, chain->entry_count); + EXPECT_EQ(3U, chain->entries[0].data_length); + EXPECT_EQ(0, memcmp("foo", chain->entries[0].data, 3)); + EXPECT_EQ(3U, chain->entries[1].data_length); + EXPECT_EQ(0, memcmp("bar", chain->entries[1].data, 3)); + EXPECT_EQ(3U, chain->entries[2].data_length); + EXPECT_EQ(0, memcmp("baz", chain->entries[2].data, 3)); + } +} + uint8_t msgbuf[] = { 220, 88, 183, 255, 71, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 228, 174, 98, 187, 191, 135, 253, 200, 51, 230, 114, 247, 151, 109, @@ -624,6 +660,8 @@ GARBAGE_TEST(SupportedByAlgorithmAndPurposeRequest) GARBAGE_TEST(SupportedByAlgorithmRequest) GARBAGE_TEST(UpdateOperationRequest); GARBAGE_TEST(UpdateOperationResponse); +GARBAGE_TEST(AttestKeyRequest); +GARBAGE_TEST(AttestKeyResponse); // The macro doesn't work on this one. TEST(GarbageTest, SupportedResponse) { diff --git a/include/keymaster/android_keymaster_messages.h b/include/keymaster/android_keymaster_messages.h index 7fc300b..bc08dc3 100644 --- a/include/keymaster/android_keymaster_messages.h +++ b/include/keymaster/android_keymaster_messages.h @@ -21,8 +21,8 @@ #include <stdlib.h> #include <string.h> -#include <keymaster/authorization_set.h> #include <keymaster/android_keymaster_utils.h> +#include <keymaster/authorization_set.h> namespace keymaster { @@ -44,6 +44,7 @@ enum AndroidKeymasterCommand { GET_SUPPORTED_IMPORT_FORMATS = 13, GET_SUPPORTED_EXPORT_FORMATS = 14, GET_KEY_CHARACTERISTICS = 15, + ATTEST_KEY = 16, }; /** @@ -165,16 +166,16 @@ class SupportedDigestsRequest : public SupportedByAlgorithmAndPurposeRequest {}; template <typename T> struct SupportedResponse : public KeymasterResponse { explicit SupportedResponse(int32_t ver = MAX_MESSAGE_VERSION) - : KeymasterResponse(ver), results(NULL), results_length(0) {} + : KeymasterResponse(ver), results(nullptr), results_length(0) {} ~SupportedResponse() { delete[] results; } - template <size_t N> void SetResults(const T(&arr)[N]) { SetResults(arr, N); } + template <size_t N> void SetResults(const T (&arr)[N]) { SetResults(arr, N); } void SetResults(const T* arr, size_t n) { delete[] results; results_length = 0; results = dup_array(arr, n); - if (results == NULL) { + if (results == nullptr) { error = KM_ERROR_MEMORY_ALLOCATION_FAILED; } else { results_length = n; @@ -190,7 +191,7 @@ template <typename T> struct SupportedResponse : public KeymasterResponse { } bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override { delete[] results; - results = NULL; + results = nullptr; UniquePtr<T[]> tmp; if (!copy_uint32_array_from_buf(buf_ptr, end, &tmp, &results_length)) return false; @@ -225,7 +226,7 @@ struct GenerateKeyRequest : public KeymasterMessage { struct GenerateKeyResponse : public KeymasterResponse { explicit GenerateKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) { - key_blob.key_material = NULL; + key_blob.key_material = nullptr; key_blob.key_material_size = 0; } ~GenerateKeyResponse(); @@ -242,7 +243,7 @@ struct GenerateKeyResponse : public KeymasterResponse { struct GetKeyCharacteristicsRequest : public KeymasterMessage { explicit GetKeyCharacteristicsRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) { - key_blob.key_material = NULL; + key_blob.key_material = nullptr; key_blob.key_material_size = 0; } ~GetKeyCharacteristicsRequest(); @@ -273,7 +274,7 @@ struct GetKeyCharacteristicsResponse : public KeymasterResponse { struct BeginOperationRequest : public KeymasterMessage { explicit BeginOperationRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) { - key_blob.key_material = NULL; + key_blob.key_material = nullptr; key_blob.key_material_size = 0; } ~BeginOperationRequest() { delete[] key_blob.key_material; } @@ -397,7 +398,7 @@ struct AddEntropyResponse : public KeymasterResponse { struct ImportKeyRequest : public KeymasterMessage { explicit ImportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) - : KeymasterMessage(ver), key_data(NULL) {} + : KeymasterMessage(ver), key_data(nullptr) {} ~ImportKeyRequest() { delete[] key_data; } void SetKeyMaterial(const void* key_material, size_t length); @@ -417,7 +418,7 @@ struct ImportKeyRequest : public KeymasterMessage { struct ImportKeyResponse : public KeymasterResponse { explicit ImportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) { - key_blob.key_material = NULL; + key_blob.key_material = nullptr; key_blob.key_material_size = 0; } ~ImportKeyResponse() { delete[] key_blob.key_material; } @@ -438,7 +439,7 @@ struct ImportKeyResponse : public KeymasterResponse { struct ExportKeyRequest : public KeymasterMessage { explicit ExportKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) { - key_blob.key_material = NULL; + key_blob.key_material = nullptr; key_blob.key_material_size = 0; } ~ExportKeyRequest() { delete[] key_blob.key_material; } @@ -459,7 +460,7 @@ struct ExportKeyRequest : public KeymasterMessage { struct ExportKeyResponse : public KeymasterResponse { explicit ExportKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) - : KeymasterResponse(ver), key_data(NULL) {} + : KeymasterResponse(ver), key_data(nullptr) {} ~ExportKeyResponse() { delete[] key_data; } void SetKeyMaterial(const void* key_material, size_t length); @@ -519,7 +520,7 @@ struct DeleteAllKeysResponse : public KeymasterResponse { }; struct GetVersionRequest : public KeymasterMessage { - explicit GetVersionRequest() : KeymasterMessage(0 /* not versionable */) {} + GetVersionRequest() : KeymasterMessage(0 /* not versionable */) {} size_t SerializedSize() const override { return 0; } uint8_t* Serialize(uint8_t* buf, const uint8_t*) const override { return buf; } @@ -527,7 +528,7 @@ struct GetVersionRequest : public KeymasterMessage { }; struct GetVersionResponse : public KeymasterResponse { - explicit GetVersionResponse() + GetVersionResponse() : KeymasterResponse(0 /* not versionable */), major_ver(0), minor_ver(0), subminor_ver(0) {} size_t NonErrorSerializedSize() const override; @@ -539,6 +540,42 @@ struct GetVersionResponse : public KeymasterResponse { uint8_t subminor_ver; }; +struct AttestKeyRequest : public KeymasterMessage { + explicit AttestKeyRequest(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterMessage(ver) { + key_blob.key_material = nullptr; + key_blob.key_material_size = 0; + } + ~AttestKeyRequest(); + + void SetKeyMaterial(const void* key_material, size_t length); + void SetKeyMaterial(const keymaster_key_blob_t& blob) { + SetKeyMaterial(blob.key_material, blob.key_material_size); + } + + size_t SerializedSize() const override; + uint8_t* Serialize(uint8_t* buf, const uint8_t* end) const override; + bool Deserialize(const uint8_t** buf_ptr, const uint8_t* end) override; + + keymaster_key_blob_t key_blob; + AuthorizationSet attest_params; +}; + +struct AttestKeyResponse : public KeymasterResponse { + explicit AttestKeyResponse(int32_t ver = MAX_MESSAGE_VERSION) : KeymasterResponse(ver) { + certificate_chain.entry_count = 0; + certificate_chain.entries = nullptr; + } + ~AttestKeyResponse(); + + bool AllocateChain(size_t entry_count); + + size_t NonErrorSerializedSize() const override; + uint8_t* NonErrorSerialize(uint8_t* buf, const uint8_t* end) const override; + bool NonErrorDeserialize(const uint8_t** buf_ptr, const uint8_t* end) override; + + keymaster_cert_chain_t certificate_chain; +}; + } // namespace keymaster #endif // SYSTEM_KEYMASTER_ANDROID_KEYMASTER_MESSAGES_H_ |