1 /**
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 *
15 * Description: hal rkp. \n
16 *
17 * History: \n
18 * 2023-03-22, Create file. \n
19 */
20 #include "hal_rkp.h"
21 #include "hal_rkp_reg.h"
22 #include "crypto_drv_common.h"
23 #include "crypto_common_macro.h"
24
hal_rkp_lock(td_void)25 td_s32 hal_rkp_lock(td_void)
26 {
27 td_u32 i = 0;
28 rkp_lock lock_val = {0};
29 td_u32 rkp_config_val = RKP_LOCK_CPU_IDLE;
30 crypto_cpu_type cpu_type = crypto_get_cpu_type();
31 switch (cpu_type) {
32 case CRYPTO_CPU_TYPE_ACPU:
33 rkp_config_val = RKP_LOCK_CPU_REE;
34 break;
35 case CRYPTO_CPU_TYPE_SCPU:
36 rkp_config_val = RKP_LOCK_CPU_TEE;
37 break;
38 default:
39 rkp_config_val = RKP_LOCK_CPU_IDLE;
40 crypto_log_err("invalid cpu_type\n");
41 return TD_FAILURE;
42 }
43
44 for (i = 0; i < RKP_LOCK_TIMEOUT_IN_US; i++) {
45 km_reg_write(RKP_LOCK, rkp_config_val);
46 lock_val.u32 = km_reg_read(RKP_LOCK);
47 if (lock_val.bits.km_lock_status == rkp_config_val) {
48 break;
49 }
50 crypto_udelay(1);
51 }
52
53 if (i >= RKP_LOCK_TIMEOUT_IN_US) {
54 crypto_log_err("drv_rkp_lock busy.\n");
55 return TD_FAILURE;
56 }
57
58 return TD_SUCCESS;
59 }
60
hal_rkp_unlock(void)61 td_s32 hal_rkp_unlock(void)
62 {
63 km_reg_write(RKP_LOCK, RKP_LOCK_CPU_IDLE);
64 return TD_SUCCESS;
65 }
66
67 #define DEOB_UPDATE_KEY_SEL_MRK1 0
68 #define DEOB_UPDATE_KEY_SEL_USK 1
69 #define DEOB_UPDATE_KEY_SEL_RUSK 2
70
71 #define DEOB_UPDATE_ALG_SEL_AES 0
72 #define DEOB_UPDATE_ALG_SEL_SM4 1
73
74 #define RKP_DEOB_UPDATE_TIMEOUT_IN_US 1000000
75
hal_rkp_deob_update(crypto_kdf_otp_key otp_key,crypto_kdf_update_alg alg)76 td_s32 hal_rkp_deob_update(crypto_kdf_otp_key otp_key, crypto_kdf_update_alg alg)
77 {
78 volatile td_s32 ret = TD_FAILURE;
79 td_u8 deob_key_reg_val = 0;
80 td_u8 deob_alg_reg_val = 0;
81 rkp_deob_cfg deob_cfg = { 0 };
82
83 if (otp_key == CRYPTO_KDF_OTP_KEY_MRK1) {
84 deob_key_reg_val = DEOB_UPDATE_KEY_SEL_MRK1;
85 } else if (otp_key == CRYPTO_KDF_OTP_KEY_USK) {
86 deob_key_reg_val = DEOB_UPDATE_KEY_SEL_USK;
87 } else if (otp_key == CRYPTO_KDF_OTP_KEY_RUSK) {
88 deob_key_reg_val = DEOB_UPDATE_KEY_SEL_RUSK;
89 } else {
90 crypto_log_err("invalid otp_key\n");
91 return TD_FAILURE;
92 }
93
94 if (alg == CRYPTO_KDF_UPDATE_ALG_AES) {
95 deob_alg_reg_val = DEOB_UPDATE_ALG_SEL_AES;
96 } else if (alg == CRYPTO_KDF_UPDATE_ALG_SM4) {
97 deob_alg_reg_val = DEOB_UPDATE_ALG_SEL_SM4;
98 } else {
99 crypto_log_err("invalid alg\n");
100 return TD_FAILURE;
101 }
102
103 deob_cfg.u32 = km_reg_read(RKP_DEOB_CFG);
104 deob_cfg.bits.deob_update_alg_sel = deob_alg_reg_val;
105 deob_cfg.bits.deob_update_sel = deob_key_reg_val;
106 deob_cfg.bits.deob_update_req = 0x1; /* start calculation */
107 km_reg_write(RKP_DEOB_CFG, deob_cfg.u32);
108
109 ret = hal_rkp_deob_wait_done();
110 if (ret != TD_SUCCESS) {
111 crypto_log_err("hal_rkp_deob_wait_done failed\n");
112 ret = TD_FAILURE;
113 }
114
115 return ret;
116 }
117
118 #define KDF_MAX_VAL_LENGTH 64
119
hal_rkp_kdf_set_val(const td_u8 * kdf_val,td_u32 val_length)120 td_s32 hal_rkp_kdf_set_val(const td_u8 *kdf_val, td_u32 val_length)
121 {
122 td_u32 i;
123 const td_u32 *kdf_val_word = TD_NULL;
124
125 crypto_chk_return(kdf_val == TD_NULL, TD_FAILURE, "kdf_val is NULL\n");
126 crypto_chk_return(val_length > KDF_MAX_VAL_LENGTH, TD_FAILURE, "val_length is too long\n");
127 crypto_chk_return((val_length % CRYPTO_WORD_WIDTH) != 0, TD_FAILURE, "invalid val_length\n");
128
129 kdf_val_word = (const td_u32 *)kdf_val;
130 for (i = 0; i < val_length / CRYPTO_WORD_WIDTH; i++) {
131 km_reg_write(RKP_PBKDF2_VAL(i), kdf_val_word[i]);
132 }
133 return TD_SUCCESS;
134 }
135
136 #define KDF_PADDING_VAL_LEN 64
hal_rkp_kdf_get_val(td_u8 * kdf_val,td_u32 val_length)137 td_s32 hal_rkp_kdf_get_val(td_u8 *kdf_val, td_u32 val_length)
138 {
139 td_u32 i;
140 td_u32 *kdf_val_word = TD_NULL;
141
142 crypto_chk_return(kdf_val == TD_NULL, TD_FAILURE, "kdf_val is NULL\n");
143 crypto_chk_return(val_length > KDF_MAX_VAL_LENGTH, TD_FAILURE, "val_length is too long\n");
144 crypto_chk_return((val_length % CRYPTO_WORD_WIDTH) != 0, TD_FAILURE, "invalid val_length\n");
145
146 kdf_val_word = (td_u32 *)kdf_val;
147 for (i = 0; i < val_length / CRYPTO_WORD_WIDTH; i++) {
148 kdf_val_word[i] = km_reg_read(RKP_PBKDF2_VAL(i));
149 }
150 return TD_SUCCESS;
151 }
152
153 #define KDF_PADDING_SALT_LEN 128
hal_rkp_kdf_set_padding_salt(const td_u8 * padding_salt,td_u32 salt_length)154 td_s32 hal_rkp_kdf_set_padding_salt(const td_u8 *padding_salt, td_u32 salt_length)
155 {
156 td_u32 i;
157 const td_u32 *salt_word = TD_NULL;
158
159 crypto_chk_return(padding_salt == TD_NULL, TD_FAILURE, "padding_salt is NULL\n");
160 crypto_chk_return(salt_length != KDF_PADDING_SALT_LEN, TD_FAILURE, "invalid salt_length\n");
161
162 salt_word = (const td_u32 *)padding_salt;
163 for (i = 0; i < salt_length / CRYPTO_WORD_WIDTH; i++) {
164 km_reg_write(RKP_PBKDF2_DATA(i), salt_word[i]);
165 }
166
167 return TD_SUCCESS;
168 }
169
170 #define KDF_PADDING_KEY_LEN 128
hal_rkp_kdf_set_padding_key(const td_u8 * padding_key,td_u32 key_length)171 td_s32 hal_rkp_kdf_set_padding_key(const td_u8 *padding_key, td_u32 key_length)
172 {
173 td_u32 i;
174 const td_u32 *key_word = TD_NULL;
175
176 crypto_chk_return(padding_key == TD_NULL, TD_FAILURE, "padding_key is NULL\n");
177 crypto_chk_return(key_length != KDF_PADDING_KEY_LEN, TD_FAILURE, "invalid key_length\n");
178
179 key_word = (const td_u32 *)padding_key;
180 for (i = 0; i < key_length / CRYPTO_WORD_WIDTH; i++) {
181 km_reg_write(RKP_PBKDF2_KEY(i), key_word[i]);
182 }
183
184 return TD_SUCCESS;
185 }
186
187 /*
188 pbkdf2_key_config
189 */
190 #define KDF_SW_GEN 3
191
192 #define PBKDF2_ALG_SEL_SHA1 1
193 #define PBKDF2_ALG_SEL_SHA256 0
194 #define PBKDF2_ALG_SEL_SHA384 3
195 #define PBKDF2_ALG_SEL_SHA512 4
196 #define PBKDF2_ALG_SEL_SM3 5
197 static crypto_table_item g_rkp_alg_sel_table[] = {
198 {
199 .index = CRYPTO_KDF_SW_ALG_SHA1, .value = PBKDF2_ALG_SEL_SHA1
200 },
201 {
202 .index = CRYPTO_KDF_SW_ALG_SHA256, .value = PBKDF2_ALG_SEL_SHA256
203 },
204 {
205 .index = CRYPTO_KDF_SW_ALG_SHA384, .value = PBKDF2_ALG_SEL_SHA384
206 },
207 {
208 .index = CRYPTO_KDF_SW_ALG_SHA512, .value = PBKDF2_ALG_SEL_SHA512
209 },
210 {
211 .index = CRYPTO_KDF_SW_ALG_SM3, .value = PBKDF2_ALG_SEL_SM3
212 },
213 };
214
hal_rkp_kdf_sw_start(crypto_kdf_sw_alg sw_alg,td_u32 count,td_bool is_wait)215 td_s32 hal_rkp_kdf_sw_start(crypto_kdf_sw_alg sw_alg, td_u32 count, td_bool is_wait)
216 {
217 rkp_cmd_cfg cfgval = {0};
218 td_u32 alg_reg_val = 0;
219 volatile td_s32 ret = TD_FAILURE;
220
221 crypto_unused(is_wait);
222
223 /* get alg_sel. */
224 ret = crypto_get_value_by_index(g_rkp_alg_sel_table, crypto_array_size(g_rkp_alg_sel_table),
225 sw_alg, &alg_reg_val);
226 crypto_chk_return(ret != TD_SUCCESS, ret, "get alg_sel failed\n");
227
228 cfgval.u32 = km_reg_read(RKP_CMD_CFG);
229 cfgval.bits.rkp_pbkdf_calc_time = count;
230 cfgval.bits.pbkdf2_alg_sel_cfg = alg_reg_val;
231 cfgval.bits.pbkdf2_key_sel_cfg = KDF_SW_GEN;
232 cfgval.bits.sw_calc_req = 0x1; /* start calculation */
233 km_reg_write(RKP_CMD_CFG, cfgval.u32);
234
235 return TD_SUCCESS;
236 }
237
hal_rkp_kdf_wait_done(td_void)238 td_s32 hal_rkp_kdf_wait_done(td_void)
239 {
240 td_u32 i;
241 volatile td_s32 ret = TD_FAILURE;
242 td_u32 kdf_err = 0;
243 rkp_cmd_cfg cmd_cfg = { 0 };
244
245 for (i = 0; i < RKP_WAIT_TIMEOUT_IN_US; ++i) {
246 cmd_cfg.u32 = km_reg_read(RKP_CMD_CFG);
247 if (cmd_cfg.bits.sw_calc_req == 0x0) {
248 km_reg_write(RKP_RAW_INT, 0x1);
249 break;
250 }
251 crypto_udelay(1);
252 }
253 if (i >= RKP_WAIT_TIMEOUT_IN_US) {
254 ret = TD_FAILURE;
255 } else {
256 ret = TD_SUCCESS;
257 }
258
259 /* check kdf err. */
260 kdf_err = km_reg_read(KDF_ERROR);
261 if (kdf_err != 0) {
262 crypto_log_err("kdf_err is 0x%x\n", kdf_err);
263 ret = TD_FAILURE;
264 }
265
266 return ret;
267 }
268
hal_rkp_deob_wait_done(td_void)269 td_s32 hal_rkp_deob_wait_done(td_void)
270 {
271 td_u32 i;
272 volatile td_s32 ret = TD_FAILURE;
273 td_u32 deob_err = 0;
274 rkp_deob_cfg deob_cfg = { 0 };
275
276 for (i = 0; i < RKP_WAIT_TIMEOUT_IN_US; ++i) {
277 deob_cfg.u32 = km_reg_read(RKP_DEOB_CFG);
278 if (deob_cfg.bits.deob_update_req == 0x0) {
279 break;
280 }
281 crypto_udelay(1);
282 }
283 if (i >= RKP_WAIT_TIMEOUT_IN_US) {
284 ret = TD_FAILURE;
285 } else {
286 ret = TD_SUCCESS;
287 }
288
289 /* check deob err. */
290 deob_err = km_reg_read(DEOB_ERROR);
291 if (deob_err != 0) {
292 crypto_log_err("deob_err is 0x%x\n", deob_err);
293 ret = TD_FAILURE;
294 }
295
296 return ret;
297 }
298
299 #define PBKDF2_KEY_SEL_ODRK1 8
300 #define PBKDF2_KEY_SEL_ABRK_REE 20
301 #define PBKDF2_KEY_SEL_RDRK_REE 22
302 static crypto_table_item g_rkp_key_sel_table[] = {
303 {
304 .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, .value = PBKDF2_KEY_SEL_ODRK1
305 },
306 {
307 .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, .value = PBKDF2_KEY_SEL_ABRK_REE
308 },
309 {
310 .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, .value = PBKDF2_KEY_SEL_RDRK_REE
311 },
312 };
313
314 #define PBKDF2_KEY_LEN_128BIT 1
315 #define PBKDF2_KEY_LEN_192BIT 2
316 #define PBKDF2_KEY_LEN_256BIT 3
317 static crypto_table_item g_rkp_key_len_table[] = {
318 {
319 .index = CRYPTO_KDF_HARD_KEY_SIZE_128BIT, .value = PBKDF2_KEY_LEN_128BIT
320 },
321 {
322 .index = CRYPTO_KDF_HARD_KEY_SIZE_192BIT, .value = PBKDF2_KEY_LEN_192BIT
323 },
324 {
325 .index = CRYPTO_KDF_HARD_KEY_SIZE_256BIT, .value = PBKDF2_KEY_LEN_256BIT
326 },
327 };
328
329 #define KDF_HARD_SALT_LEN 28
330
331 #define PBKDF2_RDRK_REE_ONEWAY_OFFSET 0
332 #define PBKDF2_ABRK_REE_ONEWAY_OFFSET 1
333 #define PBKDF2_ODRK1_ONEWAY_OFFSET 2
334 static crypto_table_item g_rkp_oneway_offset_table[] = {
335 {
336 .index = CRYPTO_KDF_HARD_KEY_TYPE_RDRK_REE, .value = PBKDF2_RDRK_REE_ONEWAY_OFFSET
337 },
338 {
339 .index = CRYPTO_KDF_HARD_KEY_TYPE_ABRK_REE, .value = PBKDF2_ABRK_REE_ONEWAY_OFFSET
340 },
341 {
342 .index = CRYPTO_KDF_HARD_KEY_TYPE_ODRK1, .value = PBKDF2_ODRK1_ONEWAY_OFFSET
343 },
344 };
345
346 static crypto_table_item g_rkp_hard_alg_sel_table[] = {
347 {
348 .index = CRYPTO_KDF_HARD_ALG_SHA256, .value = PBKDF2_ALG_SEL_SHA256
349 },
350 {
351 .index = CRYPTO_KDF_HARD_ALG_SM3, .value = PBKDF2_ALG_SEL_SM3
352 },
353 };
hal_rkp_kdf_hard_calculation(const crypto_kdf_hard_calc_param * param)354 td_s32 hal_rkp_kdf_hard_calculation(const crypto_kdf_hard_calc_param *param)
355 {
356 volatile td_s32 ret = TD_FAILURE;
357 td_u32 i;
358 td_u32 key_sel_reg_val = 0;
359 td_u32 alg_reg_val = 0;
360 td_u32 key_len_reg_val = 0;
361 rkp_oneway_ree onewayval = {0};
362 rkp_cmd_cfg cfgval = {0};
363 td_u32 oneway_offset = 0;
364 const td_u32 *salt_word = TD_NULL;
365
366 crypto_chk_return(param == TD_NULL, TD_FAILURE, "param is NULL\n");
367 crypto_chk_return(param->salt == TD_NULL, TD_FAILURE, "param->salt is NULL\n");
368 crypto_chk_return(param->salt_length != KDF_HARD_SALT_LEN, TD_FAILURE, "invalid param->salt_length\n");
369 crypto_chk_return(param->hard_alg != CRYPTO_KDF_HARD_ALG_SHA256 && param->hard_alg != CRYPTO_KDF_HARD_ALG_SM3,
370 TD_FAILURE, "invalid param->hard->alg\n");
371
372 salt_word = (const td_u32 *)param->salt;
373 /* get key_sel. */
374 ret = crypto_get_value_by_index(g_rkp_key_sel_table, crypto_array_size(g_rkp_key_sel_table),
375 param->hard_key_type, &key_sel_reg_val);
376 crypto_chk_return(ret != TD_SUCCESS, ret, "get key_sel failed\n");
377 /* get oneway_offset. */
378 ret = crypto_get_value_by_index(g_rkp_oneway_offset_table, crypto_array_size(g_rkp_oneway_offset_table),
379 param->hard_key_type, &oneway_offset);
380 crypto_chk_return(ret != TD_SUCCESS, ret, "get oneway_offset failed\n");
381
382 /* get alg_sel. */
383 ret = crypto_get_value_by_index(g_rkp_hard_alg_sel_table, crypto_array_size(g_rkp_hard_alg_sel_table),
384 param->hard_alg, &alg_reg_val);
385 crypto_chk_return(ret != TD_SUCCESS, ret, "get alg_sel failed\n");
386
387 /* get key_len. */
388 ret = crypto_get_value_by_index(g_rkp_key_len_table, crypto_array_size(g_rkp_key_len_table),
389 param->hard_key_size, &key_len_reg_val);
390 crypto_chk_return(ret != TD_SUCCESS, ret, "get key_len failed\n");
391
392 /* config oneway. */
393 onewayval.u32 = km_reg_read(RKP_ONEWAY);
394 onewayval.u32 |= (param->is_oneway << oneway_offset);
395 km_reg_write(RKP_ONEWAY, onewayval.u32);
396
397 /* config salt. */
398 for (i = 0; i < param->salt_length / CRYPTO_WORD_WIDTH; i++) {
399 km_reg_write(RKP_SALT(i), salt_word[i]);
400 }
401
402 /* config rkp_cmd_cfg. */
403 cfgval.u32 = km_reg_read(RKP_CMD_CFG);
404 cfgval.bits.pbkdf2_key_len = key_len_reg_val;
405 cfgval.bits.pbkdf2_alg_sel_cfg = alg_reg_val;
406 cfgval.bits.pbkdf2_key_sel_cfg = key_sel_reg_val;
407
408 cfgval.bits.sw_calc_req = 0x1; /* start kdf calculation */
409 km_reg_write(RKP_CMD_CFG, cfgval.u32);
410
411 ret = hal_rkp_kdf_wait_done();
412 crypto_chk_return(ret != TD_SUCCESS, ret, "hal_rkp_kdf_wait_done failed\n");
413
414 return ret;
415 }
416
hal_rkp_clear_reg_key(td_void)417 td_s32 hal_rkp_clear_reg_key(td_void)
418 {
419 td_u32 i = 0;
420 td_u32 clear_key_val = 0;
421
422 /* get random key. */
423 for (i = 0; i < KDF_PADDING_KEY_LEN / CRYPTO_WORD_WIDTH; i++) {
424 km_reg_write(RKP_PBKDF2_KEY(i), clear_key_val);
425 }
426
427 for (i = 0; i < KDF_PADDING_SALT_LEN / CRYPTO_WORD_WIDTH; i++) {
428 km_reg_write(RKP_PBKDF2_DATA(i), clear_key_val);
429 }
430
431 for (i = 0; i < KDF_PADDING_VAL_LEN / CRYPTO_WORD_WIDTH; i++) {
432 km_reg_write(RKP_PBKDF2_VAL(i), clear_key_val);
433 }
434 return TD_SUCCESS;
435 }
436
hal_rkp_debug(td_void)437 td_void hal_rkp_debug(td_void)
438 {
439 td_u32 i;
440 td_u32 reg_value = 0;
441 rkp_cmd_cfg cmd_cfg;
442
443 crypto_unused(cmd_cfg);
444 /* RKP_LOCK. */
445 reg_value = km_reg_read(RKP_LOCK);
446 if (reg_value == RKP_LOCK_CPU_REE) {
447 crypto_print("RKP locked by REE CPU!\r\n");
448 } else if (reg_value == RKP_LOCK_CPU_TEE) {
449 crypto_print("RKP locked by TEE CPU!\r\n");
450 }
451
452 /* RKP_CMD_CFG. */
453 cmd_cfg.u32 = km_reg_read(RKP_CMD_CFG);
454 crypto_print("RKP_CMD_CFG: sw_calc_req is 0x%x\r\n", cmd_cfg.bits.sw_calc_req);
455 crypto_print("RKP_CMD_CFG: pbkdf2_alg_sel_cfg is 0x%x\r\n", cmd_cfg.bits.pbkdf2_alg_sel_cfg);
456 crypto_print("RKP_CMD_CFG: pbkdf2_key_sel_cfg is 0x%x\r\n", cmd_cfg.bits.pbkdf2_key_sel_cfg);
457 crypto_print("RKP_CMD_CFG: pbkdf2_key_len is 0x%x\r\n", cmd_cfg.bits.pbkdf2_key_len);
458 crypto_print("RKP_CMD_CFG: rkp_pbkdf_calc_time is 0x%x\r\n", cmd_cfg.bits.rkp_pbkdf_calc_time);
459
460 /* KDF_ERROR. */
461 crypto_print("KDF_ERROR is 0x%x\r\n", km_reg_read(KDF_ERROR));
462 /* RKP_RAW_INT */
463 crypto_print("RKP_RAW_INT is 0x%x\r\n", km_reg_read(RKP_RAW_INT));
464 /* RKP_INT_ENABLE */
465 crypto_print("RKP_INT_ENABLE is 0x%x\r\n", km_reg_read(RKP_INT_ENABLE));
466 /* RKP_INT */
467 crypto_print("RKP_INT is 0x%x\r\n", km_reg_read(RKP_INT));
468 /* RKP_DEOB_CFG */
469 crypto_print("RKP_DEOB_CFG is 0x%x\r\n", km_reg_read(RKP_DEOB_CFG));
470 /* DEOB_ERROR */
471 crypto_print("DEOB_ERROR is 0x%x\r\n", km_reg_read(DEOB_ERROR));
472 /* RK_RDY */
473 crypto_print("RK_RDY is 0x%x\r\n", km_reg_read(RK_RDY));
474 /* RKP_SALT */
475 for (i = 0; i < KDF_HARD_SALT_LEN / CRYPTO_WORD_WIDTH; i++) {
476 crypto_print("RKP_SALT is 0x%x\r\n", km_reg_read(RKP_SALT(i)));
477 }
478 /* RKP_ONEWAY */
479 crypto_print("RKP_ONEWAY is 0x%x\r\n", km_reg_read(RKP_ONEWAY));
480 }