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