summaryrefslogtreecommitdiffstats
path: root/trusty
diff options
context:
space:
mode:
authorJocelyn Bohr2017-07-06 18:24:01 -0500
committerJocelyn Bohr2017-08-10 18:53:27 -0500
commitb3ed3772b9133ddd4e992e2f9c2fe959c4602dae (patch)
tree42fe35f05a6840087dacf5ad470ddaa447d7275a /trusty
parent6fa0884188dbc27b59b2fa3f86fb317bb1381252 (diff)
downloadplatform-system-core-b3ed3772b9133ddd4e992e2f9c2fe959c4602dae.tar.gz
platform-system-core-b3ed3772b9133ddd4e992e2f9c2fe959c4602dae.tar.xz
platform-system-core-b3ed3772b9133ddd4e992e2f9c2fe959c4602dae.zip
Enable non-secure side to receive messages > 4K
AttestKeyResponse may be larger than 4K (always less than 8K) when attesting an RSA key. This change allows the non-secure side to read a response that may be larger than 4K by adding an additional bit indicating the end of a response. If a message command has the KEYMASTER_STOP_BIT set, then the non-secure side knows that the response has been fully read. Test: android.keystore.cts.KeyAttestationTest#testRsaAttestation passes with production attestation key and chain, when AttestKeyResponse is larger than 4K. Tested with other CTS tests when keymaster messages are smaller than 4K, still passes. Manual test to verify that a tipc error due to large message size is handled correctly. Bug: 63335726 Change-Id: I8776ba7ca70da893648e15cfa770784ab31a2cb0
Diffstat (limited to 'trusty')
-rw-r--r--trusty/keymaster/keymaster_ipc.h3
-rw-r--r--trusty/keymaster/trusty_keymaster_device.cpp9
-rw-r--r--trusty/keymaster/trusty_keymaster_ipc.cpp57
3 files changed, 43 insertions, 26 deletions
diff --git a/trusty/keymaster/keymaster_ipc.h b/trusty/keymaster/keymaster_ipc.h
index b38eb0592..d63757b36 100644
--- a/trusty/keymaster/keymaster_ipc.h
+++ b/trusty/keymaster/keymaster_ipc.h
@@ -24,7 +24,8 @@
24// Commands 24// Commands
25enum keymaster_command : uint32_t { 25enum keymaster_command : uint32_t {
26 KEYMASTER_RESP_BIT = 1, 26 KEYMASTER_RESP_BIT = 1,
27 KEYMASTER_REQ_SHIFT = 1, 27 KEYMASTER_STOP_BIT = 2,
28 KEYMASTER_REQ_SHIFT = 2,
28 29
29 KM_GENERATE_KEY = (0 << KEYMASTER_REQ_SHIFT), 30 KM_GENERATE_KEY = (0 << KEYMASTER_REQ_SHIFT),
30 KM_BEGIN_OPERATION = (1 << KEYMASTER_REQ_SHIFT), 31 KM_BEGIN_OPERATION = (1 << KEYMASTER_REQ_SHIFT),
diff --git a/trusty/keymaster/trusty_keymaster_device.cpp b/trusty/keymaster/trusty_keymaster_device.cpp
index 5f16fd0c0..e2342f3ba 100644
--- a/trusty/keymaster/trusty_keymaster_device.cpp
+++ b/trusty/keymaster/trusty_keymaster_device.cpp
@@ -36,7 +36,8 @@
36#include "trusty_keymaster_device.h" 36#include "trusty_keymaster_device.h"
37#include "trusty_keymaster_ipc.h" 37#include "trusty_keymaster_ipc.h"
38 38
39const uint32_t RECV_BUF_SIZE = PAGE_SIZE; 39// Maximum size of message from Trusty is 8K (for RSA attestation key and chain)
40const uint32_t RECV_BUF_SIZE = 2*PAGE_SIZE;
40const uint32_t SEND_BUF_SIZE = (PAGE_SIZE - sizeof(struct keymaster_message) - 16 /* tipc header */); 41const uint32_t SEND_BUF_SIZE = (PAGE_SIZE - sizeof(struct keymaster_message) - 16 /* tipc header */);
41 42
42const size_t kMaximumAttestationChallengeLength = 128; 43const size_t kMaximumAttestationChallengeLength = 128;
@@ -768,6 +769,9 @@ keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializab
768 ALOGV("Sending %d byte request\n", (int)req.SerializedSize()); 769 ALOGV("Sending %d byte request\n", (int)req.SerializedSize());
769 int rc = trusty_keymaster_call(command, send_buf, req_size, recv_buf, &rsp_size); 770 int rc = trusty_keymaster_call(command, send_buf, req_size, recv_buf, &rsp_size);
770 if (rc < 0) { 771 if (rc < 0) {
772 // Reset the connection on tipc error
773 trusty_keymaster_disconnect();
774 trusty_keymaster_connect();
771 ALOGE("tipc error: %d\n", rc); 775 ALOGE("tipc error: %d\n", rc);
772 // TODO(swillden): Distinguish permanent from transient errors and set error_ appropriately. 776 // TODO(swillden): Distinguish permanent from transient errors and set error_ appropriately.
773 return translate_error(rc); 777 return translate_error(rc);
@@ -775,8 +779,7 @@ keymaster_error_t TrustyKeymasterDevice::Send(uint32_t command, const Serializab
775 ALOGV("Received %d byte response\n", rsp_size); 779 ALOGV("Received %d byte response\n", rsp_size);
776 } 780 }
777 781
778 const keymaster_message* msg = (keymaster_message*)recv_buf; 782 const uint8_t* p = recv_buf;
779 const uint8_t* p = msg->payload;
780 if (!rsp->Deserialize(&p, p + rsp_size)) { 783 if (!rsp->Deserialize(&p, p + rsp_size)) {
781 ALOGE("Error deserializing response of size %d\n", (int)rsp_size); 784 ALOGE("Error deserializing response of size %d\n", (int)rsp_size);
782 return KM_ERROR_UNKNOWN_ERROR; 785 return KM_ERROR_UNKNOWN_ERROR;
diff --git a/trusty/keymaster/trusty_keymaster_ipc.cpp b/trusty/keymaster/trusty_keymaster_ipc.cpp
index cdc27782a..54b251e93 100644
--- a/trusty/keymaster/trusty_keymaster_ipc.cpp
+++ b/trusty/keymaster/trusty_keymaster_ipc.cpp
@@ -23,6 +23,8 @@
23#include <string.h> 23#include <string.h>
24#include <unistd.h> 24#include <unistd.h>
25 25
26#include <algorithm>
27
26#include <log/log.h> 28#include <log/log.h>
27#include <trusty/tipc.h> 29#include <trusty/tipc.h>
28 30
@@ -31,7 +33,7 @@
31 33
32#define TRUSTY_DEVICE_NAME "/dev/trusty-ipc-dev0" 34#define TRUSTY_DEVICE_NAME "/dev/trusty-ipc-dev0"
33 35
34static int handle_ = 0; 36static int handle_ = -1;
35 37
36int trusty_keymaster_connect() { 38int trusty_keymaster_connect() {
37 int rc = tipc_connect(TRUSTY_DEVICE_NAME, KEYMASTER_PORT); 39 int rc = tipc_connect(TRUSTY_DEVICE_NAME, KEYMASTER_PORT);
@@ -45,7 +47,7 @@ int trusty_keymaster_connect() {
45 47
46int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out, 48int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out,
47 uint32_t* out_size) { 49 uint32_t* out_size) {
48 if (handle_ == 0) { 50 if (handle_ < 0) {
49 ALOGE("not connected\n"); 51 ALOGE("not connected\n");
50 return -EINVAL; 52 return -EINVAL;
51 } 53 }
@@ -62,32 +64,43 @@ int trusty_keymaster_call(uint32_t cmd, void* in, uint32_t in_size, uint8_t* out
62 ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno)); 64 ALOGE("failed to send cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, strerror(errno));
63 return -errno; 65 return -errno;
64 } 66 }
65 67 size_t out_max_size = *out_size;
66 rc = read(handle_, out, *out_size); 68 *out_size = 0;
67 if (rc < 0) { 69 struct iovec iov[2];
68 ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT, 70 struct keymaster_message header;
69 strerror(errno)); 71 iov[0] = {.iov_base = &header, .iov_len = sizeof(struct keymaster_message)};
70 return -errno; 72 while (true) {
71 } 73 iov[1] = {
72 74 .iov_base = out + *out_size,
73 if ((size_t)rc < sizeof(struct keymaster_message)) { 75 .iov_len = std::min<uint32_t>(KEYMASTER_MAX_BUFFER_LENGTH, out_max_size - *out_size)};
74 ALOGE("invalid response size (%d)\n", (int)rc); 76 rc = readv(handle_, iov, 2);
75 return -EINVAL; 77 if (rc < 0) {
76 } 78 ALOGE("failed to retrieve response for cmd (%d) to %s: %s\n", cmd, KEYMASTER_PORT,
77 79 strerror(errno));
78 msg = (struct keymaster_message*)out; 80 return -errno;
79 81 }
80 if ((cmd | KEYMASTER_RESP_BIT) != msg->cmd) { 82
81 ALOGE("invalid command (%d)", msg->cmd); 83 if ((size_t)rc < sizeof(struct keymaster_message)) {
82 return -EINVAL; 84 ALOGE("invalid response size (%d)\n", (int)rc);
85 return -EINVAL;
86 }
87
88 if ((cmd | KEYMASTER_RESP_BIT) != (header.cmd & ~(KEYMASTER_STOP_BIT))) {
89 ALOGE("invalid command (%d)", header.cmd);
90 return -EINVAL;
91 }
92 *out_size += ((size_t)rc - sizeof(struct keymaster_message));
93 if (header.cmd & KEYMASTER_STOP_BIT) {
94 break;
95 }
83 } 96 }
84 97
85 *out_size = ((size_t)rc) - sizeof(struct keymaster_message);
86 return rc; 98 return rc;
87} 99}
88 100
89void trusty_keymaster_disconnect() { 101void trusty_keymaster_disconnect() {
90 if (handle_ != 0) { 102 if (handle_ >= 0) {
91 tipc_close(handle_); 103 tipc_close(handle_);
92 } 104 }
105 handle_ = -1;
93} 106}