blob: 1171e22217e500f8ae049bbefde02441da04c9ff [file] [log] [blame]
// SPDX-License-Identifier: BSD-2-Clause
/*
* Copyright (c) 2020 Huawei Technologies Co., Ltd
*/
#include <crypto/crypto.h>
#include <io.h>
#include <stdint.h>
#include <tee_api_types.h>
#include <unistd.h>
#include <utee_defines.h>
#include "acipher_helpers.h"
/*
* GM/T 0003.1‒2012 Part 4 Sections 5.4.2 and 5.4.3
* GM/T 0003.1‒2012 Part 5 Sections 5.4.2 and 5.4.3
* Key derivation function based on the SM3 hash function
*/
TEE_Result sm2_kdf(const uint8_t *Z, size_t Z_len, uint8_t *t, size_t tlen)
{
TEE_Result res = TEE_SUCCESS;
size_t remain = tlen;
uint32_t count = 1;
uint32_t be_count = 0;
void *ctx = NULL;
uint8_t *out = t;
res = crypto_hash_alloc_ctx(&ctx, TEE_ALG_SM3);
if (res)
return res;
while (remain) {
uint8_t tmp[TEE_SM3_HASH_SIZE] = { };
uint8_t *buf = NULL;
if (remain >= TEE_SM3_HASH_SIZE)
buf = out;
else
buf = tmp;
put_be32(&be_count, count);
res = crypto_hash_init(ctx);
if (res)
goto out;
res = crypto_hash_update(ctx, Z, Z_len);
if (res)
goto out;
res = crypto_hash_update(ctx, (const uint8_t *)&be_count,
sizeof(be_count));
if (res)
goto out;
res = crypto_hash_final(ctx, buf, TEE_SM3_HASH_SIZE);
if (res)
goto out;
if (remain < TEE_SM3_HASH_SIZE) {
memcpy(out, tmp, remain);
break;
}
out += TEE_SM3_HASH_SIZE;
remain -= TEE_SM3_HASH_SIZE;
count++;
}
out:
crypto_hash_free_ctx(ctx);
return res;
}