1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2022 Rockchip Electronics Co. Ltd.
3*4882a593Smuzhiyun */
4*4882a593Smuzhiyun #include <string.h>
5*4882a593Smuzhiyun #include "rkcrypto_core_int.h"
6*4882a593Smuzhiyun #include "rkcrypto_otp_key.h"
7*4882a593Smuzhiyun #include "rkcrypto_trace.h"
8*4882a593Smuzhiyun #include "tee_client_api.h"
9*4882a593Smuzhiyun
10*4882a593Smuzhiyun #define STORAGE_UUID { 0x2d26d8a8, 0x5134, 0x4dd8, \
11*4882a593Smuzhiyun { 0xb3, 0x2f, 0xb3, 0x4b, 0xce, 0xeb, 0xc4, 0x71 } }
12*4882a593Smuzhiyun #define RK_CRYPTO_SERVICE_UUID { 0x0cacdb5d, 0x4fea, 0x466c, \
13*4882a593Smuzhiyun { 0x97, 0x16, 0x3d, 0x54, 0x16, 0x52, 0x83, 0x0f } }
14*4882a593Smuzhiyun
15*4882a593Smuzhiyun #define STORAGE_CMD_WRITE_OEM_OTP_KEY 14
16*4882a593Smuzhiyun #define STORAGE_CMD_SET_OEM_HR_OTP_READ_LOCK 15
17*4882a593Smuzhiyun #define STORAGE_CMD_OEM_OTP_KEY_IS_WRITTEN 16
18*4882a593Smuzhiyun #define CRYPTO_SERVICE_CMD_OEM_OTP_KEY_CIPHER 0x00000001
19*4882a593Smuzhiyun #define CRYPTO_SERVICE_CMD_OEM_OTP_KEY_PHYS_CIPHER 0x00000002
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun static const struct {
22*4882a593Smuzhiyun const uint32_t tee_code;
23*4882a593Smuzhiyun const uint32_t rk_crypto_code;
24*4882a593Smuzhiyun } tee_crypto_code[] = {
25*4882a593Smuzhiyun {TEEC_SUCCESS, RK_CRYPTO_SUCCESS},
26*4882a593Smuzhiyun {TEEC_ERROR_GENERIC, RK_CRYPTO_ERR_GENERIC},
27*4882a593Smuzhiyun {TEEC_ERROR_BAD_PARAMETERS, RK_CRYPTO_ERR_PARAMETER},
28*4882a593Smuzhiyun {TEEC_ERROR_BAD_STATE, RK_CRYPTO_ERR_STATE},
29*4882a593Smuzhiyun {TEEC_ERROR_NOT_SUPPORTED, RK_CRYPTO_ERR_NOT_SUPPORTED},
30*4882a593Smuzhiyun {TEEC_ERROR_OUT_OF_MEMORY, RK_CRYPTO_ERR_OUT_OF_MEMORY},
31*4882a593Smuzhiyun {TEEC_ERROR_ACCESS_DENIED, RK_CRYPTO_ERR_ACCESS_DENIED},
32*4882a593Smuzhiyun };
33*4882a593Smuzhiyun
tee_to_crypto_code(uint32_t tee_code)34*4882a593Smuzhiyun static RK_RES tee_to_crypto_code(uint32_t tee_code)
35*4882a593Smuzhiyun {
36*4882a593Smuzhiyun uint32_t i;
37*4882a593Smuzhiyun uint32_t array_size = sizeof(tee_crypto_code) / sizeof((tee_crypto_code)[0]);
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun for (i = 0; i < array_size; i++) {
40*4882a593Smuzhiyun if (tee_code == tee_crypto_code[i].tee_code)
41*4882a593Smuzhiyun return tee_crypto_code[i].rk_crypto_code;
42*4882a593Smuzhiyun }
43*4882a593Smuzhiyun
44*4882a593Smuzhiyun /* Others convert to RK_CRYPTO_ERR_GENERIC. */
45*4882a593Smuzhiyun return RK_CRYPTO_ERR_GENERIC;
46*4882a593Smuzhiyun }
47*4882a593Smuzhiyun
cipher_get_blocksize(uint32_t algo)48*4882a593Smuzhiyun static uint32_t cipher_get_blocksize(uint32_t algo)
49*4882a593Smuzhiyun {
50*4882a593Smuzhiyun switch (algo) {
51*4882a593Smuzhiyun case RK_ALGO_DES:
52*4882a593Smuzhiyun case RK_ALGO_TDES:
53*4882a593Smuzhiyun return DES_BLOCK_SIZE;
54*4882a593Smuzhiyun case RK_ALGO_AES:
55*4882a593Smuzhiyun return AES_BLOCK_SIZE;
56*4882a593Smuzhiyun case RK_ALGO_SM4:
57*4882a593Smuzhiyun return SM4_BLOCK_SIZE;
58*4882a593Smuzhiyun default:
59*4882a593Smuzhiyun return 1;
60*4882a593Smuzhiyun }
61*4882a593Smuzhiyun }
62*4882a593Smuzhiyun
rk_write_oem_otp_key(enum RK_OEM_OTP_KEYID key_id,uint8_t * key,uint32_t key_len)63*4882a593Smuzhiyun RK_RES rk_write_oem_otp_key(enum RK_OEM_OTP_KEYID key_id, uint8_t *key,
64*4882a593Smuzhiyun uint32_t key_len)
65*4882a593Smuzhiyun {
66*4882a593Smuzhiyun RK_RES res;
67*4882a593Smuzhiyun TEEC_Context contex;
68*4882a593Smuzhiyun TEEC_Session session;
69*4882a593Smuzhiyun TEEC_Operation operation;
70*4882a593Smuzhiyun TEEC_UUID uuid = STORAGE_UUID;
71*4882a593Smuzhiyun uint32_t error_origin = 0;
72*4882a593Smuzhiyun
73*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id != RK_OEM_OTP_KEY0 &&
74*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY1 &&
75*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY2 &&
76*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY3 &&
77*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY_FW);
78*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(!key);
79*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_len != 16 &&
80*4882a593Smuzhiyun key_len != 24 &&
81*4882a593Smuzhiyun key_len != 32);
82*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id == RK_OEM_OTP_KEY_FW &&
83*4882a593Smuzhiyun key_len != 16);
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun res = TEEC_InitializeContext(NULL, &contex);
86*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
87*4882a593Smuzhiyun E_TRACE("TEEC_InitializeContext failed with code TEEC res= 0x%x", res);
88*4882a593Smuzhiyun return tee_to_crypto_code(res);
89*4882a593Smuzhiyun }
90*4882a593Smuzhiyun
91*4882a593Smuzhiyun res = TEEC_OpenSession(&contex, &session, &uuid, TEEC_LOGIN_PUBLIC,
92*4882a593Smuzhiyun NULL, NULL, &error_origin);
93*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
94*4882a593Smuzhiyun E_TRACE("TEEC_Opensession failed with code TEEC res= 0x%x origin 0x%x",
95*4882a593Smuzhiyun res, error_origin);
96*4882a593Smuzhiyun goto out;
97*4882a593Smuzhiyun }
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun memset(&operation, 0, sizeof(TEEC_Operation));
100*4882a593Smuzhiyun operation.params[0].value.a = key_id;
101*4882a593Smuzhiyun operation.params[1].tmpref.buffer = key;
102*4882a593Smuzhiyun operation.params[1].tmpref.size = key_len;
103*4882a593Smuzhiyun operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
104*4882a593Smuzhiyun TEEC_MEMREF_TEMP_INPUT,
105*4882a593Smuzhiyun TEEC_NONE,
106*4882a593Smuzhiyun TEEC_NONE);
107*4882a593Smuzhiyun
108*4882a593Smuzhiyun res = TEEC_InvokeCommand(&session, STORAGE_CMD_WRITE_OEM_OTP_KEY,
109*4882a593Smuzhiyun &operation, &error_origin);
110*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
111*4882a593Smuzhiyun E_TRACE("InvokeCommand ERR! TEEC res= 0x%x, error_origin= 0x%x",
112*4882a593Smuzhiyun res, error_origin);
113*4882a593Smuzhiyun }
114*4882a593Smuzhiyun
115*4882a593Smuzhiyun TEEC_CloseSession(&session);
116*4882a593Smuzhiyun out:
117*4882a593Smuzhiyun TEEC_FinalizeContext(&contex);
118*4882a593Smuzhiyun return tee_to_crypto_code(res);
119*4882a593Smuzhiyun }
120*4882a593Smuzhiyun
rk_oem_otp_key_is_written(enum RK_OEM_OTP_KEYID key_id,uint8_t * is_written)121*4882a593Smuzhiyun RK_RES rk_oem_otp_key_is_written(enum RK_OEM_OTP_KEYID key_id, uint8_t *is_written)
122*4882a593Smuzhiyun {
123*4882a593Smuzhiyun RK_RES res;
124*4882a593Smuzhiyun TEEC_Context contex;
125*4882a593Smuzhiyun TEEC_Session session;
126*4882a593Smuzhiyun TEEC_Operation operation;
127*4882a593Smuzhiyun TEEC_UUID uuid = STORAGE_UUID;
128*4882a593Smuzhiyun uint32_t error_origin = 0;
129*4882a593Smuzhiyun
130*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id != RK_OEM_OTP_KEY0 &&
131*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY1 &&
132*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY2 &&
133*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY3 &&
134*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY_FW);
135*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(!is_written);
136*4882a593Smuzhiyun
137*4882a593Smuzhiyun res = TEEC_InitializeContext(NULL, &contex);
138*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
139*4882a593Smuzhiyun E_TRACE("TEEC_InitializeContext failed with code TEEC res= 0x%x", res);
140*4882a593Smuzhiyun return tee_to_crypto_code(res);
141*4882a593Smuzhiyun }
142*4882a593Smuzhiyun
143*4882a593Smuzhiyun res = TEEC_OpenSession(&contex, &session, &uuid, TEEC_LOGIN_PUBLIC,
144*4882a593Smuzhiyun NULL, NULL, &error_origin);
145*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
146*4882a593Smuzhiyun E_TRACE("TEEC_Opensession failed with code TEEC res= 0x%x origin 0x%x",
147*4882a593Smuzhiyun res, error_origin);
148*4882a593Smuzhiyun goto out;
149*4882a593Smuzhiyun }
150*4882a593Smuzhiyun
151*4882a593Smuzhiyun memset(&operation, 0, sizeof(TEEC_Operation));
152*4882a593Smuzhiyun operation.params[0].value.a = key_id;
153*4882a593Smuzhiyun operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INOUT,
154*4882a593Smuzhiyun TEEC_NONE,
155*4882a593Smuzhiyun TEEC_NONE,
156*4882a593Smuzhiyun TEEC_NONE);
157*4882a593Smuzhiyun
158*4882a593Smuzhiyun res = TEEC_InvokeCommand(&session, STORAGE_CMD_OEM_OTP_KEY_IS_WRITTEN,
159*4882a593Smuzhiyun &operation, &error_origin);
160*4882a593Smuzhiyun if (res == TEEC_ERROR_ACCESS_DENIED) {
161*4882a593Smuzhiyun E_TRACE("Check if it has been set oem_hr_otp_read_lock!");
162*4882a593Smuzhiyun } else if (res != TEEC_SUCCESS) {
163*4882a593Smuzhiyun E_TRACE("InvokeCommand ERR! TEEC res= 0x%x, error_origin= 0x%x",
164*4882a593Smuzhiyun res, error_origin);
165*4882a593Smuzhiyun } else {
166*4882a593Smuzhiyun *is_written = operation.params[0].value.b;
167*4882a593Smuzhiyun }
168*4882a593Smuzhiyun
169*4882a593Smuzhiyun TEEC_CloseSession(&session);
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun out:
172*4882a593Smuzhiyun TEEC_FinalizeContext(&contex);
173*4882a593Smuzhiyun return tee_to_crypto_code(res);
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
rk_set_oem_hr_otp_read_lock(enum RK_OEM_OTP_KEYID key_id)176*4882a593Smuzhiyun RK_RES rk_set_oem_hr_otp_read_lock(enum RK_OEM_OTP_KEYID key_id)
177*4882a593Smuzhiyun {
178*4882a593Smuzhiyun RK_RES res;
179*4882a593Smuzhiyun TEEC_Context contex;
180*4882a593Smuzhiyun TEEC_Session session;
181*4882a593Smuzhiyun TEEC_Operation operation;
182*4882a593Smuzhiyun TEEC_UUID uuid = STORAGE_UUID;
183*4882a593Smuzhiyun uint32_t error_origin = 0;
184*4882a593Smuzhiyun
185*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id != RK_OEM_OTP_KEY0 &&
186*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY1 &&
187*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY2 &&
188*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY3);
189*4882a593Smuzhiyun
190*4882a593Smuzhiyun res = TEEC_InitializeContext(NULL, &contex);
191*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
192*4882a593Smuzhiyun E_TRACE("TEEC_InitializeContext failed with code TEEC res= 0x%x", res);
193*4882a593Smuzhiyun return tee_to_crypto_code(res);
194*4882a593Smuzhiyun }
195*4882a593Smuzhiyun
196*4882a593Smuzhiyun res = TEEC_OpenSession(&contex, &session, &uuid, TEEC_LOGIN_PUBLIC,
197*4882a593Smuzhiyun NULL, NULL, &error_origin);
198*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
199*4882a593Smuzhiyun E_TRACE("TEEC_Opensession failed with code TEEC res= 0x%x origin 0x%x",
200*4882a593Smuzhiyun res, error_origin);
201*4882a593Smuzhiyun goto out;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun memset(&operation, 0, sizeof(TEEC_Operation));
205*4882a593Smuzhiyun operation.params[0].value.a = key_id;
206*4882a593Smuzhiyun operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
207*4882a593Smuzhiyun TEEC_NONE,
208*4882a593Smuzhiyun TEEC_NONE,
209*4882a593Smuzhiyun TEEC_NONE);
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun res = TEEC_InvokeCommand(&session, STORAGE_CMD_SET_OEM_HR_OTP_READ_LOCK,
212*4882a593Smuzhiyun &operation, &error_origin);
213*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
214*4882a593Smuzhiyun E_TRACE("InvokeCommand ERR! TEEC res= 0x%x, error_origin= 0x%x",
215*4882a593Smuzhiyun res, error_origin);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun TEEC_CloseSession(&session);
219*4882a593Smuzhiyun out:
220*4882a593Smuzhiyun TEEC_FinalizeContext(&contex);
221*4882a593Smuzhiyun return tee_to_crypto_code(res);
222*4882a593Smuzhiyun }
223*4882a593Smuzhiyun
rk_oem_otp_key_cipher_virt(enum RK_OEM_OTP_KEYID key_id,rk_cipher_config * config,uint8_t * src,uint8_t * dst,uint32_t len)224*4882a593Smuzhiyun RK_RES rk_oem_otp_key_cipher_virt(enum RK_OEM_OTP_KEYID key_id, rk_cipher_config *config,
225*4882a593Smuzhiyun uint8_t *src, uint8_t *dst, uint32_t len)
226*4882a593Smuzhiyun {
227*4882a593Smuzhiyun RK_RES res;
228*4882a593Smuzhiyun TEEC_Context contex;
229*4882a593Smuzhiyun TEEC_Session session;
230*4882a593Smuzhiyun TEEC_Operation operation;
231*4882a593Smuzhiyun TEEC_UUID uuid = RK_CRYPTO_SERVICE_UUID;
232*4882a593Smuzhiyun uint32_t error_origin = 0, len_aligned, len_cipher, block_size;
233*4882a593Smuzhiyun TEEC_SharedMemory sm;
234*4882a593Smuzhiyun
235*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id != RK_OEM_OTP_KEY0 &&
236*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY1 &&
237*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY2 &&
238*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY3 &&
239*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY_FW);
240*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(!config || !src || !dst);
241*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->algo != RK_ALGO_AES &&
242*4882a593Smuzhiyun config->algo != RK_ALGO_SM4);
243*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode >= RK_CIPHER_MODE_XTS);
244*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->operation != RK_OP_CIPHER_ENC &&
245*4882a593Smuzhiyun config->operation != RK_OP_CIPHER_DEC);
246*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->key_len != 16 &&
247*4882a593Smuzhiyun config->key_len != 24 &&
248*4882a593Smuzhiyun config->key_len != 32);
249*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id == RK_OEM_OTP_KEY_FW &&
250*4882a593Smuzhiyun config->key_len != 16);
251*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(len > RK_CRYPTO_MAX_DATA_LEN ||
252*4882a593Smuzhiyun len == 0);
253*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode == RK_CIPHER_MODE_CTS &&
254*4882a593Smuzhiyun len <= 16);
255*4882a593Smuzhiyun
256*4882a593Smuzhiyun len_cipher = len;
257*4882a593Smuzhiyun block_size = cipher_get_blocksize(config->algo);
258*4882a593Smuzhiyun
259*4882a593Smuzhiyun if (config->mode != RK_CIPHER_MODE_CTS && (len % block_size)) {
260*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode != RK_CIPHER_MODE_CTR &&
261*4882a593Smuzhiyun config->mode != RK_CIPHER_MODE_CFB &&
262*4882a593Smuzhiyun config->mode != RK_CIPHER_MODE_OFB);
263*4882a593Smuzhiyun
264*4882a593Smuzhiyun len_aligned = ROUNDUP(len, block_size);
265*4882a593Smuzhiyun len_cipher = len_aligned;
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun res = TEEC_InitializeContext(NULL, &contex);
269*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
270*4882a593Smuzhiyun E_TRACE("TEEC_InitializeContext failed with code TEEC res= 0x%x", res);
271*4882a593Smuzhiyun return tee_to_crypto_code(res);
272*4882a593Smuzhiyun }
273*4882a593Smuzhiyun
274*4882a593Smuzhiyun res = TEEC_OpenSession(&contex, &session, &uuid, TEEC_LOGIN_PUBLIC,
275*4882a593Smuzhiyun NULL, NULL, &error_origin);
276*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
277*4882a593Smuzhiyun E_TRACE("TEEC_Opensession failed with code TEEC res= 0x%x origin 0x%x",
278*4882a593Smuzhiyun res, error_origin);
279*4882a593Smuzhiyun goto out;
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun
282*4882a593Smuzhiyun sm.size = len_cipher;
283*4882a593Smuzhiyun sm.flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT;
284*4882a593Smuzhiyun res = TEEC_AllocateSharedMemory(&contex, &sm);
285*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
286*4882a593Smuzhiyun E_TRACE("AllocateSharedMemory ERR! TEEC res= 0x%x", res);
287*4882a593Smuzhiyun goto out1;
288*4882a593Smuzhiyun }
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun memset(sm.buffer, 0, sm.size);
291*4882a593Smuzhiyun memcpy(sm.buffer, src, len);
292*4882a593Smuzhiyun
293*4882a593Smuzhiyun memset(&operation, 0, sizeof(TEEC_Operation));
294*4882a593Smuzhiyun operation.params[0].value.a = key_id;
295*4882a593Smuzhiyun operation.params[1].tmpref.buffer = config;
296*4882a593Smuzhiyun operation.params[1].tmpref.size = sizeof(rk_cipher_config);
297*4882a593Smuzhiyun operation.params[2].memref.parent = &sm;
298*4882a593Smuzhiyun operation.params[2].memref.offset = 0;
299*4882a593Smuzhiyun operation.params[2].memref.size = sm.size;
300*4882a593Smuzhiyun
301*4882a593Smuzhiyun operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
302*4882a593Smuzhiyun TEEC_MEMREF_TEMP_INPUT,
303*4882a593Smuzhiyun TEEC_MEMREF_PARTIAL_INOUT,
304*4882a593Smuzhiyun TEEC_NONE);
305*4882a593Smuzhiyun
306*4882a593Smuzhiyun res = TEEC_InvokeCommand(&session, CRYPTO_SERVICE_CMD_OEM_OTP_KEY_CIPHER,
307*4882a593Smuzhiyun &operation, &error_origin);
308*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
309*4882a593Smuzhiyun E_TRACE("InvokeCommand ERR! TEEC res= 0x%x, error_origin= 0x%x",
310*4882a593Smuzhiyun res, error_origin);
311*4882a593Smuzhiyun } else {
312*4882a593Smuzhiyun memcpy(dst, sm.buffer, sm.size);
313*4882a593Smuzhiyun }
314*4882a593Smuzhiyun
315*4882a593Smuzhiyun TEEC_ReleaseSharedMemory(&sm);
316*4882a593Smuzhiyun
317*4882a593Smuzhiyun out1:
318*4882a593Smuzhiyun TEEC_CloseSession(&session);
319*4882a593Smuzhiyun
320*4882a593Smuzhiyun out:
321*4882a593Smuzhiyun TEEC_FinalizeContext(&contex);
322*4882a593Smuzhiyun return tee_to_crypto_code(res);
323*4882a593Smuzhiyun }
324*4882a593Smuzhiyun
rk_oem_otp_key_cipher(enum RK_OEM_OTP_KEYID key_id,rk_cipher_config * config,int32_t in_fd,int32_t out_fd,uint32_t len)325*4882a593Smuzhiyun RK_RES rk_oem_otp_key_cipher(enum RK_OEM_OTP_KEYID key_id, rk_cipher_config *config,
326*4882a593Smuzhiyun int32_t in_fd, int32_t out_fd, uint32_t len)
327*4882a593Smuzhiyun {
328*4882a593Smuzhiyun RK_RES res;
329*4882a593Smuzhiyun TEEC_Context contex;
330*4882a593Smuzhiyun TEEC_Session session;
331*4882a593Smuzhiyun TEEC_Operation operation;
332*4882a593Smuzhiyun TEEC_UUID uuid = RK_CRYPTO_SERVICE_UUID;
333*4882a593Smuzhiyun uint32_t error_origin = 0, len_aligned, len_cipher, block_size;
334*4882a593Smuzhiyun struct crypt_fd_map_op src_mop;
335*4882a593Smuzhiyun struct crypt_fd_map_op dst_mop;
336*4882a593Smuzhiyun
337*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(in_fd < 0);
338*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(out_fd < 0);
339*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id != RK_OEM_OTP_KEY0 &&
340*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY1 &&
341*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY2 &&
342*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY3 &&
343*4882a593Smuzhiyun key_id != RK_OEM_OTP_KEY_FW);
344*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(!config);
345*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->algo != RK_ALGO_AES &&
346*4882a593Smuzhiyun config->algo != RK_ALGO_SM4);
347*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode >= RK_CIPHER_MODE_XTS);
348*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->operation != RK_OP_CIPHER_ENC &&
349*4882a593Smuzhiyun config->operation != RK_OP_CIPHER_DEC);
350*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->key_len != 16 &&
351*4882a593Smuzhiyun config->key_len != 24 &&
352*4882a593Smuzhiyun config->key_len != 32);
353*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(key_id == RK_OEM_OTP_KEY_FW &&
354*4882a593Smuzhiyun config->key_len != 16);
355*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(len == 0);
356*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode == RK_CIPHER_MODE_CTS &&
357*4882a593Smuzhiyun len <= 16);
358*4882a593Smuzhiyun
359*4882a593Smuzhiyun len_cipher = len;
360*4882a593Smuzhiyun block_size = cipher_get_blocksize(config->algo);
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun if (config->mode != RK_CIPHER_MODE_CTS && (len % block_size)) {
363*4882a593Smuzhiyun RK_CRYPTO_CHECK_PARAM(config->mode != RK_CIPHER_MODE_CTR &&
364*4882a593Smuzhiyun config->mode != RK_CIPHER_MODE_CFB &&
365*4882a593Smuzhiyun config->mode != RK_CIPHER_MODE_OFB);
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun len_aligned = ROUNDUP(len, block_size);
368*4882a593Smuzhiyun len_cipher = len_aligned;
369*4882a593Smuzhiyun }
370*4882a593Smuzhiyun
371*4882a593Smuzhiyun memset(&src_mop, 0, sizeof(src_mop));
372*4882a593Smuzhiyun memset(&dst_mop, 0, sizeof(dst_mop));
373*4882a593Smuzhiyun src_mop.dma_fd = in_fd;
374*4882a593Smuzhiyun dst_mop.dma_fd = out_fd;
375*4882a593Smuzhiyun
376*4882a593Smuzhiyun res = rk_crypto_fd_ioctl(RIOCCRYPT_FD_MAP, &src_mop);
377*4882a593Smuzhiyun if (res != RK_CRYPTO_SUCCESS) {
378*4882a593Smuzhiyun E_TRACE("RIOCCRYPT_FD_MAP failed, res= 0x%x", res);
379*4882a593Smuzhiyun return res;
380*4882a593Smuzhiyun }
381*4882a593Smuzhiyun
382*4882a593Smuzhiyun if (out_fd != in_fd) {
383*4882a593Smuzhiyun res = rk_crypto_fd_ioctl(RIOCCRYPT_FD_MAP, &dst_mop);
384*4882a593Smuzhiyun if (res != RK_CRYPTO_SUCCESS) {
385*4882a593Smuzhiyun E_TRACE("RIOCCRYPT_FD_MAP failed, res= 0x%x", res);
386*4882a593Smuzhiyun goto out;
387*4882a593Smuzhiyun }
388*4882a593Smuzhiyun } else {
389*4882a593Smuzhiyun dst_mop.phys_addr = src_mop.phys_addr;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun res = TEEC_InitializeContext(NULL, &contex);
393*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
394*4882a593Smuzhiyun E_TRACE("TEEC_InitializeContext failed with code TEEC res= 0x%x", res);
395*4882a593Smuzhiyun goto out1;
396*4882a593Smuzhiyun }
397*4882a593Smuzhiyun
398*4882a593Smuzhiyun res = TEEC_OpenSession(&contex, &session, &uuid, TEEC_LOGIN_PUBLIC,
399*4882a593Smuzhiyun NULL, NULL, &error_origin);
400*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
401*4882a593Smuzhiyun E_TRACE("TEEC_Opensession failed with code TEEC res= 0x%x origin 0x%x",
402*4882a593Smuzhiyun res, error_origin);
403*4882a593Smuzhiyun goto out2;
404*4882a593Smuzhiyun }
405*4882a593Smuzhiyun
406*4882a593Smuzhiyun memset(&operation, 0, sizeof(TEEC_Operation));
407*4882a593Smuzhiyun operation.params[0].value.a = key_id;
408*4882a593Smuzhiyun operation.params[1].tmpref.buffer = config;
409*4882a593Smuzhiyun operation.params[1].tmpref.size = sizeof(rk_cipher_config);
410*4882a593Smuzhiyun operation.params[2].value.a = src_mop.phys_addr;
411*4882a593Smuzhiyun operation.params[2].value.b = len_cipher;
412*4882a593Smuzhiyun operation.params[3].value.a = dst_mop.phys_addr;
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun operation.paramTypes = TEEC_PARAM_TYPES(TEEC_VALUE_INPUT,
415*4882a593Smuzhiyun TEEC_MEMREF_TEMP_INPUT,
416*4882a593Smuzhiyun TEEC_VALUE_INPUT,
417*4882a593Smuzhiyun TEEC_VALUE_INPUT);
418*4882a593Smuzhiyun
419*4882a593Smuzhiyun res = TEEC_InvokeCommand(&session, CRYPTO_SERVICE_CMD_OEM_OTP_KEY_PHYS_CIPHER,
420*4882a593Smuzhiyun &operation, &error_origin);
421*4882a593Smuzhiyun if (res != TEEC_SUCCESS) {
422*4882a593Smuzhiyun E_TRACE("InvokeCommand ERR! TEEC res= 0x%x, error_origin= 0x%x",
423*4882a593Smuzhiyun res, error_origin);
424*4882a593Smuzhiyun }
425*4882a593Smuzhiyun
426*4882a593Smuzhiyun TEEC_CloseSession(&session);
427*4882a593Smuzhiyun
428*4882a593Smuzhiyun out2:
429*4882a593Smuzhiyun TEEC_FinalizeContext(&contex);
430*4882a593Smuzhiyun
431*4882a593Smuzhiyun out1:
432*4882a593Smuzhiyun res = tee_to_crypto_code(res);
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun if (out_fd != in_fd)
435*4882a593Smuzhiyun rk_crypto_fd_ioctl(RIOCCRYPT_FD_UNMAP, &dst_mop);
436*4882a593Smuzhiyun
437*4882a593Smuzhiyun out:
438*4882a593Smuzhiyun rk_crypto_fd_ioctl(RIOCCRYPT_FD_UNMAP, &src_mop);
439*4882a593Smuzhiyun
440*4882a593Smuzhiyun return res;
441*4882a593Smuzhiyun }
442