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 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 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