xref: /optee_os/core/drivers/crypto/hisilicon/sec_hmac.c (revision b6a44cc5a792f1ca0c8f4fc0a9ae33f1017c1e2f)
194c8a339Sleisen // SPDX-License-Identifier: BSD-2-Clause
294c8a339Sleisen /*
394c8a339Sleisen  * Copyright 2022-2024 HiSilicon Limited.
494c8a339Sleisen  * Kunpeng hardware accelerator sec hmac algorithm implementation.
594c8a339Sleisen  */
694c8a339Sleisen 
794c8a339Sleisen #include <drvcrypt_mac.h>
894c8a339Sleisen #include <initcall.h>
9*b6a44cc5Sleisen 
10*b6a44cc5Sleisen #include "sec_hash.h"
11*b6a44cc5Sleisen #include "sec_main.h"
1294c8a339Sleisen 
to_hmac_ctx(struct crypto_mac_ctx * ctx)1394c8a339Sleisen static struct crypto_hmac *to_hmac_ctx(struct crypto_mac_ctx *ctx)
1494c8a339Sleisen {
1594c8a339Sleisen 	return container_of(ctx, struct crypto_hmac, hmac_op);
1694c8a339Sleisen }
1794c8a339Sleisen 
sec_hmac_initialize(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)1894c8a339Sleisen static TEE_Result sec_hmac_initialize(struct crypto_mac_ctx *ctx,
1994c8a339Sleisen 				      const uint8_t *key, size_t len)
2094c8a339Sleisen {
2194c8a339Sleisen 	struct crypto_hmac *hash = NULL;
2294c8a339Sleisen 	struct hashctx *hash_ctx = NULL;
2394c8a339Sleisen 
2494c8a339Sleisen 	if (!ctx || !key) {
2594c8a339Sleisen 		EMSG("Input ctx is NULL");
2694c8a339Sleisen 		return TEE_ERROR_BAD_PARAMETERS;
2794c8a339Sleisen 	}
2894c8a339Sleisen 
2994c8a339Sleisen 	hash = to_hmac_ctx(ctx);
3094c8a339Sleisen 	hash_ctx = hash->ctx;
3194c8a339Sleisen 
3294c8a339Sleisen 	return hisi_sec_digest_ctx_init(hash_ctx, key, len);
3394c8a339Sleisen }
3494c8a339Sleisen 
sec_hmac_do_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)3594c8a339Sleisen static TEE_Result sec_hmac_do_update(struct crypto_mac_ctx *ctx,
3694c8a339Sleisen 				     const uint8_t *data, size_t len)
3794c8a339Sleisen {
3894c8a339Sleisen 	struct crypto_hmac *hash = NULL;
3994c8a339Sleisen 	struct hashctx *hashctx = NULL;
4094c8a339Sleisen 
4194c8a339Sleisen 	if (!len) {
4294c8a339Sleisen 		IMSG("This is 0 len task, skip");
4394c8a339Sleisen 		return TEE_SUCCESS;
4494c8a339Sleisen 	}
4594c8a339Sleisen 
4694c8a339Sleisen 	if (!ctx || (!data && len)) {
4794c8a339Sleisen 		EMSG("Invalid input parameters");
4894c8a339Sleisen 		return TEE_ERROR_BAD_PARAMETERS;
4994c8a339Sleisen 	}
5094c8a339Sleisen 
5194c8a339Sleisen 	hash = to_hmac_ctx(ctx);
5294c8a339Sleisen 	hashctx = hash->ctx;
5394c8a339Sleisen 
5494c8a339Sleisen 	return hisi_sec_digest_do_update(hashctx, data, len);
5594c8a339Sleisen }
5694c8a339Sleisen 
sec_hmac_do_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)5794c8a339Sleisen static TEE_Result sec_hmac_do_final(struct crypto_mac_ctx *ctx, uint8_t *digest,
5894c8a339Sleisen 				    size_t len)
5994c8a339Sleisen {
6094c8a339Sleisen 	struct crypto_hmac *hash = to_hmac_ctx(ctx);
6194c8a339Sleisen 	struct hashctx *hash_ctx = hash->ctx;
6294c8a339Sleisen 
6394c8a339Sleisen 	return hisi_sec_digest_do_final(hash_ctx, digest, len);
6494c8a339Sleisen }
6594c8a339Sleisen 
sec_hmac_ctx_free(struct crypto_mac_ctx * ctx)6694c8a339Sleisen static void sec_hmac_ctx_free(struct crypto_mac_ctx *ctx)
6794c8a339Sleisen {
6894c8a339Sleisen 	struct crypto_hmac *hash = NULL;
6994c8a339Sleisen 	struct hashctx *hash_ctx = NULL;
7094c8a339Sleisen 
7194c8a339Sleisen 	if (!ctx)
7294c8a339Sleisen 		return;
7394c8a339Sleisen 
7494c8a339Sleisen 	hash = to_hmac_ctx(ctx);
7594c8a339Sleisen 	hash_ctx = hash->ctx;
7694c8a339Sleisen 	if (!hash_ctx)
7794c8a339Sleisen 		return;
7894c8a339Sleisen 
7994c8a339Sleisen 	memzero_explicit(hash_ctx->key, hash_ctx->key_len);
8094c8a339Sleisen 	hisi_sec_digest_ctx_free(hash_ctx);
8194c8a339Sleisen 
8294c8a339Sleisen 	hash->ctx = NULL;
8394c8a339Sleisen 
8494c8a339Sleisen 	free(hash);
8594c8a339Sleisen }
8694c8a339Sleisen 
sec_hmac_copy_state(struct crypto_mac_ctx * out_ctx,struct crypto_mac_ctx * in_ctx)8794c8a339Sleisen static void sec_hmac_copy_state(struct crypto_mac_ctx *out_ctx,
8894c8a339Sleisen 				struct crypto_mac_ctx *in_ctx)
8994c8a339Sleisen {
9094c8a339Sleisen 	struct crypto_hmac *out_hash = NULL;
9194c8a339Sleisen 	struct crypto_hmac *in_hash = NULL;
9294c8a339Sleisen 	struct hashctx *out_hash_ctx = NULL;
9394c8a339Sleisen 	struct hashctx *in_hash_ctx = NULL;
9494c8a339Sleisen 
9594c8a339Sleisen 	if (!out_ctx || !in_ctx) {
9694c8a339Sleisen 		EMSG("Invalid input parameters");
9794c8a339Sleisen 		return;
9894c8a339Sleisen 	}
9994c8a339Sleisen 
10094c8a339Sleisen 	out_hash = to_hmac_ctx(out_ctx);
10194c8a339Sleisen 	in_hash = to_hmac_ctx(in_ctx);
10294c8a339Sleisen 
10394c8a339Sleisen 	out_hash_ctx = out_hash->ctx;
10494c8a339Sleisen 	in_hash_ctx = in_hash->ctx;
10594c8a339Sleisen 
10694c8a339Sleisen 	hisi_sec_digest_copy_state(out_hash_ctx, in_hash_ctx);
10794c8a339Sleisen }
10894c8a339Sleisen 
10994c8a339Sleisen static struct crypto_mac_ops hash_ops = {
11094c8a339Sleisen 	.init = sec_hmac_initialize,
11194c8a339Sleisen 	.update = sec_hmac_do_update,
11294c8a339Sleisen 	.final = sec_hmac_do_final,
11394c8a339Sleisen 	.free_ctx = sec_hmac_ctx_free,
11494c8a339Sleisen 	.copy_state = sec_hmac_copy_state,
11594c8a339Sleisen };
11694c8a339Sleisen 
sec_hmac_ctx_allocate(struct crypto_mac_ctx ** ctx,uint32_t algo)11794c8a339Sleisen static TEE_Result sec_hmac_ctx_allocate(struct crypto_mac_ctx **ctx,
11894c8a339Sleisen 					uint32_t algo)
11994c8a339Sleisen {
12094c8a339Sleisen 	struct crypto_hmac *hash = NULL;
12194c8a339Sleisen 	struct hashctx *hash_ctx = NULL;
12294c8a339Sleisen 	TEE_Result ret = TEE_SUCCESS;
12394c8a339Sleisen 
12494c8a339Sleisen 	if (!ctx) {
12594c8a339Sleisen 		EMSG("Ctx is NULL");
12694c8a339Sleisen 		return TEE_ERROR_BAD_PARAMETERS;
12794c8a339Sleisen 	}
12894c8a339Sleisen 
12994c8a339Sleisen 	hash = calloc(1, sizeof(*hash));
13094c8a339Sleisen 	if (!hash) {
13194c8a339Sleisen 		EMSG("Fail to alloc hash");
13294c8a339Sleisen 		return TEE_ERROR_OUT_OF_MEMORY;
13394c8a339Sleisen 	}
13494c8a339Sleisen 
13594c8a339Sleisen 	hash_ctx = calloc(1, sizeof(*hash_ctx));
13694c8a339Sleisen 	if (!hash_ctx) {
13794c8a339Sleisen 		EMSG("Fail to alloc hashctx");
13894c8a339Sleisen 		ret = TEE_ERROR_OUT_OF_MEMORY;
13994c8a339Sleisen 		goto free_hash;
14094c8a339Sleisen 	}
14194c8a339Sleisen 
14294c8a339Sleisen 	ret = hisi_sec_hash_ctx_init(hash_ctx, algo);
14394c8a339Sleisen 	if (ret)
14494c8a339Sleisen 		goto free_ctx;
14594c8a339Sleisen 
14694c8a339Sleisen 	hash->hmac_op.ops = &hash_ops;
14794c8a339Sleisen 	hash->ctx = hash_ctx;
14894c8a339Sleisen 	*ctx = &hash->hmac_op;
14994c8a339Sleisen 
15094c8a339Sleisen 	return 0;
15194c8a339Sleisen 
15294c8a339Sleisen free_ctx:
15394c8a339Sleisen 	free(hash_ctx);
15494c8a339Sleisen free_hash:
15594c8a339Sleisen 	free(hash);
15694c8a339Sleisen 
15794c8a339Sleisen 	return ret;
15894c8a339Sleisen }
15994c8a339Sleisen 
sec_hmac_init(void)16094c8a339Sleisen static TEE_Result sec_hmac_init(void)
16194c8a339Sleisen {
16294c8a339Sleisen 	TEE_Result ret = TEE_SUCCESS;
16394c8a339Sleisen 
16494c8a339Sleisen 	ret = drvcrypt_register_hmac(&sec_hmac_ctx_allocate);
16594c8a339Sleisen 	if (ret)
16694c8a339Sleisen 		EMSG("Sec hmac register to crypto fail");
16794c8a339Sleisen 
16894c8a339Sleisen 	return ret;
16994c8a339Sleisen }
17094c8a339Sleisen driver_init(sec_hmac_init);
171