1 /*
2  * Copyright (C) 2015 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 <stdio.h>
18 #include <stdlib.h>
19 #include <string.h>
20 #include <trusty_ipc.h>
21 #include <uapi/err.h>
22 
23 #include <dice/cbor_reader.h>
24 #include <interface/keymaster/keymaster.h>
25 #include <lib/keymaster/keymaster.h>
26 
27 #include <openssl/hmac.h>
28 
29 #define LOG_TAG "libkeymaster"
30 #define TLOGE(fmt, ...) \
31     fprintf(stderr, "%s: %d: " fmt, LOG_TAG, __LINE__, ##__VA_ARGS__)
32 
33 #define HMAC_LEN (sizeof(((hw_auth_token_t*)0)->hmac))
34 
35 #define AUTH_TOKEN_KEY_LEN (32)
36 
send_req(keymaster_session_t session,uint32_t cmd)37 static long send_req(keymaster_session_t session, uint32_t cmd) {
38     struct keymaster_message msg = {
39             .cmd = cmd,
40     };
41 
42     struct iovec tx_iov = {
43             .iov_base = &msg,
44             .iov_len = sizeof(msg),
45     };
46     ipc_msg_t tx_msg = {
47             .iov = &tx_iov,
48             .num_iov = 1,
49     };
50 
51     long rc = send_msg(session, &tx_msg);
52     if (rc < 0) {
53         TLOGE("%s: failed (%ld) to send_msg\n", __func__, rc);
54         return rc;
55     }
56 
57     if (((size_t)rc) != sizeof(msg)) {
58         TLOGE("%s: msg invalid size (%zu != %zu)", __func__, (size_t)rc,
59               sizeof(msg));
60         return ERR_IO;
61     }
62 
63     return NO_ERROR;
64 }
65 
await_response(keymaster_session_t session,struct ipc_msg_info * inf)66 static long await_response(keymaster_session_t session,
67                            struct ipc_msg_info* inf) {
68     uevent_t uevt;
69     long rc = wait(session, &uevt, INFINITE_TIME);
70     if (rc != NO_ERROR) {
71         TLOGE("%s: interrupted waiting for response (%ld)\n", __func__, rc);
72         return rc;
73     }
74 
75     rc = get_msg(session, inf);
76     if (rc != NO_ERROR) {
77         TLOGE("%s: failed to get_msg (%ld)\n", __func__, rc);
78     }
79 
80     return rc;
81 }
82 
read_response(keymaster_session_t session,uint32_t msg_id,uint32_t cmd,uint8_t * buf,uint32_t size)83 static long read_response(keymaster_session_t session,
84                           uint32_t msg_id,
85                           uint32_t cmd,
86                           uint8_t* buf,
87                           uint32_t size) {
88     struct keymaster_message msg;
89 
90     struct iovec rx_iov[2] = {
91             {.iov_base = &msg, .iov_len = sizeof(msg)},
92             {.iov_base = buf, .iov_len = size},
93     };
94     struct ipc_msg rx_msg = {
95             .iov = rx_iov,
96             .num_iov = 2,
97     };
98 
99     long rc = read_msg(session, msg_id, 0, &rx_msg);
100     put_msg(session, msg_id);
101 
102     if ((cmd | KM_RESP_BIT) != (msg.cmd & ~(KM_STOP_BIT))) {
103         TLOGE("%s: invalid response (0x%x) for cmd (0x%x)\n", __func__, msg.cmd,
104               cmd);
105         return ERR_NOT_VALID;
106     }
107 
108     return rc;
109 }
110 
keymaster_open(void)111 int keymaster_open(void) {
112     return connect(KEYMASTER_SECURE_PORT, IPC_CONNECT_WAIT_FOR_PORT);
113 }
114 
keymaster_close(keymaster_session_t session)115 void keymaster_close(keymaster_session_t session) {
116     close(session);
117 }
118 
keymaster_send_command(keymaster_session_t session,uint8_t command,uint8_t ** data_buf_p,uint32_t * size_p)119 int keymaster_send_command(keymaster_session_t session,
120                            uint8_t command,
121                            uint8_t** data_buf_p,
122                            uint32_t* size_p) {
123     if (size_p == NULL || data_buf_p == NULL) {
124         return ERR_NOT_VALID;
125     }
126 
127     long rc = send_req(session, command);
128     if (rc < 0) {
129         TLOGE("%s: failed (%ld) to send req\n", __func__, rc);
130         return rc;
131     }
132 
133     struct ipc_msg_info inf;
134     rc = await_response(session, &inf);
135     if (rc < 0) {
136         TLOGE("%s: failed (%ld) to await response\n", __func__, rc);
137         return rc;
138     }
139 
140     if (inf.len <= sizeof(struct keymaster_message)) {
141         TLOGE("%s: invalid response len (%zu)\n", __func__, inf.len);
142         put_msg(session, inf.id);
143         return ERR_NOT_FOUND;
144     }
145 
146     size_t size = inf.len - sizeof(struct keymaster_message);
147     uint8_t* data_buf = malloc(size);
148     if (data_buf == NULL) {
149         TLOGE("%s: out of memory (%zu)\n", __func__, inf.len);
150         put_msg(session, inf.id);
151         return ERR_NO_MEMORY;
152     }
153 
154     rc = read_response(session, inf.id, command, data_buf, size);
155     if (rc < 0) {
156         goto err_bad_read;
157     }
158 
159     size_t read_len = (size_t)rc;
160     if (read_len != inf.len) {
161         // data read in does not match message length
162         TLOGE("%s: invalid read length: (%zu != %zu)\n", __func__, read_len,
163               inf.len);
164         rc = ERR_IO;
165         goto err_bad_read;
166     }
167 
168     *size_p = (uint32_t)size;
169     *data_buf_p = data_buf;
170     return NO_ERROR;
171 
172 err_bad_read:
173     free(data_buf);
174     TLOGE("%s: failed read_msg (%ld)\n", __func__, rc);
175     return rc;
176 }
177 
keymaster_get_auth_token_key(keymaster_session_t session,uint8_t ** key_buf_p,uint32_t * size_p)178 int keymaster_get_auth_token_key(keymaster_session_t session,
179                                  uint8_t** key_buf_p,
180                                  uint32_t* size_p) {
181     long rc = keymaster_send_command(session, KM_GET_AUTH_TOKEN_KEY, key_buf_p,
182                                      size_p);
183     /*
184      * TODO: Return message of this API contains an error if one happened and a
185      * key on success. It may be impossible to distinguish the two if they are
186      * the same size. A proper fix would require changing the layout of the
187      * return message. However, that changes the ABI. So, just assume that the
188      * key is 32 bytes. We know that from KM code.
189      */
190     if (rc == NO_ERROR && *size_p != AUTH_TOKEN_KEY_LEN) {
191         TLOGE("%s: auth token key wrong length: %u, expected %d\n", __func__,
192               *size_p, AUTH_TOKEN_KEY_LEN);
193         rc = ERR_BAD_LEN;
194         free(*key_buf_p);
195         *key_buf_p = NULL;
196     }
197     return rc;
198 }
199 
keymaster_get_device_info(keymaster_session_t session,uint8_t ** info_buffer_p,uint32_t * size_p)200 int keymaster_get_device_info(keymaster_session_t session,
201                               uint8_t** info_buffer_p,
202                               uint32_t* size_p) {
203     long rc = keymaster_send_command(session, KM_GET_DEVICE_INFO, info_buffer_p,
204                                      size_p);
205     /*
206      * TODO: Return message of this API contains an error if one happened and a
207      * key on success. It may be impossible to distinguish the two if they are
208      * the same size. A proper fix would require changing the layout of the
209      * return message. However, that changes the ABI. So, attempt to parse the
210      * message as a valid CBOR map with non-zero entries. If this fails, it's
211      * an error.
212      */
213     if (rc == NO_ERROR) {
214         struct CborIn in;
215         CborInInit(*info_buffer_p, *size_p, &in);
216         size_t pair_count;
217         if (*size_p == 0 ||
218             CborReadMap(&in, &pair_count) != CBOR_READ_RESULT_OK) {
219             TLOGE("%s: device info byte stream is not valid CBOR or a map.\n",
220                   __func__);
221             goto err_bad_cbor;
222         }
223         // Each entry would require at least two bytes.
224         if (*size_p < pair_count * 2) {
225             TLOGE("%s: Device info is malformed. Size is %u, expected > %zu\n",
226                   __func__, *size_p, pair_count * 2);
227             goto err_bad_cbor;
228         }
229     }
230     return rc;
231 
232 err_bad_cbor:
233     rc = ERR_FAULT;
234     free(*info_buffer_p);
235     *info_buffer_p = NULL;
236     return rc;
237 }
238 
keymaster_get_uds_certs(keymaster_session_t session,uint8_t ** cert_buffer_p,uint32_t * size_p)239 int keymaster_get_uds_certs(keymaster_session_t session,
240                             uint8_t** cert_buffer_p,
241                             uint32_t* size_p) {
242     uint8_t* data = NULL;
243     uint32_t data_len = 0;
244     long rc =
245             keymaster_send_command(session, KM_GET_UDS_CERTS, &data, &data_len);
246     if (rc != NO_ERROR) {
247         return rc;
248     }
249 
250     // The first four bytes (native endian) after the (consumed) command code
251     // indicate the error code for the command (0 for success).
252     if (data_len < sizeof(uint32_t)) {
253         TLOGE("%s: UDS certs return code wrong length: %zu, expected >= %zu\n",
254               __func__, (size_t)data_len, sizeof(uint32_t));
255         rc = ERR_BAD_LEN;
256         goto exit;
257     }
258     uint32_t errcode = *(uint32_t*)data;
259     if (errcode != 0) {
260         TLOGE("%s: UDS certs retrieval failed: %u\n", __func__, errcode);
261         rc = ERR_FAULT;
262         goto exit;
263     }
264 
265     // Remainder of message is the UDS certs, starting with a 32-bit (native
266     // endian) length.
267     uint32_t remaining_len = data_len - sizeof(uint32_t);
268     uint8_t* rest = data + sizeof(uint32_t);
269     if (remaining_len < sizeof(uint32_t)) {
270         TLOGE("%s: UDS cert data wrong length: %zu, expected >= %zu\n",
271               __func__, (size_t)remaining_len, sizeof(uint32_t));
272         rc = ERR_BAD_LEN;
273         goto exit;
274     }
275 
276     *size_p = *(uint32_t*)rest;
277     remaining_len -= sizeof(uint32_t);
278     rest += sizeof(uint32_t);
279     if (*size_p != remaining_len) {
280         TLOGE("%s: UDS cert data inconsistent length: claims %zu, %zu remaining\n",
281               __func__, (size_t)(*size_p), (size_t)remaining_len);
282         rc = ERR_BAD_LEN;
283         goto exit;
284     }
285 
286     // Allocate space for just the UDS certs.
287     *cert_buffer_p = malloc(*size_p);
288     if (*cert_buffer_p == NULL) {
289         TLOGE("%s: out of memory (%zu)\n", __func__, (size_t)(*size_p));
290         rc = ERR_NO_MEMORY;
291         goto exit;
292     }
293     memcpy(*cert_buffer_p, rest, *size_p);
294 
295 exit:
296     // Always free the (prefixed) response buffer.
297     free(data);
298     return rc;
299 }
300 
mint_hmac(uint8_t * key,size_t key_size,uint8_t * message,size_t message_size,uint8_t * hmac)301 static int mint_hmac(uint8_t* key,
302                      size_t key_size,
303                      uint8_t* message,
304                      size_t message_size,
305                      uint8_t* hmac) {
306     unsigned int tok_size;
307     unsigned char* ret;
308     memset(hmac, 0, HMAC_LEN);
309     ret = HMAC(EVP_sha256(), (void*)key, key_size, message, message_size, hmac,
310                &tok_size);
311     if (ret == NULL || tok_size != HMAC_LEN) {
312         TLOGE("Failed to execute HMAC()!\n");
313         return ERR_FAULT;
314     }
315 
316     return NO_ERROR;
317 }
318 
keymaster_sign_auth_token(keymaster_session_t session,hw_auth_token_t * token)319 int keymaster_sign_auth_token(keymaster_session_t session,
320                               hw_auth_token_t* token) {
321     int ret = NO_ERROR;
322 
323     if (token == NULL) {
324         TLOGE("Invalid token!\n");
325         return ERR_NOT_VALID;
326     }
327 
328     uint8_t* key_buf;
329     uint32_t key_buf_size;
330     ret = keymaster_get_auth_token_key(session, &key_buf, &key_buf_size);
331     if (ret) {
332         return ret;
333     }
334 
335     /* Initialize the token and message size */
336     size_t message_size = sizeof(hw_auth_token_t) - sizeof(token->hmac);
337     /* Mint the token key with the given HMAC key and message */
338     ret = mint_hmac(key_buf, key_buf_size, (uint8_t*)token, message_size,
339                     token->hmac);
340 
341 free_mem:
342     free(key_buf);
343     return ret;
344 }
345 
keymaster_validate_auth_token(keymaster_session_t session,hw_auth_token_t * token)346 int keymaster_validate_auth_token(keymaster_session_t session,
347                                   hw_auth_token_t* token) {
348     int ret = NO_ERROR;
349 
350     if (token == NULL) {
351         TLOGE("Invalid token!\n");
352         return ERR_NOT_VALID;
353     }
354 
355     uint8_t* key_buf;
356     uint32_t key_buf_size;
357     ret = keymaster_get_auth_token_key(session, &key_buf, &key_buf_size);
358     if (ret) {
359         return ret;
360     }
361 
362     /* compute the expected token hmac */
363     uint8_t expected_hmac[HMAC_LEN];
364     size_t message_size = sizeof(hw_auth_token_t) - sizeof(token->hmac);
365 
366     ret = mint_hmac(key_buf, key_buf_size, (uint8_t*)token, message_size,
367                     expected_hmac);
368     if (ret) {
369         goto free_mem;
370     }
371 
372     /* Compare the expected hmac with the provided hmac */
373     ret = memcmp(expected_hmac, token->hmac, sizeof(expected_hmac));
374 
375 free_mem:
376     free(key_buf);
377     return ret;
378 }
379