1 /*
2  * Copyright (C) 2021 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 #define TLOG_TAG "lib_hwaes_server"
18 
19 #include <assert.h>
20 #include <lib/hwaes_server/hwaes_server.h>
21 #include <lib/tipc/tipc_srv.h>
22 #include <stdlib.h>
23 #include <sys/auxv.h>
24 #include <sys/mman.h>
25 #include <trusty/sys/mman.h>
26 
27 #include <trusty_log.h>
28 #include <uapi/err.h>
29 
30 #include <inttypes.h>
31 
32 #define AUX_PAGE_SIZE() getauxval(AT_PAGESZ)
33 
34 struct shm {
35     void* base;
36     size_t size;
37     int mmap_prot;
38 };
39 
40 /**
41  * tipc_err_to_hwaes_err() - translates tipc/lk err to hwaes err value
42  * @tipc_err: tipc err value
43  *
44  * Returns: enum hwaes_err value
45  */
tipc_err_to_hwaes_err(int tipc_err)46 static enum hwaes_err tipc_err_to_hwaes_err(int tipc_err) {
47     switch (tipc_err) {
48     case NO_ERROR:
49         return HWAES_NO_ERROR;
50     case ERR_INVALID_ARGS:
51         return HWAES_ERR_INVALID_ARGS;
52     case ERR_IO:
53         return HWAES_ERR_IO;
54     case ERR_BAD_HANDLE:
55         return HWAES_ERR_BAD_HANDLE;
56     case ERR_NOT_IMPLEMENTED:
57         return HWAES_ERR_NOT_IMPLEMENTED;
58     default:
59         return HWAES_ERR_GENERIC;
60     }
61 }
62 
63 /**
64  * int hwaes_send_resp() - send response to the client
65  * @chan:   the channel handle.
66  * @buf:    the pointer to the buffer to store the response.
67  * @buf_sz: the size of the buffer pointed by @buf parameter.
68  *
69  * Returns: NO_ERROR on success, negative error code on failure
70  */
hwaes_send_resp(handle_t chan,void * buf,size_t buf_sz)71 static int hwaes_send_resp(handle_t chan, void* buf, size_t buf_sz) {
72     struct hwaes_resp* resp_header = (struct hwaes_resp*)buf;
73     resp_header->cmd |= HWAES_RESP_BIT;
74 
75     int rc = tipc_send1(chan, buf, buf_sz);
76     if ((size_t)rc != buf_sz) {
77         TLOGE("failed (%d) to send message. Expected to send %zu bytes.\n", rc,
78               buf_sz);
79         if (rc >= 0) {
80             rc = ERR_BAD_LEN;
81         }
82         return rc;
83     }
84     return NO_ERROR;
85 }
86 
87 /**
88  * int hwaes_map_shm() - map the shared memories.
89  * @num:       the number of shared memories.
90  * @handles:   the array of shared memory handles.
91  * @shm_descs: the array of shared memory descriptors.
92  * @shms:      the array of shared memories.
93  *
94  * Returns: NO_ERROR on success, negative error code on failure
95  */
hwaes_map_shm(size_t num,handle_t * handles,struct hwaes_shm_desc * shm_descs,struct shm * shms)96 static int hwaes_map_shm(size_t num,
97                          handle_t* handles,
98                          struct hwaes_shm_desc* shm_descs,
99                          struct shm* shms) {
100     for (size_t i = 0; i < num; i++) {
101         if (shm_descs[i].reserved) {
102             TLOGE("bad shared memory descriptor, reserved not 0, (%d)\n",
103                   shm_descs[i].reserved);
104             return ERR_IO;
105         }
106 
107         if (~1U & shm_descs[i].write) {
108             TLOGE("the write flag (%u) of shared memory is invalid.\n",
109                   shm_descs[i].write);
110             return ERR_IO;
111         }
112         int mmap_prot = PROT_READ;
113         if (shm_descs[i].write) {
114             mmap_prot |= PROT_WRITE;
115         }
116 
117         uint64_t size64 = shm_descs[i].size;
118         if (size64 > SIZE_MAX) {
119             TLOGE("share memory size is larger than SIZE_MAX\n");
120             return ERR_INVALID_ARGS;
121         }
122 
123         size_t size = size64;
124         if (size == 0 || size % AUX_PAGE_SIZE()) {
125             TLOGE("size (%zu) of shared memory is invalid.\n", size);
126             return ERR_INVALID_ARGS;
127         }
128 
129         shms[i].base = mmap(0, shm_descs[i].size, mmap_prot, 0, handles[i], 0);
130         if (shms[i].base == MAP_FAILED) {
131             TLOGE("failed to mmap() shared memory for handle (%zu).\n", i);
132             return ERR_BAD_HANDLE;
133         }
134         shms[i].size = shm_descs[i].size;
135         shms[i].mmap_prot = mmap_prot;
136     }
137     return NO_ERROR;
138 }
139 
140 /**
141  * void hwaes_unmap_shm() - unmap the shared memories.
142  * @num:  the number of shared memories.
143  * @shms: the array of shared memories.
144  *
145  */
hwaes_unmap_shm(size_t num,struct shm * shms)146 static void hwaes_unmap_shm(size_t num, struct shm* shms) {
147     for (size_t i = 0; i < num; i++) {
148         if (shms[i].size) {
149             int rc = munmap(shms[i].base, shms[i].size);
150             if (rc != NO_ERROR) {
151                 TLOGW("munmap() failed: %d\n", rc);
152             }
153         }
154     }
155 }
156 
157 /**
158  * int hwaes_set_arg_out() - set the output argument
159  * @data_desc_ptr: pointer to a data_desc.
160  * @mmap_prot:     shared memory mmap flag required for the argument.
161  * @shms:          the array of shared memories.
162  * @num_shms:      the number of shared memories.
163  * @buf_start:     the start of the buffer.
164  * @max_buf_sz:    the maximum size of the buffer.
165  * @offset_ptr:    pointer to the offset to the start of the buffer.
166  * @arg_ptr:       pointer to the output argument.
167  *
168  * Returns: NO_ERROR on success, negative error code on failure
169  */
hwaes_set_arg_out(struct hwaes_data_desc * data_desc_ptr,int mmap_prot,struct shm * shms,size_t num_shms,uint8_t * buf_start,size_t max_buf_sz,size_t * offset_ptr,struct hwaes_arg_out * arg_ptr)170 static int hwaes_set_arg_out(struct hwaes_data_desc* data_desc_ptr,
171                              int mmap_prot,
172                              struct shm* shms,
173                              size_t num_shms,
174                              uint8_t* buf_start,
175                              size_t max_buf_sz,
176                              size_t* offset_ptr,
177                              struct hwaes_arg_out* arg_ptr) {
178     if (data_desc_ptr->reserved) {
179         TLOGE("bad data descriptor, reserved not 0, (%d)\n",
180               data_desc_ptr->reserved);
181         return ERR_IO;
182     }
183 
184     size_t offset = *offset_ptr;
185     if (data_desc_ptr->len) {
186         if (data_desc_ptr->len > SIZE_MAX) {
187             TLOGE("data length is larger than SIZE_MAX\n");
188             return ERR_INVALID_ARGS;
189         }
190         arg_ptr->len = data_desc_ptr->len;
191         if (HWAES_INVALID_INDEX != data_desc_ptr->shm_idx) {
192             if (data_desc_ptr->shm_idx >= num_shms) {
193                 TLOGE("invalid shared memory index\n");
194                 return ERR_IO;
195             }
196             int shm_mmap_prot = shms[data_desc_ptr->shm_idx].mmap_prot;
197             if (~shm_mmap_prot & mmap_prot) {
198                 TLOGE("invalid shared memory protect flag\n");
199                 return ERR_IO;
200             }
201             size_t end_offset;
202             if (__builtin_add_overflow(data_desc_ptr->offset,
203                                        data_desc_ptr->len, &end_offset)) {
204                 TLOGE("the calculation of end_offset overflows \n");
205                 return ERR_INVALID_ARGS;
206             }
207             if (shms[data_desc_ptr->shm_idx].size < end_offset) {
208                 TLOGE("data exceeds shared memory boundaries\n");
209                 return ERR_INVALID_ARGS;
210             }
211             arg_ptr->data_ptr =
212                     shms[data_desc_ptr->shm_idx].base + data_desc_ptr->offset;
213         } else {
214             if (offset != data_desc_ptr->offset) {
215                 /* Some buffers may have buffer alignment requirements.
216                  * For inlined buffers, the offsets should be adjusted
217                  * on the client side to achieve the required alignment.
218                  * If this has been done, the offset needs updating here
219                  * also, read it from the descriptor (it should be
220                  * not less than end of the previous entry, though).
221                  */
222                 if (data_desc_ptr->offset < offset) {
223                     TLOGE("invalid descriptor offset (%" PRIu64 " < %zu)\n",
224                           data_desc_ptr->offset, offset);
225                     return ERR_INVALID_ARGS;
226                 }
227                 offset = data_desc_ptr->offset;
228             }
229 
230             if (__builtin_add_overflow(offset, data_desc_ptr->len, &offset)) {
231                 TLOGE("the calculation of offset overflows\n");
232                 return ERR_INVALID_ARGS;
233             }
234             if (offset > max_buf_sz) {
235                 TLOGE("offset (%zu) exceeds the maximum message size\n",
236                       offset);
237                 return ERR_INVALID_ARGS;
238             }
239             arg_ptr->data_ptr = buf_start + data_desc_ptr->offset;
240             *offset_ptr = offset;
241         }
242     }
243     return NO_ERROR;
244 }
245 
hwaes_set_arg_in(struct hwaes_data_desc * data_desc_ptr,int mmap_prot,struct shm * shms,size_t num_shms,uint8_t * buf_start,size_t max_buf_sz,size_t * offset_ptr,struct hwaes_arg_in * arg)246 static int hwaes_set_arg_in(struct hwaes_data_desc* data_desc_ptr,
247                             int mmap_prot,
248                             struct shm* shms,
249                             size_t num_shms,
250                             uint8_t* buf_start,
251                             size_t max_buf_sz,
252                             size_t* offset_ptr,
253                             struct hwaes_arg_in* arg) {
254     int rc;
255     struct hwaes_arg_out out_arg = {0};
256     rc = hwaes_set_arg_out(data_desc_ptr, mmap_prot, shms, num_shms, buf_start,
257                            max_buf_sz, offset_ptr, &out_arg);
258     if (rc != NO_ERROR) {
259         return rc;
260     }
261     arg->data_ptr = out_arg.data_ptr;
262     arg->len = out_arg.len;
263     return NO_ERROR;
264 }
265 
266 /**
267  * int hwaes_handle_aes_cmd() - handle request with HWAES_AES command
268  * @chan:         the channel handle.
269  * @req_msg_buf:  the request message buffer.
270  * @req_msg_size: the size of request message.
271  * @resp_msg_buf: the response message buffer.
272  * @shm_handles:  the array of shared memory handles.
273  * @num_handles:  the number of shared memory handles.
274  *
275  * Returns: NO_ERROR on success, negative error code on failure
276  */
hwaes_handle_aes_cmd(handle_t chan,uint8_t * req_msg_buf,size_t req_msg_size,uint8_t * resp_msg_buf,handle_t * shm_handles,size_t num_handles)277 static int hwaes_handle_aes_cmd(handle_t chan,
278                                 uint8_t* req_msg_buf,
279                                 size_t req_msg_size,
280                                 uint8_t* resp_msg_buf,
281                                 handle_t* shm_handles,
282                                 size_t num_handles) {
283     int rc;
284     struct shm shms[HWAES_MAX_NUM_HANDLES] = {0};
285 
286     struct hwaes_req* req_header = (struct hwaes_req*)req_msg_buf;
287 
288     struct hwaes_resp* resp_header = (struct hwaes_resp*)resp_msg_buf;
289     size_t resp_msg_size = sizeof(*resp_header);
290 
291     struct hwaes_aes_req* cmd_header =
292             (struct hwaes_aes_req*)(req_msg_buf + sizeof(*req_header));
293 
294     if (cmd_header->reserved) {
295         TLOGE("bad cmd header, reserved not 0, (%d)\n", cmd_header->reserved);
296         return ERR_NOT_VALID;
297     }
298 
299     size_t header_num_handles = cmd_header->num_handles;
300 
301     if (header_num_handles != num_handles) {
302         TLOGE("header specified num_handles(%zu) is not equal to the num_handles(%zu)\n",
303               header_num_handles, num_handles);
304         return ERR_NOT_VALID;
305     }
306 
307     size_t req_header_size = sizeof(*req_header) + sizeof(*cmd_header) +
308                              num_handles * sizeof(struct hwaes_shm_desc);
309 
310     if (req_header_size > HWAES_MAX_MSG_SIZE) {
311         TLOGE("request header size (%zu) exceeds the maximum message size\n",
312               req_header_size);
313         return ERR_NOT_VALID;
314     }
315 
316     struct hwaes_shm_desc* shm_descs =
317             (struct hwaes_shm_desc*)(req_msg_buf + sizeof(*req_header) +
318                                      sizeof(*cmd_header));
319 
320     rc = hwaes_map_shm(num_handles, shm_handles, shm_descs, shms);
321     if (rc != NO_ERROR) {
322         TLOGE("failed to hwaes_map_shm()\n");
323         resp_header->result = tipc_err_to_hwaes_err(rc);
324         goto out;
325     }
326 
327     struct hwaes_aes_op_args args = {
328             .key_type = cmd_header->key_type,
329             .padding = cmd_header->padding,
330             .mode = cmd_header->mode,
331             .encrypt = !!cmd_header->encrypt,
332     };
333 
334     size_t req_offset = req_header_size;
335     size_t resp_offset = resp_msg_size;
336 
337     rc = hwaes_set_arg_in(&cmd_header->key, PROT_READ, shms, num_handles,
338                           req_msg_buf, req_msg_size, &req_offset, &args.key);
339     if (rc != NO_ERROR) {
340         TLOGE("failed to set key\n");
341         resp_header->result = tipc_err_to_hwaes_err(rc);
342         goto out;
343     }
344 
345     rc = hwaes_set_arg_in(&cmd_header->iv, PROT_READ, shms, num_handles,
346                           req_msg_buf, req_msg_size, &req_offset, &args.iv);
347     if (rc != NO_ERROR) {
348         TLOGE("failed to set iv\n");
349         resp_header->result = tipc_err_to_hwaes_err(rc);
350         goto out;
351     }
352 
353     rc = hwaes_set_arg_in(&cmd_header->aad, PROT_READ, shms, num_handles,
354                           req_msg_buf, req_msg_size, &req_offset, &args.aad);
355     if (rc != NO_ERROR) {
356         TLOGE("failed to set aad\n");
357         resp_header->result = tipc_err_to_hwaes_err(rc);
358         goto out;
359     }
360 
361     rc = hwaes_set_arg_in(&cmd_header->text_in, PROT_READ, shms, num_handles,
362                           req_msg_buf, req_msg_size, &req_offset,
363                           &args.text_in);
364     if (rc != NO_ERROR) {
365         TLOGE("failed to set text_in\n");
366         resp_header->result = tipc_err_to_hwaes_err(rc);
367         goto out;
368     }
369 
370     rc = hwaes_set_arg_in(&cmd_header->tag_in, PROT_READ, shms, num_handles,
371                           req_msg_buf, req_msg_size, &req_offset, &args.tag_in);
372     if (rc != NO_ERROR) {
373         TLOGE("failed to set tag_in\n");
374         resp_header->result = tipc_err_to_hwaes_err(rc);
375         goto out;
376     }
377 
378     rc = hwaes_set_arg_out(&cmd_header->text_out, PROT_READ | PROT_WRITE, shms,
379                            num_handles, resp_msg_buf, HWAES_MAX_MSG_SIZE,
380                            &resp_offset, &args.text_out);
381     if (rc != NO_ERROR) {
382         TLOGE("failed to set text_out\n");
383         resp_header->result = tipc_err_to_hwaes_err(rc);
384         goto out;
385     }
386 
387     rc = hwaes_set_arg_out(&cmd_header->tag_out, PROT_READ | PROT_WRITE, shms,
388                            num_handles, resp_msg_buf, HWAES_MAX_MSG_SIZE,
389                            &resp_offset, &args.tag_out);
390     if (rc != NO_ERROR) {
391         TLOGE("failed to set tag_out\n");
392         resp_header->result = tipc_err_to_hwaes_err(rc);
393         goto out;
394     }
395 
396     resp_header->result = hwaes_aes_op(&args);
397     if (resp_header->result == HWAES_NO_ERROR) {
398         resp_msg_size = resp_offset;
399     }
400 
401 out:
402     rc = hwaes_send_resp(chan, resp_msg_buf, resp_msg_size);
403     hwaes_unmap_shm(cmd_header->num_handles, shms);
404     return rc;
405 }
406 
407 /**
408  * int hwaes_read_req() - read the request from the client
409  * @chan:             the channel handle.
410  * @buf:              the pointer to the buffer to store the request.
411  * @shm_handles:      the array of shared memory handles.
412  * @num_handles_ptr:  pointer to the number of shared memory handles.
413  * @req_msg_size_ptr: pointer to the size of request message.
414  *
415  * Returns: NO_ERROR on success, negative error code on failure
416  */
hwaes_read_req(handle_t chan,void * buf,handle_t * shm_handles,size_t * num_handles_ptr,size_t * req_msg_size_ptr)417 static int hwaes_read_req(handle_t chan,
418                           void* buf,
419                           handle_t* shm_handles,
420                           size_t* num_handles_ptr,
421                           size_t* req_msg_size_ptr) {
422     int rc;
423     struct ipc_msg_info msg_inf;
424 
425     rc = get_msg(chan, &msg_inf);
426     if (rc != NO_ERROR) {
427         TLOGE("failed (%d) to get_msg()\n", rc);
428         return rc;
429     }
430 
431     if (msg_inf.len < sizeof(struct hwaes_req) ||
432         msg_inf.len > HWAES_MAX_MSG_SIZE) {
433         TLOGE("unexpected msg size: buffer too small or too big\n");
434         rc = ERR_BAD_LEN;
435         goto free_msg;
436     }
437 
438     if (msg_inf.num_handles > HWAES_MAX_NUM_HANDLES) {
439         TLOGE("too many shared memory handles\n");
440         rc = ERR_BAD_LEN;
441         goto free_msg;
442     }
443 
444     struct iovec iov = {
445             .iov_base = buf,
446             .iov_len = HWAES_MAX_MSG_SIZE,
447     };
448     struct ipc_msg ipc_msg = {
449             .iov = &iov,
450             .num_iov = 1,
451             .handles = shm_handles,
452             .num_handles = msg_inf.num_handles,
453     };
454 
455     rc = read_msg(chan, msg_inf.id, 0, &ipc_msg);
456     if (rc < 0) {
457         TLOGE("failed (%d) to read_msg()\n", rc);
458         goto free_msg;
459     }
460     assert(rc == (int)msg_inf.len);
461 
462     *req_msg_size_ptr = rc;
463     *num_handles_ptr = msg_inf.num_handles;
464     rc = NO_ERROR;
465 
466 free_msg:
467     put_msg(chan, msg_inf.id);
468     return rc;
469 }
470 
hwaes_on_message(const struct tipc_port * port,handle_t chan,void * ctx)471 static int hwaes_on_message(const struct tipc_port* port,
472                             handle_t chan,
473                             void* ctx) {
474     int rc;
475 
476     handle_t shm_handles[HWAES_MAX_NUM_HANDLES];
477     size_t num_handles = 0;
478     size_t req_msg_size;
479 
480     uint8_t* req_msg_buf = memalign(AUX_PAGE_SIZE(), HWAES_MAX_MSG_SIZE);
481     uint8_t* resp_msg_buf = memalign(AUX_PAGE_SIZE(), HWAES_MAX_MSG_SIZE);
482 
483     if (req_msg_buf == 0 || resp_msg_buf == 0) {
484         TLOGE("failed to allocate memory for req/resp msg.\n");
485         rc = ERR_NO_MEMORY;
486         goto free_handles;
487     }
488 
489     rc = hwaes_read_req(chan, req_msg_buf, shm_handles, &num_handles,
490                         &req_msg_size);
491     if (rc != NO_ERROR) {
492         TLOGE("failed (%d) to hwaes_read_req()\n", rc);
493         num_handles = 0;
494         goto free_handles;
495     };
496 
497     struct hwaes_req* req_header = (struct hwaes_req*)req_msg_buf;
498     if (req_header->reserved) {
499         TLOGE("bad general header, reserved not 0, (%d)\n",
500               req_header->reserved);
501         rc = ERR_NOT_VALID;
502         goto free_handles;
503     }
504 
505     struct hwaes_resp* resp_header = (struct hwaes_resp*)resp_msg_buf;
506 
507     resp_header->cmd = req_header->cmd;
508 
509     /* handle it */
510     switch (req_header->cmd) {
511     case HWAES_AES:
512         rc = hwaes_handle_aes_cmd(chan, req_msg_buf, req_msg_size, resp_msg_buf,
513                                   shm_handles, num_handles);
514         break;
515 
516     default:
517         TLOGE("unsupported request: %d\n", (int)req_header->cmd);
518         resp_header->result = HWAES_ERR_NOT_IMPLEMENTED;
519         rc = hwaes_send_resp(chan, resp_header, sizeof(*resp_header));
520     }
521 
522 free_handles:
523     for (size_t i = 0; i < num_handles; i++) {
524         close(shm_handles[i]);
525     }
526 
527     free(req_msg_buf);
528     free(resp_msg_buf);
529 
530     return rc;
531 }
532 
add_hwaes_service(struct tipc_hset * hset,const uuid_t ** allowed_clients,size_t allowed_clients_len)533 int add_hwaes_service(struct tipc_hset* hset,
534                       const uuid_t** allowed_clients,
535                       size_t allowed_clients_len) {
536     static struct tipc_port_acl acl = {
537             .flags = IPC_PORT_ALLOW_TA_CONNECT,
538     };
539     acl.uuid_num = allowed_clients_len;
540     acl.uuids = allowed_clients;
541 
542     static struct tipc_port port = {
543             .name = HWAES_PORT,
544             .msg_max_size = HWAES_MAX_MSG_SIZE,
545             .msg_queue_len = 1,
546             .acl = &acl,
547     };
548     static struct tipc_srv_ops ops = {
549             .on_message = hwaes_on_message,
550     };
551     return tipc_add_service(hset, &port, 1, 2, &ops);
552 }
553