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
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)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
nvmem_huk_probe(const void * fdt,int node,const void * compat_data __unused)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