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