1 /*
2 * Copyright (C) 2020 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 <lib/hwwsk/client.h>
18
19 #include <assert.h>
20 #include <lib/tipc/tipc.h>
21 #include <lk/macros.h>
22 #include <stdbool.h>
23 #include <stdint.h>
24 #include <string.h>
25 #include <sys/mman.h>
26 #include <uapi/err.h>
27
28 #define TLOG_LVL TLOG_LVL_INFO
29 #define TLOG_TAG "hwwsk-client"
30 #include <trusty_log.h>
31
32 /*
33 * Helper to convert error codes
34 */
hwwsk_err_to_lk_err(uint32_t err)35 static int hwwsk_err_to_lk_err(uint32_t err) {
36 switch (err) {
37 case HWWSK_NO_ERROR:
38 return NO_ERROR;
39
40 case HWWSK_ERR_GENERIC:
41 return ERR_GENERIC;
42
43 case HWWSK_ERR_INVALID_ARGS:
44 return ERR_INVALID_ARGS;
45
46 case HWWSK_ERR_BAD_LEN:
47 return ERR_BAD_LEN;
48
49 case HWWSK_ERR_NOT_SUPPORTED:
50 return ERR_NOT_SUPPORTED;
51
52 default:
53 return ERR_GENERIC;
54 }
55 }
56
handle_reply(handle_t chan,void * buf,size_t buf_size)57 static int handle_reply(handle_t chan, void* buf, size_t buf_size) {
58 int rc;
59 struct uevent evt;
60 struct hwwsk_rsp_hdr rsp;
61
62 /* wait for reply */
63 wait(chan, &evt, INFINITE_TIME);
64
65 /* read reply */
66 rc = tipc_recv2(chan, sizeof(rsp), &rsp, sizeof(rsp), buf, buf_size);
67 if (rc < 0) {
68 TLOGD("Failed (%d) to read reply\n", rc);
69 return rc;
70 }
71
72 /* check server reply */
73 if (rsp.status != 0) {
74 rc = hwwsk_err_to_lk_err(rsp.status);
75 TLOGD("Server returned error (%d)\n", rc);
76 return rc;
77 }
78
79 if (((size_t)rc - sizeof(rsp)) > buf_size) {
80 TLOGD("buffer too small (%d)\n", rc);
81 return ERR_INVALID_ARGS;
82 }
83
84 return (size_t)rc - sizeof(rsp);
85 }
86
hwwsk_generate_key(handle_t hchan,void * buf,size_t buf_sz,uint32_t key_size,uint32_t key_flags,const void * raw_key,size_t raw_key_len)87 int hwwsk_generate_key(handle_t hchan,
88 void* buf,
89 size_t buf_sz,
90 uint32_t key_size,
91 uint32_t key_flags,
92 const void* raw_key,
93 size_t raw_key_len) {
94 int rc;
95 struct {
96 struct hwwsk_req_hdr hdr;
97 struct hwwsk_generate_key_req req;
98 } msg;
99
100 /* fill request */
101 memset(&msg, 0, sizeof(msg));
102 msg.hdr.cmd = HWWSK_CMD_GENERATE_KEY;
103 msg.hdr.flags = 0;
104
105 msg.req.key_size = key_size;
106 msg.req.key_flags = key_flags;
107
108 /* send request */
109 rc = tipc_send2(hchan, &msg, sizeof(msg), raw_key, raw_key_len);
110 if (rc < 0) {
111 TLOGE("Failed (%d) send request\n", rc);
112 return rc;
113 }
114
115 return handle_reply(hchan, buf, buf_sz);
116 }
117
hwwsk_export_key(handle_t hchan,void * buf,size_t buf_sz,const void * key_blob,size_t key_blob_len)118 int hwwsk_export_key(handle_t hchan,
119 void* buf,
120 size_t buf_sz,
121 const void* key_blob,
122 size_t key_blob_len) {
123 int rc;
124 struct {
125 struct hwwsk_req_hdr hdr;
126 } msg;
127
128 /* fill request header */
129 msg.hdr.cmd = HWWSK_CMD_EXPORT_KEY;
130 msg.hdr.flags = 0;
131
132 /* send request */
133 rc = tipc_send2(hchan, &msg, sizeof(msg), key_blob, key_blob_len);
134 if (rc < 0) {
135 TLOGE("Failed (%d) send request\n", rc);
136 return rc;
137 }
138
139 return handle_reply(hchan, buf, buf_sz);
140 }
141