blob: 16ed5162665d3a7ddd65d97bc11e341c276b1505 [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
29/**********************************/
30/** global definitions **/
31/**********************************/
32
33#define TZ_ES_SET_ICE_KEY 0x2
34#define TZ_ES_INVALIDATE_ICE_KEY 0x3
35
36/* index 0 and 1 is reserved for FDE */
37#define MIN_ICE_KEY_INDEX 2
38
39#define MAX_ICE_KEY_INDEX 31
40
41
42#define TZ_ES_SET_ICE_KEY_ID \
43 TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, TZ_SVC_ES, TZ_ES_SET_ICE_KEY)
44
45
46#define TZ_ES_INVALIDATE_ICE_KEY_ID \
47 TZ_SYSCALL_CREATE_SMC_ID(TZ_OWNER_SIP, \
48 TZ_SVC_ES, TZ_ES_INVALIDATE_ICE_KEY)
49
50
51#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
57#define TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID \
58 TZ_SYSCALL_CREATE_PARAM_ID_1( \
59 TZ_SYSCALL_PARAM_TYPE_VAL)
60
61#define ICE_KEY_SIZE 32
62#define ICE_SALT_SIZE 32
63
64static uint8_t ice_key[ICE_KEY_SIZE];
65static uint8_t ice_salt[ICE_KEY_SIZE];
66
67int qti_pfk_ice_set_key(uint32_t index, uint8_t *key, uint8_t *salt,
68 char *storage_type)
69{
70 struct scm_desc desc = {0};
71 int ret, ret1;
72 char *tzbuf_key = (char *)ice_key;
73 char *tzbuf_salt = (char *)ice_salt;
74 char *s_type = storage_type;
75
76 uint32_t smc_id = 0;
77 u32 tzbuflen_key = sizeof(ice_key);
78 u32 tzbuflen_salt = sizeof(ice_salt);
79
80 if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
81 pr_err("%s Invalid index %d\n", __func__, index);
82 return -EINVAL;
83 }
84 if (!key || !salt) {
85 pr_err("%s Invalid key/salt\n", __func__);
86 return -EINVAL;
87 }
88
89 if (!tzbuf_key || !tzbuf_salt) {
90 pr_err("%s No Memory\n", __func__);
91 return -ENOMEM;
92 }
93
94 if (s_type == NULL) {
95 pr_err("%s Invalid Storage type\n", __func__);
96 return -EINVAL;
97 }
98
99 memset(tzbuf_key, 0, tzbuflen_key);
100 memset(tzbuf_salt, 0, tzbuflen_salt);
101
102 memcpy(ice_key, key, tzbuflen_key);
103 memcpy(ice_salt, salt, tzbuflen_salt);
104
105 dmac_flush_range(tzbuf_key, tzbuf_key + tzbuflen_key);
106 dmac_flush_range(tzbuf_salt, tzbuf_salt + tzbuflen_salt);
107
108 smc_id = TZ_ES_SET_ICE_KEY_ID;
109
110 desc.arginfo = TZ_ES_SET_ICE_KEY_PARAM_ID;
111 desc.args[0] = index;
112 desc.args[1] = virt_to_phys(tzbuf_key);
113 desc.args[2] = tzbuflen_key;
114 desc.args[3] = virt_to_phys(tzbuf_salt);
115 desc.args[4] = tzbuflen_salt;
116
117 ret = qcom_ice_setup_ice_hw((const char *)s_type, true);
118
119 if (ret) {
120 pr_err("%s: could not enable clocks: %d\n", __func__, ret);
121 goto out;
122 }
123
124 ret = scm_call2(smc_id, &desc);
125
126 if (ret) {
127 pr_err("%s: Set Key Error: %d\n", __func__, ret);
128 if (ret == -EBUSY) {
129 if (qcom_ice_setup_ice_hw((const char *)s_type, false))
130 pr_err("%s: clock disable failed\n", __func__);
131 goto out;
132 }
133 /*Try to invalidate the key to keep ICE in proper state*/
134 smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
135 desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
136 desc.args[0] = index;
137 ret1 = scm_call2(smc_id, &desc);
138 if (ret1)
139 pr_err("%s: Invalidate Key Error: %d\n", __func__,
140 ret1);
141 goto out;
142 }
143 ret = qcom_ice_setup_ice_hw((const char *)s_type, false);
144
145out:
146 return ret;
147}
148
149int qti_pfk_ice_invalidate_key(uint32_t index, char *storage_type)
150{
151 struct scm_desc desc = {0};
152 int ret;
153
154 uint32_t smc_id = 0;
155
156 if (index < MIN_ICE_KEY_INDEX || index > MAX_ICE_KEY_INDEX) {
157 pr_err("%s Invalid index %d\n", __func__, index);
158 return -EINVAL;
159 }
160
161 if (storage_type == NULL) {
162 pr_err("%s Invalid Storage type\n", __func__);
163 return -EINVAL;
164 }
165
166 smc_id = TZ_ES_INVALIDATE_ICE_KEY_ID;
167
168 desc.arginfo = TZ_ES_INVALIDATE_ICE_KEY_PARAM_ID;
169 desc.args[0] = index;
170
171 ret = qcom_ice_setup_ice_hw((const char *)storage_type, true);
172
173 if (ret) {
174 pr_err("%s: could not enable clocks: 0x%x\n", __func__, ret);
175 return ret;
176 }
177
178 ret = scm_call2(smc_id, &desc);
179
180 if (ret) {
181 pr_err("%s: Error: 0x%x\n", __func__, ret);
182 if (qcom_ice_setup_ice_hw((const char *)storage_type, false))
183 pr_err("%s: could not disable clocks\n", __func__);
184 } else {
185 ret = qcom_ice_setup_ice_hw((const char *)storage_type, false);
186 }
187
188 return ret;
189}