1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * Copyright (c) 2023, Microchip 4 */ 5 6 #include <drivers/nvmem.h> 7 #include <io.h> 8 #include <kernel/dt.h> 9 #include <kernel/huk_subkey.h> 10 #include <kernel/tee_common_otp.h> 11 #include <libfdt.h> 12 #include <malloc.h> 13 #include <tee_api_defines.h> 14 #include <tee_api_types.h> 15 #include <trace.h> 16 #include <types_ext.h> 17 18 static uint8_t *huk; 19 20 TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey) 21 { 22 if (!huk) { 23 EMSG("no HUK"); 24 return TEE_ERROR_GENERIC; 25 } 26 27 memcpy(hwkey->data, huk, HW_UNIQUE_KEY_LENGTH); 28 29 return TEE_SUCCESS; 30 } 31 32 static TEE_Result nvmem_huk_probe(const void *fdt, int node, 33 const void *compat_data __unused) 34 { 35 TEE_Result res = TEE_ERROR_GENERIC; 36 struct nvmem_cell *cell = NULL; 37 uint8_t *data = NULL; 38 39 res = nvmem_get_cell_by_name(fdt, node, "hw_unique_key", &cell); 40 if (res) 41 return res; 42 43 if (cell->len < HW_UNIQUE_KEY_LENGTH) { 44 EMSG("cell %s is too small", fdt_get_name(fdt, node, NULL)); 45 nvmem_put_cell(cell); 46 return TEE_ERROR_GENERIC; 47 } 48 49 if (cell->len > HW_UNIQUE_KEY_LENGTH) 50 IMSG("nvmem_huk: HUK truncated from %zu to %u bytes", 51 cell->len, HW_UNIQUE_KEY_LENGTH); 52 53 res = nvmem_cell_malloc_and_read(cell, &data); 54 if (!res) 55 huk = data; 56 57 nvmem_put_cell(cell); 58 59 return res; 60 } 61 62 static const struct dt_device_match nvmem_huk_match_table[] = { 63 { .compatible = "optee,nvmem-huk" }, 64 { } 65 }; 66 67 DEFINE_DT_DRIVER(nvmem_huk_dt_driver) = { 68 .name = "nvmem_huk", 69 .type = DT_DRIVER_NVMEM, 70 .match_table = nvmem_huk_match_table, 71 .probe = nvmem_huk_probe, 72 }; 73