xref: /optee_os/core/drivers/crypto/hisilicon/sec_hmac.c (revision b6a44cc5a792f1ca0c8f4fc0a9ae33f1017c1e2f)
1 // SPDX-License-Identifier: BSD-2-Clause
2 /*
3  * Copyright 2022-2024 HiSilicon Limited.
4  * Kunpeng hardware accelerator sec hmac algorithm implementation.
5  */
6 
7 #include <drvcrypt_mac.h>
8 #include <initcall.h>
9 
10 #include "sec_hash.h"
11 #include "sec_main.h"
12 
to_hmac_ctx(struct crypto_mac_ctx * ctx)13 static struct crypto_hmac *to_hmac_ctx(struct crypto_mac_ctx *ctx)
14 {
15 	return container_of(ctx, struct crypto_hmac, hmac_op);
16 }
17 
sec_hmac_initialize(struct crypto_mac_ctx * ctx,const uint8_t * key,size_t len)18 static TEE_Result sec_hmac_initialize(struct crypto_mac_ctx *ctx,
19 				      const uint8_t *key, size_t len)
20 {
21 	struct crypto_hmac *hash = NULL;
22 	struct hashctx *hash_ctx = NULL;
23 
24 	if (!ctx || !key) {
25 		EMSG("Input ctx is NULL");
26 		return TEE_ERROR_BAD_PARAMETERS;
27 	}
28 
29 	hash = to_hmac_ctx(ctx);
30 	hash_ctx = hash->ctx;
31 
32 	return hisi_sec_digest_ctx_init(hash_ctx, key, len);
33 }
34 
sec_hmac_do_update(struct crypto_mac_ctx * ctx,const uint8_t * data,size_t len)35 static TEE_Result sec_hmac_do_update(struct crypto_mac_ctx *ctx,
36 				     const uint8_t *data, size_t len)
37 {
38 	struct crypto_hmac *hash = NULL;
39 	struct hashctx *hashctx = NULL;
40 
41 	if (!len) {
42 		IMSG("This is 0 len task, skip");
43 		return TEE_SUCCESS;
44 	}
45 
46 	if (!ctx || (!data && len)) {
47 		EMSG("Invalid input parameters");
48 		return TEE_ERROR_BAD_PARAMETERS;
49 	}
50 
51 	hash = to_hmac_ctx(ctx);
52 	hashctx = hash->ctx;
53 
54 	return hisi_sec_digest_do_update(hashctx, data, len);
55 }
56 
sec_hmac_do_final(struct crypto_mac_ctx * ctx,uint8_t * digest,size_t len)57 static TEE_Result sec_hmac_do_final(struct crypto_mac_ctx *ctx, uint8_t *digest,
58 				    size_t len)
59 {
60 	struct crypto_hmac *hash = to_hmac_ctx(ctx);
61 	struct hashctx *hash_ctx = hash->ctx;
62 
63 	return hisi_sec_digest_do_final(hash_ctx, digest, len);
64 }
65 
sec_hmac_ctx_free(struct crypto_mac_ctx * ctx)66 static void sec_hmac_ctx_free(struct crypto_mac_ctx *ctx)
67 {
68 	struct crypto_hmac *hash = NULL;
69 	struct hashctx *hash_ctx = NULL;
70 
71 	if (!ctx)
72 		return;
73 
74 	hash = to_hmac_ctx(ctx);
75 	hash_ctx = hash->ctx;
76 	if (!hash_ctx)
77 		return;
78 
79 	memzero_explicit(hash_ctx->key, hash_ctx->key_len);
80 	hisi_sec_digest_ctx_free(hash_ctx);
81 
82 	hash->ctx = NULL;
83 
84 	free(hash);
85 }
86 
sec_hmac_copy_state(struct crypto_mac_ctx * out_ctx,struct crypto_mac_ctx * in_ctx)87 static void sec_hmac_copy_state(struct crypto_mac_ctx *out_ctx,
88 				struct crypto_mac_ctx *in_ctx)
89 {
90 	struct crypto_hmac *out_hash = NULL;
91 	struct crypto_hmac *in_hash = NULL;
92 	struct hashctx *out_hash_ctx = NULL;
93 	struct hashctx *in_hash_ctx = NULL;
94 
95 	if (!out_ctx || !in_ctx) {
96 		EMSG("Invalid input parameters");
97 		return;
98 	}
99 
100 	out_hash = to_hmac_ctx(out_ctx);
101 	in_hash = to_hmac_ctx(in_ctx);
102 
103 	out_hash_ctx = out_hash->ctx;
104 	in_hash_ctx = in_hash->ctx;
105 
106 	hisi_sec_digest_copy_state(out_hash_ctx, in_hash_ctx);
107 }
108 
109 static struct crypto_mac_ops hash_ops = {
110 	.init = sec_hmac_initialize,
111 	.update = sec_hmac_do_update,
112 	.final = sec_hmac_do_final,
113 	.free_ctx = sec_hmac_ctx_free,
114 	.copy_state = sec_hmac_copy_state,
115 };
116 
sec_hmac_ctx_allocate(struct crypto_mac_ctx ** ctx,uint32_t algo)117 static TEE_Result sec_hmac_ctx_allocate(struct crypto_mac_ctx **ctx,
118 					uint32_t algo)
119 {
120 	struct crypto_hmac *hash = NULL;
121 	struct hashctx *hash_ctx = NULL;
122 	TEE_Result ret = TEE_SUCCESS;
123 
124 	if (!ctx) {
125 		EMSG("Ctx is NULL");
126 		return TEE_ERROR_BAD_PARAMETERS;
127 	}
128 
129 	hash = calloc(1, sizeof(*hash));
130 	if (!hash) {
131 		EMSG("Fail to alloc hash");
132 		return TEE_ERROR_OUT_OF_MEMORY;
133 	}
134 
135 	hash_ctx = calloc(1, sizeof(*hash_ctx));
136 	if (!hash_ctx) {
137 		EMSG("Fail to alloc hashctx");
138 		ret = TEE_ERROR_OUT_OF_MEMORY;
139 		goto free_hash;
140 	}
141 
142 	ret = hisi_sec_hash_ctx_init(hash_ctx, algo);
143 	if (ret)
144 		goto free_ctx;
145 
146 	hash->hmac_op.ops = &hash_ops;
147 	hash->ctx = hash_ctx;
148 	*ctx = &hash->hmac_op;
149 
150 	return 0;
151 
152 free_ctx:
153 	free(hash_ctx);
154 free_hash:
155 	free(hash);
156 
157 	return ret;
158 }
159 
sec_hmac_init(void)160 static TEE_Result sec_hmac_init(void)
161 {
162 	TEE_Result ret = TEE_SUCCESS;
163 
164 	ret = drvcrypt_register_hmac(&sec_hmac_ctx_allocate);
165 	if (ret)
166 		EMSG("Sec hmac register to crypto fail");
167 
168 	return ret;
169 }
170 driver_init(sec_hmac_init);
171