1 /*
2 * Copyright 2024 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include <endian.h>
18 #include <trusty/secretkeeper.h>
19 #include <trusty/trusty_ipc.h>
20 #include <trusty/util.h>
21
22 static struct trusty_ipc_chan secretkeeper_chan;
23 static bool initialized;
24
secretkeeper_tipc_init(struct trusty_ipc_dev * dev)25 int secretkeeper_tipc_init(struct trusty_ipc_dev* dev) {
26 trusty_assert(dev);
27 trusty_assert(!initialized);
28 trusty_ipc_chan_init(&secretkeeper_chan, dev);
29
30 trusty_debug(
31 "In secretkeeper_tipc_init: connecting to secretkeeper bootloader service.\n");
32 int rc = trusty_ipc_connect(&secretkeeper_chan, SECRETKEEPER_BL_PORT,
33 true /*wait*/);
34 if (rc < 0) {
35 trusty_error(
36 "In secretkeeper_tipc_init:: failed (%d) to connect to '%s'.\n",
37 rc, SECRETKEEPER_BL_PORT);
38 return rc;
39 }
40 initialized = true;
41 return TRUSTY_ERR_NONE;
42 }
43
secretkeeper_tipc_shutdown(void)44 void secretkeeper_tipc_shutdown(void) {
45 if (!initialized) {
46 return;
47 }
48 trusty_ipc_close(&secretkeeper_chan);
49 initialized = false;
50 }
51
send_header_only_request(struct secretkeeper_req_hdr * hdr,size_t hdr_size)52 static int send_header_only_request(struct secretkeeper_req_hdr* hdr,
53 size_t hdr_size) {
54 int num_iovec = 1;
55 struct trusty_ipc_iovec req_iov = {.base = hdr, .len = hdr_size};
56 return trusty_ipc_send(&secretkeeper_chan, &req_iov, num_iovec, true);
57 }
58
read_response_with_data(struct secretkeeper_req_hdr * hdr,uint8_t * buf,size_t buf_size,size_t * out_size)59 static int read_response_with_data(struct secretkeeper_req_hdr* hdr,
60 uint8_t* buf,
61 size_t buf_size,
62 size_t* out_size) {
63 struct secretkeeper_resp_hdr resp_hdr = {};
64
65 trusty_assert(buf);
66 trusty_assert(out_size);
67
68 int num_iovec = 2;
69 struct trusty_ipc_iovec resp_iovecs[2] = {
70 {.base = &resp_hdr, .len = sizeof(resp_hdr)},
71 {.base = buf, .len = buf_size},
72 };
73
74 int rc = trusty_ipc_recv(&secretkeeper_chan, resp_iovecs, num_iovec, true);
75 if (rc < 0) {
76 trusty_error("Secretkeeper: Failure on receiving response: %d\n", rc);
77 return rc;
78 }
79
80 size_t bytes = rc;
81 if (bytes < sizeof(resp_hdr)) {
82 trusty_error("Secretkeeper: Invalid response size (%d).\n", rc);
83 return TRUSTY_ERR_GENERIC;
84 }
85
86 if (resp_hdr.cmd != (hdr->cmd | htonl(SECRETKEEPER_RESPONSE_MARKER))) {
87 trusty_error("Secretkeeper: Unknown response cmd: %x\n",
88 ntohl(resp_hdr.cmd));
89 return TRUSTY_ERR_GENERIC;
90 }
91
92 if (resp_hdr.error_code != 0) {
93 trusty_error("Secretkeeper: Error code (%d) is not zero.\n",
94 ntohl(resp_hdr.error_code));
95 return TRUSTY_ERR_GENERIC;
96 }
97
98 *out_size = bytes - sizeof(resp_hdr);
99 return rc;
100 }
101
secretkeeper_get_identity(size_t identity_buf_size,uint8_t identity_buf[],size_t * identity_size)102 int secretkeeper_get_identity(size_t identity_buf_size,
103 uint8_t identity_buf[],
104 size_t* identity_size) {
105 trusty_assert(dice_artifacts);
106 trusty_assert(dice_artifacts_size);
107
108 struct secretkeeper_req_hdr hdr;
109 hdr.cmd = htonl(SECRETKEEPER_CMD_GET_IDENTITY);
110
111 int rc = send_header_only_request(&hdr, sizeof(hdr));
112
113 if (rc < 0) {
114 trusty_error(
115 "In secretkeeper_get_identity: failed (%d) to send request to Secretkeeper.",
116 rc);
117 return rc;
118 }
119
120 rc = read_response_with_data(&hdr, identity_buf, identity_buf_size,
121 identity_size);
122
123 if (rc < 0) {
124 trusty_error(
125 "In secretkeeper_get_identity: failed (%d) to read the response.",
126 rc);
127 return rc;
128 }
129
130 return TRUSTY_ERR_NONE;
131 }
132