xref: /optee_os/core/drivers/widevine_huk.c (revision ad194957b67062673816128f89eededb83f4be5b)
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