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