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