blob: 61ad8f1ae19a9581ff0a40cbb4d59bd3174f9662 [file] [log] [blame]
Maria Yu4c12e922018-05-10 16:18:20 +08001/* Copyright (c) 2013-2015, 2018, The Linux Foundation. All rights reserved.
Channagoud Kadabi723f6792015-01-29 13:26:06 -08002 *
3 * Redistribution and use in source and binary forms, with or without
4 * modification, are permitted provided that the following conditions are
5 * met:
6 * * Redistributions of source code must retain the above copyright
7 * notice, this list of conditions and the following disclaimer.
8 * * Redistributions in binary form must reproduce the above
9 * copyright notice, this list of conditions and the following
10 * disclaimer in the documentation and/or other materials provided
11 * with the distribution.
12 * * Neither the name of The Linux Foundation nor the names of its
13 * contributors may be used to endorse or promote products derived
14 * from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
17 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
18 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
19 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
23 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
25 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
26 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28#include <debug.h>
29#include <rpmb.h>
30#include <rpmb_listener.h>
31#include <qseecom_lk_api.h>
Maria Yu4c12e922018-05-10 16:18:20 +080032#include <stdlib.h>
Channagoud Kadabi723f6792015-01-29 13:26:06 -080033
34#define RPMB_LSTNR_VERSION_2 0x2
35
36typedef enum
37{
38 TZ_CM_CMD_RPMB_INIT = 0x101, //257
39 TZ_CM_CMD_RPMB_READ, //258
40 TZ_CM_CMD_RPMB_WRITE, //259
41 TZ_CM_CMD_RPMB_PARTITION, //260
42} tz_rpmb_cmd_type;
43
44struct tz_device_init_req
45{
46 uint32_t cmd_id;
47 uint32_t version;
48}__PACKED;
49
50/* RPMB Init response message */
51struct tz_device_init_resp
52{
53 uint32_t cmd_id; /* Command ID */
54 uint32_t version; /* Messaging version from RPMB listener */
55 uint32_t status; /* RPMB init status */
56 uint32_t num_sectors; /* Size of RPMB (in sectors) */
57 uint32_t rel_wr_count; /* Reliable write count for the RPMB */
58 uint32_t dev_type; /* Storage device type (like eMMC or UFS) */
59 uint32_t reserved1; /* Reserved 1 */
60 uint32_t reserved2; /* Reserved 2 */
61 uint32_t reserved3; /* Reserved 3 */
62 uint32_t reserved4; /* Reserved 4 */
63}__PACKED;
64
65struct tz_rpmb_rw_req
66{
67 uint32_t cmd_id;
68 uint32_t num_sectors;
69 uint32_t req_buff_len;
70 uint32_t req_buff_offset;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -070071 uint32_t version;
72 uint32_t rel_wr_count;
Channagoud Kadabi723f6792015-01-29 13:26:06 -080073}__PACKED;
74
75struct tz_rpmb_rw_resp
76{
77 uint32_t cmd_id;
78 int32_t status;
79 uint32_t res_buff_len;
80 uint32_t res_buff_offset;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -070081 uint32_t version;
Channagoud Kadabi723f6792015-01-29 13:26:06 -080082}__PACKED;
83
84typedef int (*ListenerCallback)(void*, uint32_t);
85
86static void handle_init_request(void *buf, uint32_t sz)
87{
88 struct tz_device_init_req *init_req_p = NULL;
89 struct tz_device_init_resp *init_resp = (struct tz_device_init_resp*) buf;
90 struct rpmb_init_info *rpmb_info = NULL;
91
92 init_req_p = (struct tz_device_init_req *) buf;
93
94 rpmb_info = rpmb_get_init_info();
95
96 if (rpmb_info)
97 init_resp->status = 0;
98
99 init_resp->cmd_id = init_req_p->cmd_id;
100 init_resp->version = RPMB_LSTNR_VERSION_2;
Sridhar Parasuram552f6492015-09-08 11:58:52 -0700101 init_resp->num_sectors = rpmb_info->size;
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800102 init_resp->rel_wr_count = rpmb_info->rel_wr_count;
103 init_resp->dev_type = rpmb_info->dev_type;
104}
105
106static void handle_rw_request(void *buf, uint32_t sz)
107{
108 struct tz_rpmb_rw_req *req_p = (struct tz_rpmb_rw_req *)buf;
109 struct tz_rpmb_rw_resp *resp_p = NULL;
110 uint32_t *req_buf = buf + req_p->req_buff_offset;
Saranya Chidura88168a32018-10-11 17:21:11 +0530111 uint32_t *resp_buf = buf + sizeof(struct tz_rpmb_rw_resp);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800112
113 resp_p = (struct tz_rpmb_rw_resp *) buf;
114
115 switch (req_p->cmd_id)
116 {
117 case TZ_CM_CMD_RPMB_READ:
118#if DEBUG_RPMB
119 dprintf(INFO, "Read Request received\n");
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700120 dprintf(INFO, "READ: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800121#endif
122 resp_p->status = rpmb_read(req_buf, req_p->num_sectors, resp_buf, &resp_p->res_buff_len);
123 break;
124 case TZ_CM_CMD_RPMB_WRITE:
125#if DEBUG_RPMB
126 dprintf(INFO, "Write Request received\n");
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700127 dprintf(INFO, "WRITE: RPMB_REL_RW_COUNT 0x%x\n", req_p->rel_wr_count);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800128#endif
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700129 resp_p->status = rpmb_write(req_buf, req_p->num_sectors, req_p->rel_wr_count, resp_buf, &resp_p->res_buff_len);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800130 break;
131 default:
132 dprintf(CRITICAL, "Unsupported request command request: %u\n", req_p->cmd_id);
133 ASSERT(0);
134 };
135
Saranya Chidura88168a32018-10-11 17:21:11 +0530136 resp_p->res_buff_offset = sizeof(struct tz_rpmb_rw_resp);
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800137 resp_p->cmd_id = req_p->cmd_id;
138}
139
140int rpmb_cmd_handler(void *buf, uint32_t sz)
141{
142 int ret = 0;
143 uint32_t cmd_id;
144
145 ASSERT(buf);
146
147 cmd_id = (uint32_t) *((uint32_t *)buf);
148
149 switch(cmd_id)
150 {
151 case TZ_CM_CMD_RPMB_READ:
152 case TZ_CM_CMD_RPMB_WRITE:
153 handle_rw_request(buf, sz);
154 break;
155 case TZ_CM_CMD_RPMB_INIT:
156#if DEBUG_RPMB
157 dprintf(INFO, "RPMB init received\n");
158#endif
159 handle_init_request(buf, sz);
160 break;
161 case TZ_CM_CMD_RPMB_PARTITION:
162#if DEBUG_RPMB
163 dprintf(INFO, "Partition init received\n");
164#endif
165 ret = -1;
166 break;
167 default:
168 /* Does qseecom need a response here? */
169 dprintf(CRITICAL, "Unsupported Request from qseecom: %d\n", cmd_id);
170 ASSERT(0);
171 };
172
173 return ret;
174}
175
176int rpmb_listener_start()
177{
178 int ret;
179 struct qseecom_listener_services rpmb_listener;
180
181 rpmb_listener.service_name = "RPMB system services";
182 rpmb_listener.id = RPMB_LSTNR_ID;
Sridhar Parasuramc97e0542015-06-26 16:14:58 -0700183 rpmb_listener.sb_size = 25 * 1024;
Channagoud Kadabi723f6792015-01-29 13:26:06 -0800184 rpmb_listener.service_cmd_handler = rpmb_cmd_handler;
185
186 ret = qseecom_register_listener(&rpmb_listener);
187
188 if (ret < 0)
189 dprintf(CRITICAL, "Failed to register rpmb listener\n");
190
191 return ret;
192}
193
194int rpmb_listener_stop(int id)
195{
196 int ret;
197
198 ret = qseecom_deregister_listener(id);
199
200 if (ret < 0)
201 dprintf(CRITICAL, "Failed to unregister rpmb listener\n");
202
203 return ret;
204}
205