xref: /optee_os/core/kernel/huk_subkey.c (revision fa0525fa6a3046e03374f572141845c268058e61)
1*fa0525faSJens Wiklander // SPDX-License-Identifier: BSD-2-Clause
2*fa0525faSJens Wiklander /*
3*fa0525faSJens Wiklander  * Copyright (c) 2019, Linaro Limited
4*fa0525faSJens Wiklander  */
5*fa0525faSJens Wiklander 
6*fa0525faSJens Wiklander #include <crypto/crypto.h>
7*fa0525faSJens Wiklander #include <kernel/huk_subkey.h>
8*fa0525faSJens Wiklander #include <kernel/tee_common_otp.h>
9*fa0525faSJens Wiklander 
10*fa0525faSJens Wiklander static TEE_Result mac_usage(void *ctx, uint32_t usage)
11*fa0525faSJens Wiklander {
12*fa0525faSJens Wiklander 	return crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256,
13*fa0525faSJens Wiklander 				 (const void *)&usage, sizeof(usage));
14*fa0525faSJens Wiklander }
15*fa0525faSJens Wiklander 
16*fa0525faSJens Wiklander TEE_Result huk_subkey_derive(enum huk_subkey_usage usage,
17*fa0525faSJens Wiklander 			     const void *const_data, size_t const_data_len,
18*fa0525faSJens Wiklander 			     uint8_t *subkey, size_t subkey_len)
19*fa0525faSJens Wiklander {
20*fa0525faSJens Wiklander 	void *ctx = NULL;
21*fa0525faSJens Wiklander 	struct tee_hw_unique_key huk = { };
22*fa0525faSJens Wiklander 	TEE_Result res = TEE_SUCCESS;
23*fa0525faSJens Wiklander 
24*fa0525faSJens Wiklander 	if (subkey_len > HUK_SUBKEY_MAX_LEN)
25*fa0525faSJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
26*fa0525faSJens Wiklander 	if (!const_data && const_data_len)
27*fa0525faSJens Wiklander 		return TEE_ERROR_BAD_PARAMETERS;
28*fa0525faSJens Wiklander 
29*fa0525faSJens Wiklander 	res = crypto_mac_alloc_ctx(&ctx, TEE_ALG_HMAC_SHA256);
30*fa0525faSJens Wiklander 	if (res)
31*fa0525faSJens Wiklander 		return res;
32*fa0525faSJens Wiklander 
33*fa0525faSJens Wiklander 	res = tee_otp_get_hw_unique_key(&huk);
34*fa0525faSJens Wiklander 	if (res)
35*fa0525faSJens Wiklander 		goto out;
36*fa0525faSJens Wiklander 
37*fa0525faSJens Wiklander 	res = crypto_mac_init(ctx, TEE_ALG_HMAC_SHA256, huk.data,
38*fa0525faSJens Wiklander 			      sizeof(huk.data));
39*fa0525faSJens Wiklander 	if (res)
40*fa0525faSJens Wiklander 		goto out;
41*fa0525faSJens Wiklander 
42*fa0525faSJens Wiklander 	res = mac_usage(ctx, usage);
43*fa0525faSJens Wiklander 	if (res)
44*fa0525faSJens Wiklander 		goto out;
45*fa0525faSJens Wiklander 
46*fa0525faSJens Wiklander 	if (const_data) {
47*fa0525faSJens Wiklander 		res = crypto_mac_update(ctx, TEE_ALG_HMAC_SHA256, const_data,
48*fa0525faSJens Wiklander 					const_data_len);
49*fa0525faSJens Wiklander 		if (res)
50*fa0525faSJens Wiklander 			goto out;
51*fa0525faSJens Wiklander 	}
52*fa0525faSJens Wiklander 
53*fa0525faSJens Wiklander 	res = crypto_mac_final(ctx, TEE_ALG_HMAC_SHA256, subkey, subkey_len);
54*fa0525faSJens Wiklander out:
55*fa0525faSJens Wiklander 	if (res)
56*fa0525faSJens Wiklander 		memset(subkey, 0, subkey_len);
57*fa0525faSJens Wiklander 	memset(&huk, 0, sizeof(huk));
58*fa0525faSJens Wiklander 	crypto_mac_free_ctx(ctx, TEE_ALG_HMAC_SHA256);
59*fa0525faSJens Wiklander 	return res;
60*fa0525faSJens Wiklander }
61