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