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