1 /* silabs_se_hash.c
2 *
3 * Copyright (C) 2006-2021 wolfSSL Inc.
4 *
5 * This file is part of wolfSSL.
6 *
7 * wolfSSL is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or
10 * (at your option) any later version.
11 *
12 * wolfSSL is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335, USA
20 */
21
22 /* Silicon Labs Secure Element Manager Hashing Function */
23
24 #ifdef HAVE_CONFIG_H
25 #include <config.h>
26 #endif
27
28
29 #include <wolfssl/wolfcrypt/settings.h>
30
31 #if defined(WOLFSSL_SILABS_SE_ACCEL)
32
33 #include <wolfssl/wolfcrypt/hash.h>
34 #include <wolfssl/wolfcrypt/error-crypt.h>
35
36 #include <wolfssl/wolfcrypt/port/silabs/silabs_hash.h>
37
wc_silabs_se_hash_init(wc_silabs_sha_t * sha,enum wc_HashType type)38 int wc_silabs_se_hash_init (wc_silabs_sha_t* sha, enum wc_HashType type)
39 {
40 int ret = 0;
41 sl_status_t rr;
42
43 /* set sizes and state */
44 XMEMSET(sha, 0, sizeof(wc_silabs_sha_t));
45
46 /* set init state */
47 switch(type) {
48 case WC_HASH_TYPE_SHA:
49 rr = sl_se_hash_starts(&sha->hash_ctx,
50 &sha->cmd_ctx,
51 SL_SE_HASH_SHA1,
52 &sha->hash_type_ctx);
53 break;
54 case WC_HASH_TYPE_SHA224:
55 rr = sl_se_hash_starts(&sha->hash_ctx,
56 &sha->cmd_ctx,
57 SL_SE_HASH_SHA224,
58 &sha->hash_type_ctx);
59 break;
60 case WC_HASH_TYPE_SHA256:
61 rr = sl_se_hash_starts(&sha->hash_ctx,
62 &sha->cmd_ctx,
63 SL_SE_HASH_SHA256,
64 &sha->hash_type_ctx);
65 break;
66
67 #ifdef WOLFSSL_SILABS_SHA384
68 case WC_HASH_TYPE_SHA384:
69 rr = sl_se_hash_starts(&sha->hash_ctx,
70 &sha->cmd_ctx,
71 SL_SE_HASH_SHA384,
72 &sha->hash_type_ctx);
73 break;
74 #endif
75
76 #ifdef WOLFSSL_SILABS_SHA512
77 case WC_HASH_TYPE_SHA512:
78 rr = sl_se_hash_starts(&sha->hash_ctx,
79 &sha->cmd_ctx,
80 SL_SE_HASH_SHA512,
81 &sha->hash_type_ctx);
82 break;
83 #endif
84
85 default:
86 ret = BAD_FUNC_ARG;
87 break;
88 }
89
90 if (rr != SL_STATUS_OK) {
91 ret = WC_HW_E;
92 }
93
94 return ret;
95 }
96
wc_silabs_se_hash_update(wc_silabs_sha_t * sha,const byte * data,word32 len)97 int wc_silabs_se_hash_update (wc_silabs_sha_t* sha, const byte* data, word32 len)
98 {
99 int ret = 0;
100
101 sl_status_t status = sl_se_hash_update(&sha->hash_ctx, data, len);
102 if (status != SL_STATUS_OK) {
103 ret = BUFFER_E;
104 }
105
106 return ret;
107 }
108
wc_silabs_se_hash_final(wc_silabs_sha_t * sha,byte * hash)109 int wc_silabs_se_hash_final (wc_silabs_sha_t* sha, byte* hash)
110 {
111 int ret = 0;
112
113 sl_status_t status = sl_se_hash_finish(&sha->hash_ctx, hash, sha->hash_ctx.size);
114 if (status != SL_STATUS_OK) {
115 ret = BUFFER_E;
116 }
117
118 return ret;
119 }
120
121
wc_HashUpdate_ex(wc_silabs_sha_t * sha,const byte * data,word32 len)122 int wc_HashUpdate_ex (wc_silabs_sha_t* sha, const byte* data, word32 len)
123 {
124 int ret = 0;
125
126 if (sha == NULL || (data == NULL && len > 0)) {
127 return BAD_FUNC_ARG;
128 }
129
130 ret = wolfSSL_CryptHwMutexLock();
131 if (ret == 0) {
132 ret = wc_silabs_se_hash_update(sha, data, len);
133
134 wolfSSL_CryptHwMutexUnLock();
135 }
136 return ret;
137 }
138
wc_HashFinal_ex(wc_silabs_sha_t * sha,byte * hash)139 int wc_HashFinal_ex(wc_silabs_sha_t* sha, byte* hash)
140 {
141 int ret = 0;
142
143 if (sha == NULL || hash == NULL) {
144 return BAD_FUNC_ARG;
145 }
146
147 ret = wolfSSL_CryptHwMutexLock();
148 if (ret == 0) {
149 ret = wc_silabs_se_hash_final(sha, hash);
150 wolfSSL_CryptHwMutexUnLock();
151 }
152
153 return ret;
154 }
155
156 #ifndef NO_SHA
157
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)158 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
159 {
160 if (sha == NULL) {
161 return BAD_FUNC_ARG;
162 }
163
164 (void)devId;
165 (void)heap;
166
167 return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA);
168 }
169
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)170 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
171 {
172 return wc_HashUpdate_ex(&(sha->silabsCtx), data, len);
173 }
174
wc_ShaFinal(wc_Sha * sha,byte * hash)175 int wc_ShaFinal(wc_Sha* sha, byte* hash)
176 {
177 int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash);
178
179 (void)wc_InitSha(sha); /* reset state */
180
181 return ret;
182 }
183
184 #endif /* ! NO_SHA */
185
186 #ifndef NO_SHA256
wc_InitSha256_ex(wc_Sha256 * sha,void * heap,int devId)187 int wc_InitSha256_ex(wc_Sha256* sha, void* heap, int devId)
188 {
189 if (sha == NULL) {
190 return BAD_FUNC_ARG;
191 }
192
193 (void)devId;
194 (void)heap;
195
196 return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA256);
197 }
198
199
wc_Sha256Update(wc_Sha256 * sha,const byte * data,word32 len)200 int wc_Sha256Update(wc_Sha256* sha, const byte* data, word32 len)
201 {
202 return wc_HashUpdate_ex(&(sha->silabsCtx), data, len);
203 }
204
wc_Sha256Final(wc_Sha256 * sha,byte * hash)205 int wc_Sha256Final(wc_Sha256* sha, byte* hash)
206 {
207 int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash);
208
209 (void)wc_InitSha256(sha); /* reset state */
210
211 return ret;
212 }
213 #endif /* ! NO_SHA256 */
214
215 #ifndef NO_SHA224
wc_InitSha224_ex(wc_Sha224 * sha,void * heap,int devId)216 int wc_InitSha224_ex(wc_Sha224* sha, void* heap, int devId)
217 {
218 if (sha == NULL) {
219 return BAD_FUNC_ARG;
220 }
221
222 (void)devId;
223 (void)heap;
224
225 return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA224);
226 }
227
228
wc_Sha224Update(wc_Sha224 * sha,const byte * data,word32 len)229 int wc_Sha224Update(wc_Sha224* sha, const byte* data, word32 len)
230 {
231 return wc_HashUpdate_ex(&(sha->silabsCtx), data, len);
232 }
233
wc_Sha224Final(wc_Sha224 * sha,byte * hash)234 int wc_Sha224Final(wc_Sha224* sha, byte* hash)
235 {
236 int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash);
237
238 (void)wc_InitSha224(sha); /* reset state */
239
240 return ret;
241 }
242 #endif /* ! NO_SHA224 */
243
244 #ifdef WOLFSSL_SILABS_SHA384
wc_InitSha384_ex(wc_Sha384 * sha,void * heap,int devId)245 int wc_InitSha384_ex(wc_Sha384* sha, void* heap, int devId)
246 {
247 if (sha == NULL) {
248 return BAD_FUNC_ARG;
249 }
250
251 (void)devId;
252 (void)heap;
253
254 return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA384);
255 }
256
257
wc_Sha384Update(wc_Sha384 * sha,const byte * data,word32 len)258 int wc_Sha384Update(wc_Sha384* sha, const byte* data, word32 len)
259 {
260 return wc_HashUpdate_ex(&(sha->silabsCtx), data, len);
261 }
262
wc_Sha384Final(wc_Sha384 * sha,byte * hash)263 int wc_Sha384Final(wc_Sha384* sha, byte* hash)
264 {
265 int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash);
266
267 (void)wc_InitSha384(sha); /* reset state */
268
269 return ret;
270 }
271 #endif /* WOLFSSL_SILABS_SHA384 */
272
273 #ifdef WOLFSSL_SILABS_SHA512
wc_InitSha512_ex(wc_Sha512 * sha,void * heap,int devId)274 int wc_InitSha512_ex(wc_Sha512* sha, void* heap, int devId)
275 {
276 if (sha == NULL) {
277 return BAD_FUNC_ARG;
278 }
279
280 (void)devId;
281 (void)heap;
282
283 return wc_silabs_se_hash_init(&(sha->silabsCtx), WC_HASH_TYPE_SHA512);
284 }
285
286
wc_Sha512Update(wc_Sha512 * sha,const byte * data,word32 len)287 int wc_Sha512Update(wc_Sha512* sha, const byte* data, word32 len)
288 {
289 return wc_HashUpdate_ex(&(sha->silabsCtx), data, len);
290 }
291
wc_Sha512Final(wc_Sha512 * sha,byte * hash)292 int wc_Sha512Final(wc_Sha512* sha, byte* hash)
293 {
294 int ret = wc_HashFinal_ex(&(sha->silabsCtx), hash);
295
296 (void)wc_InitSha512(sha); /* reset state */
297
298 return ret;
299 }
300 #endif /* WOLFSSL_SILABS_SHA512 */
301
302 #endif /* defined(WOLFSSL_SILABS_SE_ACCEL) */
303