131a85db8SThomas Perrot // SPDX-License-Identifier: BSD-2-Clause
231a85db8SThomas Perrot /*
331a85db8SThomas Perrot * Copyright (c) 2023, Microchip
431a85db8SThomas Perrot */
531a85db8SThomas Perrot
631a85db8SThomas Perrot #include <drivers/nvmem.h>
731a85db8SThomas Perrot #include <io.h>
831a85db8SThomas Perrot #include <kernel/dt.h>
931a85db8SThomas Perrot #include <kernel/huk_subkey.h>
1031a85db8SThomas Perrot #include <kernel/tee_common_otp.h>
1131a85db8SThomas Perrot #include <malloc.h>
1231a85db8SThomas Perrot #include <tee_api_defines.h>
1331a85db8SThomas Perrot #include <tee_api_types.h>
1431a85db8SThomas Perrot #include <types_ext.h>
1531a85db8SThomas Perrot
1631a85db8SThomas Perrot static uint8_t *die_id;
1731a85db8SThomas Perrot static size_t die_id_len;
1831a85db8SThomas Perrot
tee_otp_get_die_id(uint8_t * buffer,size_t len)1931a85db8SThomas Perrot int tee_otp_get_die_id(uint8_t *buffer, size_t len)
2031a85db8SThomas Perrot {
2131a85db8SThomas Perrot if (!die_id) {
2231a85db8SThomas Perrot if (huk_subkey_derive(HUK_SUBKEY_DIE_ID, NULL, 0, buffer, len))
2331a85db8SThomas Perrot return -1;
2431a85db8SThomas Perrot return 0;
2531a85db8SThomas Perrot }
2631a85db8SThomas Perrot
2731a85db8SThomas Perrot memcpy(buffer, die_id, MIN(die_id_len, len));
2831a85db8SThomas Perrot
2931a85db8SThomas Perrot return 0;
3031a85db8SThomas Perrot }
3131a85db8SThomas Perrot
nvmem_die_id_probe(const void * fdt,int node,const void * compat_data __unused)3231a85db8SThomas Perrot static TEE_Result nvmem_die_id_probe(const void *fdt, int node,
3331a85db8SThomas Perrot const void *compat_data __unused)
3431a85db8SThomas Perrot {
3531a85db8SThomas Perrot TEE_Result res = TEE_ERROR_GENERIC;
3631a85db8SThomas Perrot struct nvmem_cell *cell = NULL;
3731a85db8SThomas Perrot uint8_t *data = NULL;
3831a85db8SThomas Perrot
3931a85db8SThomas Perrot res = nvmem_get_cell_by_name(fdt, node, "die_id", &cell);
4031a85db8SThomas Perrot if (res)
4131a85db8SThomas Perrot return res;
4231a85db8SThomas Perrot
4331a85db8SThomas Perrot res = nvmem_cell_malloc_and_read(cell, &data);
44*7e619050SThomas Perrot if (!res) {
4531a85db8SThomas Perrot die_id = data;
46*7e619050SThomas Perrot die_id_len = cell->len;
47*7e619050SThomas Perrot }
4831a85db8SThomas Perrot
4931a85db8SThomas Perrot nvmem_put_cell(cell);
5031a85db8SThomas Perrot
5131a85db8SThomas Perrot return res;
5231a85db8SThomas Perrot }
5331a85db8SThomas Perrot
5431a85db8SThomas Perrot static const struct dt_device_match nvmem_die_id_match_table[] = {
5531a85db8SThomas Perrot { .compatible = "optee,nvmem-die-id" },
5631a85db8SThomas Perrot { }
5731a85db8SThomas Perrot };
5831a85db8SThomas Perrot
5931a85db8SThomas Perrot DEFINE_DT_DRIVER(nvmem_die_id_dt_driver) = {
6031a85db8SThomas Perrot .name = "nvmem_die_id_key",
6131a85db8SThomas Perrot .type = DT_DRIVER_NVMEM,
6231a85db8SThomas Perrot .match_table = nvmem_die_id_match_table,
6331a85db8SThomas Perrot .probe = nvmem_die_id_probe,
6431a85db8SThomas Perrot };
65