1*ad194957SYi Chou // SPDX-License-Identifier: BSD-2-Clause
2*ad194957SYi Chou /*
3*ad194957SYi Chou * Copyright (c) 2023, The ChromiumOS Authors
4*ad194957SYi Chou */
5*ad194957SYi Chou
6*ad194957SYi Chou #include <kernel/tee_common_otp.h>
7*ad194957SYi Chou #include <libfdt.h>
8*ad194957SYi Chou #include <stdint.h>
9*ad194957SYi Chou #include <string.h>
10*ad194957SYi Chou
11*ad194957SYi Chou static uint8_t dt_huk[HW_UNIQUE_KEY_LENGTH];
12*ad194957SYi Chou static bool dt_huk_initialized;
13*ad194957SYi Chou
init_widevine_huk_dt_data(void)14*ad194957SYi Chou static TEE_Result init_widevine_huk_dt_data(void)
15*ad194957SYi Chou {
16*ad194957SYi Chou int node = 0;
17*ad194957SYi Chou int len = 0;
18*ad194957SYi Chou void *fdt = NULL;
19*ad194957SYi Chou const void *value = NULL;
20*ad194957SYi Chou
21*ad194957SYi Chou if (dt_huk_initialized)
22*ad194957SYi Chou return TEE_SUCCESS;
23*ad194957SYi Chou
24*ad194957SYi Chou fdt = get_secure_dt();
25*ad194957SYi Chou if (!fdt)
26*ad194957SYi Chou return TEE_ERROR_NO_DATA;
27*ad194957SYi Chou
28*ad194957SYi Chou node = fdt_path_offset(fdt, "/options/op-tee/widevine");
29*ad194957SYi Chou if (node < 0)
30*ad194957SYi Chou return TEE_ERROR_ITEM_NOT_FOUND;
31*ad194957SYi Chou
32*ad194957SYi Chou value = fdt_getprop(fdt, node, "op-tee,hardware-unique-key", &len);
33*ad194957SYi Chou if (!value)
34*ad194957SYi Chou return TEE_ERROR_ITEM_NOT_FOUND;
35*ad194957SYi Chou
36*ad194957SYi Chou if (len >= HW_UNIQUE_KEY_LENGTH)
37*ad194957SYi Chou len = HW_UNIQUE_KEY_LENGTH;
38*ad194957SYi Chou else
39*ad194957SYi Chou return TEE_ERROR_BAD_FORMAT;
40*ad194957SYi Chou
41*ad194957SYi Chou memcpy(dt_huk, value, len);
42*ad194957SYi Chou dt_huk_initialized = true;
43*ad194957SYi Chou
44*ad194957SYi Chou return TEE_SUCCESS;
45*ad194957SYi Chou }
46*ad194957SYi Chou
47*ad194957SYi Chou service_init(init_widevine_huk_dt_data);
48*ad194957SYi Chou
tee_otp_get_hw_unique_key(struct tee_hw_unique_key * hwkey)49*ad194957SYi Chou TEE_Result tee_otp_get_hw_unique_key(struct tee_hw_unique_key *hwkey)
50*ad194957SYi Chou {
51*ad194957SYi Chou TEE_Result result = TEE_SUCCESS;
52*ad194957SYi Chou
53*ad194957SYi Chou /*
54*ad194957SYi Chou * Ensure we get data from the DT, in case called before service_init()
55*ad194957SYi Chou * handler.
56*ad194957SYi Chou */
57*ad194957SYi Chou result = init_widevine_huk_dt_data();
58*ad194957SYi Chou if (result != TEE_SUCCESS)
59*ad194957SYi Chou return result;
60*ad194957SYi Chou
61*ad194957SYi Chou memcpy(hwkey->data, dt_huk, HW_UNIQUE_KEY_LENGTH);
62*ad194957SYi Chou
63*ad194957SYi Chou return TEE_SUCCESS;
64*ad194957SYi Chou }
65