• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }