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 #include <assert.h>
18 #include <lib/keybox/client/keybox.h>
19 #include <lib/tipc/tipc.h>
20 #include <lk/compiler.h>
21 #include <lk/macros.h>
22 #include <uapi/err.h>
23 
24 #define TLOG_TAG "keybox-client"
25 #include <trusty_log.h>
26 
27 struct full_keybox_unwrap_request {
28     struct keybox_req header;
29     struct keybox_unwrap_req unwrap_header;
30 };
31 
32 struct full_keybox_unwrap_response {
33     struct keybox_resp header;
34     struct keybox_unwrap_resp unwrap_header;
35 };
36 
keybox_unwrap(const uint8_t * wrapped_keybox,size_t wrapped_keybox_size,uint8_t * unwrapped_keybox,size_t unwrapped_keybox_buf_size,size_t * unwrapped_keybox_size)37 int keybox_unwrap(const uint8_t* wrapped_keybox,
38                   size_t wrapped_keybox_size,
39                   uint8_t* unwrapped_keybox,
40                   size_t unwrapped_keybox_buf_size,
41                   size_t* unwrapped_keybox_size) {
42     handle_t chan;
43     int rc = tipc_connect(&chan, KEYBOX_PORT);
44     if (rc < 0) {
45         TLOGE("Failed to connect to %s\n", KEYBOX_PORT);
46         return ERR_IO;
47     }
48 
49     struct full_keybox_unwrap_request req;
50     req.header.cmd = KEYBOX_CMD_UNWRAP;
51     req.header.reserved = 0;
52     req.unwrap_header.wrapped_keybox_len = wrapped_keybox_size;
53     rc = tipc_send2(chan, &req, sizeof(req), wrapped_keybox,
54                     wrapped_keybox_size);
55     if (rc < 0) {
56         TLOGE("Unable to send unwrap request: %d\n", rc);
57         goto out;
58     }
59 
60     uevent_t uevt;
61     rc = wait(chan, &uevt, INFINITE_TIME);
62     if (rc != NO_ERROR) {
63         goto out;
64     }
65 
66     struct full_keybox_unwrap_response rsp;
67     rc = tipc_recv2(chan, sizeof(rsp.header), &rsp, sizeof(rsp),
68                     unwrapped_keybox, unwrapped_keybox_buf_size);
69     if (rc < 0) {
70         goto out;
71     }
72 
73     if (rsp.header.status != KEYBOX_STATUS_SUCCESS) {
74         rc = rsp.header.status;
75         goto out;
76     }
77 
78     if ((size_t)rc < sizeof(rsp)) {
79         rc = ERR_IO;
80         goto out;
81     }
82 
83     uint64_t computed_size;
84     if (__builtin_add_overflow(rsp.unwrap_header.unwrapped_keybox_len,
85                                sizeof(rsp), &computed_size)) {
86         rc = ERR_IO;
87         goto out;
88     }
89 
90     if (computed_size != (size_t)rc) {
91         rc = ERR_IO;
92         goto out;
93     }
94 
95     *unwrapped_keybox_size = rsp.unwrap_header.unwrapped_keybox_len;
96 
97     rc = NO_ERROR;
98 
99 out:
100     close(chan);
101     return rc;
102 }
103