1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3 * Copyright 2020 NXP
4 */
5
6 #include <drivers/imx/dcp.h>
7 #include <kernel/tee_common_otp.h>
8 #include <local.h>
9 #include <trace.h>
10
11 #define HUK_MESSAGE_NULL_BYTE 0
12 #define NB_ITERATION_HUK 1
13 #define HUK_SIZE_BITS 128
14
15 /* State of the generated HUK */
16 enum dcp_huk_state {
17 DCP_HUK_EMPTY = 0,
18 DCP_HUK_GENERATED,
19 DCP_HUK_ERROR,
20 };
21
22 /* Information about HUK */
23 static struct {
24 enum dcp_huk_state state;
25 uint8_t data[HW_UNIQUE_KEY_LENGTH];
26 } dcp_huk = { .state = DCP_HUK_EMPTY };
27
28 /*
29 * Generate Hardware Unique Key using the Data Co-Processor (DCP) AES128-CMAC
30 * cryptographic operation
31 * Follow dcp_aes_cmac() message format
32 *
33 * @hwkey [out] Hardware Unique Key private data
34 */
dcp_generate_huk(struct tee_hw_unique_key * hwkey)35 static TEE_Result dcp_generate_huk(struct tee_hw_unique_key *hwkey)
36 {
37 struct dcp_cipher_init init = {
38 .key_mode = DCP_OTP,
39 .mode = DCP_ECB,
40 .op = DCP_ENCRYPT,
41 };
42 uint8_t content[DCP_AES128_BLOCK_SIZE] = { NB_ITERATION_HUK,
43 'h',
44 'u',
45 'k',
46 HUK_MESSAGE_NULL_BYTE,
47 'o',
48 'p',
49 't',
50 'e',
51 'e',
52 'o',
53 's',
54 'd',
55 'c',
56 'p',
57 HUK_SIZE_BITS };
58
59 return dcp_cmac(&init, content, DCP_AES128_BLOCK_SIZE, hwkey->data);
60 }
61
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)62 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
63 {
64 TEE_Result ret = TEE_ERROR_GENERIC;
65
66 if (!hwkey || !hwkey->data) {
67 EMSG("HUK generation failed, hwkey structure is NULL");
68 return TEE_ERROR_BAD_PARAMETERS;
69 }
70
71 ret = dcp_init();
72 if (ret != TEE_SUCCESS) {
73 dcp_huk.state = DCP_HUK_ERROR;
74 return ret;
75 }
76
77 if (dcp_huk.state == DCP_HUK_EMPTY) {
78 ret = dcp_generate_huk(hwkey);
79 if (ret != TEE_SUCCESS) {
80 dcp_huk.state = DCP_HUK_ERROR;
81 } else {
82 memcpy(dcp_huk.data, hwkey->data, HW_UNIQUE_KEY_LENGTH);
83 dcp_huk.state = DCP_HUK_GENERATED;
84 }
85 } else if (dcp_huk.state == DCP_HUK_GENERATED) {
86 memcpy(hwkey->data, dcp_huk.data, HW_UNIQUE_KEY_LENGTH);
87 ret = TEE_SUCCESS;
88 } else {
89 ret = TEE_ERROR_GENERIC;
90 }
91
92 return ret;
93 }
94