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