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 */ 35 static TEE_Result dcp_generate_huk(struct tee_hw_unique_key *hwkey) 36 { 37 TEE_Result res = TEE_ERROR_GENERIC; 38 struct dcp_cipher_init init = { 39 .key_mode = DCP_OTP, 40 .mode = DCP_ECB, 41 .op = DCP_ENCRYPT, 42 }; 43 uint8_t content[DCP_AES128_BLOCK_SIZE] = { NB_ITERATION_HUK, 44 'h', 45 'u', 46 'k', 47 HUK_MESSAGE_NULL_BYTE, 48 'o', 49 'p', 50 't', 51 'e', 52 'e', 53 'o', 54 's', 55 'd', 56 'c', 57 'p', 58 HUK_SIZE_BITS }; 59 60 res = dcp_cmac(&init, content, DCP_AES128_BLOCK_SIZE, hwkey->data); 61 62 dcp_disable_unique_key(); 63 64 return res; 65 } 66 67 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) 68 { 69 TEE_Result ret = TEE_ERROR_GENERIC; 70 71 if (!hwkey) { 72 EMSG("HUK generation failed, hwkey structure is NULL"); 73 return TEE_ERROR_BAD_PARAMETERS; 74 } 75 76 ret = dcp_init(); 77 if (ret != TEE_SUCCESS) { 78 dcp_huk.state = DCP_HUK_ERROR; 79 return ret; 80 } 81 82 if (dcp_huk.state == DCP_HUK_EMPTY) { 83 ret = dcp_generate_huk(hwkey); 84 if (ret != TEE_SUCCESS) { 85 dcp_huk.state = DCP_HUK_ERROR; 86 } else { 87 memcpy(dcp_huk.data, hwkey->data, HW_UNIQUE_KEY_LENGTH); 88 dcp_huk.state = DCP_HUK_GENERATED; 89 } 90 } else if (dcp_huk.state == DCP_HUK_GENERATED) { 91 memcpy(hwkey->data, dcp_huk.data, HW_UNIQUE_KEY_LENGTH); 92 ret = TEE_SUCCESS; 93 } else { 94 ret = TEE_ERROR_GENERIC; 95 } 96 97 return ret; 98 } 99