summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShawn Willden <swillden@google.com>2016-01-05 18:01:46 -0700
committerShawn Willden <swillden@google.com>2016-01-27 16:14:07 -0700
commit3d68cf64fb4bcea55406c3b6844b397ad264d8b2 (patch)
tree44c9245cb540e21ced75caf7e7480bb9a25a19a0
parent239c1664173c941038a1d1d13626e58ce3cef819 (diff)
downloadkeymaster-3d68cf64fb4bcea55406c3b6844b397ad264d8b2.tar.gz
Add attestation request/response messages
Bug: 22914603 Change-Id: I6f21da2bd7050519dd2b58a10ecacfef71d174c4
-rw-r--r--android_keymaster_messages.cpp84
-rw-r--r--android_keymaster_messages_test.cpp38
-rw-r--r--include/keymaster/android_keymaster_messages.h65
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_