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