blob: e5ed3d6f8765d79991a29b6264d5363b82d22d8f [file] [log] [blame]
Neeraj Sonic692cb92018-04-18 17:20:22 +05301/* Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
2 *
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License version 2 and
5 * only version 2 as published by the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 */
12
13#include <linux/module.h>
14#include <linux/init.h>
15#include <linux/errno.h>
16#include <linux/io.h>
17#include <linux/interrupt.h>
18#include <linux/delay.h>
19#include <linux/async.h>
20#include <linux/mm.h>
21#include <linux/of.h>
22#include <soc/qcom/scm.h>
23#include <linux/device-mapper.h>
24#include <soc/qcom/qseecomi.h>
25#include <crypto/ice.h>
26#include "pfk_ice.h"
27
28
Neeraj Sonie3af8d52018-09-05 14:32:49 +053029#define TZ_ES_SET_ICE_KEY 0x2
30#define TZ_ES_CONFIG_SET_ICE_KEY 0x4
31#define TZ_ES_INVALIDATE_ICE_KEY 0x3
Neeraj Sonic692cb92018-04-18 17:20:22 +053032
33/* index 0 and 1 is reserved for FDE */
Neeraj Sonie3af8d52018-09-05 14:32:49 +053034#define MIN_ICE_KEY_INDEX 2
Neeraj Sonic692cb92018-04-18 17:20:22 +053035
Neeraj Sonie3af8d52018-09-05 14:32:49 +053036#define MAX_ICE_KEY_INDEX 31
37#define ICE20 2
38
39#define TZ_ES_SET_ICE_KEY_ID \
40 TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, \
41 TZ_ES_SET_ICE_KEY)
Neeraj Sonic692cb92018-04-18 17:20:22 +053042
Neeraj Soniefb33112018-08-17 20:39:35 +053043#define TZ_ES_CONFIG_SET_ICE_KEY_ID \
44 TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, \
45 TZ_ES_CONFIG_SET_ICE_KEY)
Neeraj Sonic692cb92018-04-18 17:20:22 +053046
47#define TZ_ES_INVALIDATE_ICE_KEY_ID \
48 TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \
49 TZ_SVC_ES, TZ_ES_INVALIDATE_ICE_KEY)
50
Neeraj Sonie3af8d52018-09-05 14:32:49 +053051#define TZ_ES_SET_ICE_KEY_PARAM_ID \
52 TZ_SYSCALL_CREATE_PARAM_ID_5( \
53 TZ_SYSCALL_PARAM_TYPE_VAL, \
54 TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL, \
55 TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL)
56
Neeraj Soniefb33112018-08-17 20:39:35 +053057#define TZ_ES_CONFIG_SET_ICE_KEY_PARAM_ID \
Neeraj Sonic692cb92018-04-18 17:20:22 +053058 TZ_SYSCALL_CREATE_PARAM_ID_5( \
59 TZ_SYSCALL_PARAM_TYPE_VAL, \
60 TZ_SYSCALL_PARAM_TYPE_BUF_RW, TZ_SYSCALL_PARAM_TYPE_VAL, \
Neeraj Soniefb33112018-08-17 20:39:35 +053061 TZ_SYSCALL_PARAM_TYPE_VAL, TZ_SYSCALL_PARAM_TYPE_VAL)
Neeraj Sonic692cb92018-04-18 17:20:22 +053062
63#define TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID \
64 TZ_SYSCALL_CREATE_PARAM_ID_1( \
65 TZ_SYSCALL_PARAM_TYPE_VAL)
66
Neeraj Soniefb33112018-08-17 20:39:35 +053067#define ICE_BUFFER_SIZE 64
Neeraj Sonic692cb92018-04-18 17:20:22 +053068
Neeraj Sonic692cb92018-04-18 17:20:22 +053069int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
Neeraj Sonie3af8d52018-09-05 14:32:49 +053070 char *storage_type, unsigned int data_unit,
71 int ice_rev)
Neeraj Sonic692cb92018-04-18 17:20:22 +053072{
73 struct scm_desc desc = {0};
74 int ret, ret1;
Neeraj Sonic692cb92018-04-18 17:20:22 +053075 char *s_type = storage_type;
Neeraj Sonie3af8d52018-09-05 14:32:49 +053076 char *ice_buffer = NULL;
77 char *tzbuf_salt = NULL;
78 char *tzbuf_key = NULL;
Neeraj Sonic692cb92018-04-18 17:20:22 +053079
80 uint32_t smc_id = 0;
Neeraj Soniefb33112018-08-17 20:39:35 +053081 u32 size = ICE_BUFFER_SIZE / 2;
Neeraj Sonic692cb92018-04-18 17:20:22 +053082
83 if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
84 pr_err("%s Invalid index %d\n", __func__, index);
85 return -EINVAL;
86 }
87 if (!key || !salt) {
88 pr_err("%s Invalid key/salt\n", __func__);
89 return -EINVAL;
90 }
91
Neeraj Sonic692cb92018-04-18 17:20:22 +053092 if (s_type == NULL) {
93 pr_err("%s Invalid Storage type\n", __func__);
94 return -EINVAL;
95 }
96
Neeraj Sonie3af8d52018-09-05 14:32:49 +053097 if (ice_rev > ICE20) {
98 ice_buffer = kzalloc(ICE_BUFFER_SIZE, GFP_KERNEL);
99 if (!ice_buffer)
100 return -ENOMEM;
Neeraj Sonic692cb92018-04-18 17:20:22 +0530101
Neeraj Sonie3af8d52018-09-05 14:32:49 +0530102 memset(ice_buffer, 0, ICE_BUFFER_SIZE);
103 memcpy(ice_buffer, key, size);
104 memcpy(ice_buffer + size, salt, size);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530105
Neeraj Sonie3af8d52018-09-05 14:32:49 +0530106 dmac_flush_range(ice_buffer, ice_buffer + ICE_BUFFER_SIZE);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530107
Neeraj Sonie3af8d52018-09-05 14:32:49 +0530108 smc_id = TZ_ES_CONFIG_SET_ICE_KEY_ID;
Neeraj Sonic692cb92018-04-18 17:20:22 +0530109
Neeraj Sonie3af8d52018-09-05 14:32:49 +0530110 desc.arginfo = TZ_ES_CONFIG_SET_ICE_KEY_PARAM_ID;
111 desc.args[0] = index;
112 desc.args[1] = virt_to_phys(ice_buffer);
113 desc.args[2] = ICE_BUFFER_SIZE;
114 desc.args[3] = ICE_CRYPTO_MODE_XTS_256;
115 desc.args[4] = data_unit;
116 } else {
117 tzbuf_key = kzalloc((ICE_BUFFER_SIZE / 2), GFP_KERNEL);
118 if (tzbuf_key) {
119 tzbuf_salt = kzalloc((ICE_BUFFER_SIZE / 2), GFP_KERNEL);
120 if (!tzbuf_salt) {
121 kfree(tzbuf_key);
122 return -ENOMEM;
123 }
124 } else {
125 return -ENOMEM;
126 }
127
128 memset(tzbuf_key, 0, size);
129 memset(tzbuf_salt, 0, size);
130 memcpy(tzbuf_key, key, size);
131 memcpy(tzbuf_salt, salt, size);
132
133 dmac_flush_range(tzbuf_key, tzbuf_key + size);
134 dmac_flush_range(tzbuf_salt, tzbuf_salt + size);
135
136 smc_id = TZ_ES_SET_ICE_KEY_ID;
137
138 desc.arginfo = TZ_ES_SET_ICE_KEY_PARAM_ID;
139 desc.args[0] = index;
140 desc.args[1] = virt_to_phys(tzbuf_key);
141 desc.args[2] = size;
142 desc.args[3] = virt_to_phys(tzbuf_salt);
143 desc.args[4] = size;
144 }
Neeraj Sonic692cb92018-04-18 17:20:22 +0530145
146 ret = qcom_ice_setup_ice_hw((const char *)s_type, true);
147
148 if (ret) {
149 pr_err("%s: could not enable clocks: %d\n", __func__, ret);
150 goto out;
151 }
152
Neeraj Sonidee86cb2018-04-02 19:00:31 +0530153 ret = scm_call2_noretry(smc_id, &desc);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530154
155 if (ret) {
156 pr_err("%s: Set Key Error: %d\n", __func__, ret);
157 if (ret == -EBUSY) {
158 if (qcom_ice_setup_ice_hw((const char *)s_type, false))
159 pr_err("%s: clock disable failed\n", __func__);
160 goto out;
161 }
162 /*Try to invalidate the key to keep ICE in proper state*/
163 smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
164 desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
165 desc.args[0] = index;
Neeraj Sonidee86cb2018-04-02 19:00:31 +0530166 ret1 = scm_call2_noretry(smc_id, &desc);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530167 if (ret1)
168 pr_err("%s: Invalidate Key Error: %d\n", __func__,
169 ret1);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530170 }
Neeraj Sonicce088b2018-07-25 15:52:51 +0530171 ret1 = qcom_ice_setup_ice_hw((const char *)s_type, false);
172 if (ret1)
173 pr_err("%s: Error %d disabling clocks\n", __func__, ret1);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530174
175out:
Neeraj Sonie3af8d52018-09-05 14:32:49 +0530176 if (ice_rev > ICE20) {
177 kfree(ice_buffer);
178 } else {
179 kfree(tzbuf_key);
180 kfree(tzbuf_salt);
181 }
182
Neeraj Sonic692cb92018-04-18 17:20:22 +0530183 return ret;
184}
185
186int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type)
187{
188 struct scm_desc desc = {0};
189 int ret;
190
191 uint32_t smc_id = 0;
192
193 if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
194 pr_err("%s Invalid index %d\n", __func__, index);
195 return -EINVAL;
196 }
197
198 if (storage_type == NULL) {
199 pr_err("%s Invalid Storage type\n", __func__);
200 return -EINVAL;
201 }
202
203 smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
204
205 desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
206 desc.args[0] = index;
207
208 ret = qcom_ice_setup_ice_hw((const char *)storage_type, true);
209
210 if (ret) {
211 pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);
212 return ret;
213 }
214
Neeraj Sonidee86cb2018-04-02 19:00:31 +0530215 ret = scm_call2_noretry(smc_id, &desc);
Neeraj Sonic692cb92018-04-18 17:20:22 +0530216
217 if (ret) {
218 pr_err("%s: Error: 0x%x\n", __func__, ret);
219 if (qcom_ice_setup_ice_hw((const char *)storage_type, false))
220 pr_err("%s: could not disable clocks\n", __func__);
221 } else {
222 ret = qcom_ice_setup_ice_hw((const char *)storage_type, false);
223 }
224
225 return ret;
226}