1 /***************************************************************************//**
2  * @file
3  * @brief Silicon Labs Secure Engine Manager API.
4  *******************************************************************************
5  * # License
6  * <b>Copyright 2020 Silicon Laboratories Inc. www.silabs.com</b>
7  *******************************************************************************
8  *
9  * SPDX-License-Identifier: Zlib
10  *
11  * The licensor of this software is Silicon Laboratories Inc.
12  *
13  * This software is provided 'as-is', without any express or implied
14  * warranty. In no event will the authors be held liable for any damages
15  * arising from the use of this software.
16  *
17  * Permission is granted to anyone to use this software for any purpose,
18  * including commercial applications, and to alter it and redistribute it
19  * freely, subject to the following restrictions:
20  *
21  * 1. The origin of this software must not be misrepresented; you must not
22  *    claim that you wrote the original software. If you use this software
23  *    in a product, an acknowledgment in the product documentation would be
24  *    appreciated but is not required.
25  * 2. Altered source versions must be plainly marked as such, and must not be
26  *    misrepresented as being the original software.
27  * 3. This notice may not be removed or altered from any source distribution.
28  *
29  ******************************************************************************/
30 #include "em_device.h"
31 
32 #if defined(SEMAILBOX_PRESENT)
33 
34 #include "sl_se_manager.h"
35 #include "sli_se_manager_internal.h"
36 #include "em_se.h"
37 #include "sl_assert.h"
38 #include <string.h>
39 
40 /***************************************************************************//**
41  * \addtogroup sl_se Secure Engine Manager API
42  * @{
43  ******************************************************************************/
44 
45 // -----------------------------------------------------------------------------
46 // Global functions
47 
48 /***************************************************************************//**
49  * Start a SHA1 stream operation.
50  ******************************************************************************/
sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t * sha1_ctx,sl_se_command_context_t * cmd_ctx)51 sl_status_t sl_se_hash_sha1_multipart_starts(sl_se_sha1_multipart_context_t *sha1_ctx,
52                                              sl_se_command_context_t *cmd_ctx)
53 {
54   static const uint8_t init_state_sha1[32] = {
55     0x67, 0x45, 0x23, 0x01,
56     0xEF, 0xCD, 0xAB, 0x89,
57     0x98, 0xBA, 0xDC, 0xFE,
58     0x10, 0x32, 0x54, 0x76,
59     0xC3, 0xD2, 0xE1, 0xF0,
60     0x00, 0x00, 0x00, 0x00,
61     0x00, 0x00, 0x00, 0x00,
62     0x00, 0x00, 0x00, 0x00
63   };
64 
65   if (cmd_ctx == NULL || sha1_ctx == NULL) {
66     return SL_STATUS_INVALID_PARAMETER;
67   }
68 
69   sha1_ctx->total[0] = 0;
70   sha1_ctx->total[1] = 0;
71   memcpy(sha1_ctx->state, init_state_sha1, sizeof(sha1_ctx->state));
72 
73   sha1_ctx->hash_type = SL_SE_HASH_SHA1;
74 
75   return SL_STATUS_OK;
76 }
77 
78 /***************************************************************************//**
79  * Start a SHA1 stream operation. Deprecated.
80  ******************************************************************************/
sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_sha1_streaming_context_t * sha1_ctx)81 sl_status_t sl_se_hash_sha1_starts(sl_se_hash_streaming_context_t *hash_ctx,
82                                    sl_se_command_context_t *cmd_ctx,
83                                    sl_se_sha1_streaming_context_t *sha1_ctx)
84 {
85   if (hash_ctx == NULL || cmd_ctx == NULL || sha1_ctx == NULL ) {
86     return SL_STATUS_INVALID_PARAMETER;
87   }
88 
89   hash_ctx->cmd_ctx = cmd_ctx;
90 
91   sl_se_sha1_multipart_context_t sha1_ctx_multi;
92 
93   sl_status_t status = sl_se_hash_sha1_multipart_starts(&sha1_ctx_multi, hash_ctx->cmd_ctx);
94   if (status != SL_STATUS_OK) {
95     return status;
96   }
97   memcpy(sha1_ctx->total, sha1_ctx_multi.total, sizeof(sha1_ctx->total));
98   memcpy(sha1_ctx->state, sha1_ctx_multi.state, sizeof(sha1_ctx->state));
99 
100   hash_ctx->hash_type_ctx = sha1_ctx;
101   hash_ctx->hash_type = SL_SE_HASH_SHA1;
102 
103   return SL_STATUS_OK;
104 }
105 
106 /***************************************************************************//**
107  * Start a SHA224 stream operation.
108  ******************************************************************************/
109 sl_status_t
sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t * sha224_ctx,sl_se_command_context_t * cmd_ctx)110 sl_se_hash_sha224_multipart_starts(sl_se_sha224_multipart_context_t *sha224_ctx,
111                                    sl_se_command_context_t *cmd_ctx)
112 {
113   static const uint8_t init_state_sha224[32] = {
114     0xC1, 0x05, 0x9E, 0xD8,
115     0x36, 0x7C, 0xD5, 0x07,
116     0x30, 0x70, 0xDD, 0x17,
117     0xF7, 0x0E, 0x59, 0x39,
118     0xFF, 0xC0, 0x0B, 0x31,
119     0x68, 0x58, 0x15, 0x11,
120     0x64, 0xF9, 0x8F, 0xA7,
121     0xBE, 0xFA, 0x4F, 0xA4
122   };
123 
124   if (cmd_ctx == NULL || sha224_ctx == NULL) {
125     return SL_STATUS_INVALID_PARAMETER;
126   }
127 
128   sha224_ctx->total[0] = 0;
129   sha224_ctx->total[1] = 0;
130   memcpy(sha224_ctx->state, init_state_sha224, sizeof(sha224_ctx->state));
131 
132   sha224_ctx->hash_type = SL_SE_HASH_SHA224;
133 
134   return SL_STATUS_OK;
135 }
136 
137 /***************************************************************************//**
138  * Start a SHA224 stream operation. Deprecated.
139  ******************************************************************************/
140 sl_status_t
sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_sha224_streaming_context_t * sha224_ctx)141 sl_se_hash_sha224_starts(sl_se_hash_streaming_context_t *hash_ctx,
142                          sl_se_command_context_t *cmd_ctx,
143                          sl_se_sha224_streaming_context_t *sha224_ctx)
144 {
145   if (hash_ctx == NULL || cmd_ctx == NULL || sha224_ctx == NULL ) {
146     return SL_STATUS_INVALID_PARAMETER;
147   }
148 
149   hash_ctx->cmd_ctx = cmd_ctx;
150 
151   sl_se_sha224_multipart_context_t sha224_ctx_multi;
152 
153   sl_status_t status = sl_se_hash_sha224_multipart_starts(&sha224_ctx_multi, hash_ctx->cmd_ctx);
154   if (status != SL_STATUS_OK) {
155     return status;
156   }
157 
158   memcpy(sha224_ctx->total, sha224_ctx_multi.total, sizeof(sha224_ctx->total));
159   memcpy(sha224_ctx->state, sha224_ctx_multi.state, sizeof(sha224_ctx->state));
160 
161   hash_ctx->hash_type_ctx = sha224_ctx;
162   hash_ctx->hash_type = SL_SE_HASH_SHA224;
163 
164   return SL_STATUS_OK;
165 }
166 
167 /***************************************************************************//**
168  * Start a SHA256 stream operation.
169  ******************************************************************************/
170 sl_status_t
sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t * sha256_ctx,sl_se_command_context_t * cmd_ctx)171 sl_se_hash_sha256_multipart_starts(sl_se_sha256_multipart_context_t *sha256_ctx,
172                                    sl_se_command_context_t *cmd_ctx)
173 {
174   static const uint8_t init_state_sha256[32] = {
175     0x6A, 0x09, 0xE6, 0x67,
176     0xBB, 0x67, 0xAE, 0x85,
177     0x3C, 0x6E, 0xF3, 0x72,
178     0xA5, 0x4F, 0xF5, 0x3A,
179     0x51, 0x0E, 0x52, 0x7F,
180     0x9B, 0x05, 0x68, 0x8C,
181     0x1F, 0x83, 0xD9, 0xAB,
182     0x5B, 0xE0, 0xCD, 0x19
183   };
184 
185   if (cmd_ctx == NULL || sha256_ctx == NULL) {
186     return SL_STATUS_INVALID_PARAMETER;
187   }
188 
189   sha256_ctx->total[0] = 0;
190   sha256_ctx->total[1] = 0;
191   memcpy(sha256_ctx->state, init_state_sha256, sizeof(sha256_ctx->state));
192 
193   sha256_ctx->hash_type = SL_SE_HASH_SHA256;
194 
195   return SL_STATUS_OK;
196 }
197 
198 /***************************************************************************//**
199  * Start a SHA256 stream operation. Deprecated.
200  ******************************************************************************/
201 sl_status_t
sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_sha256_streaming_context_t * sha256_ctx)202 sl_se_hash_sha256_starts(sl_se_hash_streaming_context_t *hash_ctx,
203                          sl_se_command_context_t *cmd_ctx,
204                          sl_se_sha256_streaming_context_t *sha256_ctx)
205 {
206   if (hash_ctx == NULL || cmd_ctx == NULL || sha256_ctx == NULL ) {
207     return SL_STATUS_INVALID_PARAMETER;
208   }
209 
210   hash_ctx->cmd_ctx = cmd_ctx;
211 
212   sl_se_sha256_multipart_context_t sha256_ctx_multi;
213 
214   sl_status_t status = sl_se_hash_sha256_multipart_starts(&sha256_ctx_multi, hash_ctx->cmd_ctx);
215 
216   if (status != SL_STATUS_OK) {
217     return status;
218   }
219   memcpy(sha256_ctx->total, sha256_ctx_multi.total, sizeof(sha256_ctx->total));
220   memcpy(sha256_ctx->state, sha256_ctx_multi.state, sizeof(sha256_ctx->state));
221 
222   hash_ctx->hash_type = SL_SE_HASH_SHA256;
223   hash_ctx->hash_type_ctx = sha256_ctx;
224 
225   return SL_STATUS_OK;
226 }
227 
228 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
229 /***************************************************************************//**
230  * Start a SHA384 stream operation.
231  ******************************************************************************/
232 sl_status_t
sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t * sha384_ctx,sl_se_command_context_t * cmd_ctx)233 sl_se_hash_sha384_multipart_starts(sl_se_sha384_multipart_context_t *sha384_ctx,
234                                    sl_se_command_context_t *cmd_ctx)
235 {
236   static const uint8_t init_state_sha384[64] = {
237     0xCB, 0xBB, 0x9D, 0x5D, 0xC1, 0x05, 0x9E, 0xD8,
238     0x62, 0x9A, 0x29, 0x2A, 0x36, 0x7C, 0xD5, 0x07,
239     0x91, 0x59, 0x01, 0x5A, 0x30, 0x70, 0xDD, 0x17,
240     0x15, 0x2F, 0xEC, 0xD8, 0xF7, 0x0E, 0x59, 0x39,
241     0x67, 0x33, 0x26, 0x67, 0xFF, 0xC0, 0x0B, 0x31,
242     0x8E, 0xB4, 0x4A, 0x87, 0x68, 0x58, 0x15, 0x11,
243     0xDB, 0x0C, 0x2E, 0x0D, 0x64, 0xF9, 0x8F, 0xA7,
244     0x47, 0xB5, 0x48, 0x1D, 0xBE, 0xFA, 0x4F, 0xA4
245   };
246 
247   if (cmd_ctx == NULL || sha384_ctx == NULL) {
248     return SL_STATUS_INVALID_PARAMETER;
249   }
250 
251   sha384_ctx->total[0] = 0;
252   sha384_ctx->total[1] = 0;
253   sha384_ctx->total[2] = 0;
254   sha384_ctx->total[3] = 0;
255   memcpy(sha384_ctx->state, init_state_sha384, sizeof(sha384_ctx->state));
256 
257   sha384_ctx->hash_type = SL_SE_HASH_SHA384;
258 
259   return SL_STATUS_OK;
260 }
261 
262 /***************************************************************************//**
263  * Start a SHA384 stream operation. Deprecated.
264  ******************************************************************************/
265 sl_status_t
sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_sha384_streaming_context_t * sha384_ctx)266 sl_se_hash_sha384_starts(sl_se_hash_streaming_context_t *hash_ctx,
267                          sl_se_command_context_t *cmd_ctx,
268                          sl_se_sha384_streaming_context_t *sha384_ctx)
269 {
270   if (hash_ctx == NULL || cmd_ctx == NULL || sha384_ctx == NULL ) {
271     return SL_STATUS_INVALID_PARAMETER;
272   }
273   hash_ctx->cmd_ctx = cmd_ctx;
274 
275   sl_se_sha384_multipart_context_t sha384_ctx_multi;
276 
277   sl_status_t status = sl_se_hash_sha384_multipart_starts(&sha384_ctx_multi, hash_ctx->cmd_ctx);
278   if (status != SL_STATUS_OK) {
279     return status;
280   }
281 
282   memcpy(sha384_ctx->total, sha384_ctx_multi.total, sizeof(sha384_ctx->total));
283   memcpy(sha384_ctx->state, sha384_ctx_multi.state, sizeof(sha384_ctx->state));
284 
285   hash_ctx->hash_type = SL_SE_HASH_SHA384;
286   hash_ctx->hash_type_ctx = sha384_ctx;
287 
288   return SL_STATUS_OK;
289 }
290 
291 /***************************************************************************//**
292  * Start a SHA512 stream operation.
293  ******************************************************************************/
294 sl_status_t
sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t * sha512_ctx,sl_se_command_context_t * cmd_ctx)295 sl_se_hash_sha512_multipart_starts(sl_se_sha512_multipart_context_t *sha512_ctx, sl_se_command_context_t *cmd_ctx)
296 {
297   static const uint8_t init_state_sha512[64] = {
298     0x6A, 0x09, 0xE6, 0x67, 0xF3, 0xBC, 0xC9, 0x08,
299     0xBB, 0x67, 0xAE, 0x85, 0x84, 0xCA, 0xA7, 0x3B,
300     0x3C, 0x6E, 0xF3, 0x72, 0xFE, 0x94, 0xF8, 0x2B,
301     0xA5, 0x4F, 0xF5, 0x3A, 0x5F, 0x1D, 0x36, 0xF1,
302     0x51, 0x0E, 0x52, 0x7F, 0xAD, 0xE6, 0x82, 0xD1,
303     0x9B, 0x05, 0x68, 0x8C, 0x2B, 0x3E, 0x6C, 0x1F,
304     0x1F, 0x83, 0xD9, 0xAB, 0xFB, 0x41, 0xBD, 0x6B,
305     0x5B, 0xE0, 0xCD, 0x19, 0x13, 0x7E, 0x21, 0x79
306   };
307 
308   if (cmd_ctx == NULL || sha512_ctx == NULL) {
309     return SL_STATUS_INVALID_PARAMETER;
310   }
311 
312   sha512_ctx->total[0] = 0;
313   sha512_ctx->total[1] = 0;
314   sha512_ctx->total[2] = 0;
315   sha512_ctx->total[3] = 0;
316   memcpy(sha512_ctx->state, init_state_sha512, sizeof(sha512_ctx->state));
317 
318   sha512_ctx->hash_type = SL_SE_HASH_SHA512;
319 
320   return SL_STATUS_OK;
321 }
322 
323 /***************************************************************************//**
324  * Start a SHA512 stream operation. Deprecated.
325  ******************************************************************************/
326 sl_status_t
sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_sha512_streaming_context_t * sha512_ctx)327 sl_se_hash_sha512_starts(sl_se_hash_streaming_context_t *hash_ctx,
328                          sl_se_command_context_t *cmd_ctx,
329                          sl_se_sha512_streaming_context_t *sha512_ctx)
330 {
331   if (hash_ctx == NULL || cmd_ctx == NULL || sha512_ctx == NULL ) {
332     return SL_STATUS_INVALID_PARAMETER;
333   }
334 
335   hash_ctx->cmd_ctx = cmd_ctx;
336 
337   sl_se_sha512_multipart_context_t sha512_ctx_multi;
338 
339   sl_status_t status = sl_se_hash_sha512_multipart_starts(&sha512_ctx_multi, hash_ctx->cmd_ctx);
340   if (status != SL_STATUS_OK) {
341     return SL_STATUS_INVALID_PARAMETER;
342   }
343   memcpy(sha512_ctx->total, sha512_ctx_multi.total, sizeof(sha512_ctx->total));
344   memcpy(sha512_ctx->state, sha512_ctx_multi.state, sizeof(sha512_ctx->state));
345 
346   hash_ctx->hash_type = SL_SE_HASH_SHA512;
347   hash_ctx->hash_type_ctx = sha512_ctx;
348 
349   return SL_STATUS_OK;
350 }
351 
352 #endif
353 
354 /***************************************************************************//**
355  * Start a hash stream operation.
356  ******************************************************************************/
sl_se_hash_multipart_starts(void * hash_type_ctx,sl_se_command_context_t * cmd_ctx,sl_se_hash_type_t hash_type)357 sl_status_t sl_se_hash_multipart_starts(void *hash_type_ctx,
358                                         sl_se_command_context_t *cmd_ctx,
359                                         sl_se_hash_type_t hash_type)
360 {
361   if (cmd_ctx == NULL || hash_type_ctx == NULL) {
362     return SL_STATUS_INVALID_PARAMETER;
363   }
364 
365   switch (hash_type) {
366     case SL_SE_HASH_SHA1:
367       return sl_se_hash_sha1_multipart_starts((sl_se_sha1_multipart_context_t*)
368                                               hash_type_ctx, cmd_ctx);
369 
370     case SL_SE_HASH_SHA224:
371       return sl_se_hash_sha224_multipart_starts((sl_se_sha224_multipart_context_t*)
372                                                 hash_type_ctx, cmd_ctx);
373 
374     case SL_SE_HASH_SHA256:
375       return sl_se_hash_sha256_multipart_starts((sl_se_sha256_multipart_context_t*)
376                                                 hash_type_ctx, cmd_ctx);
377 
378 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
379     case SL_SE_HASH_SHA384:
380       return sl_se_hash_sha384_multipart_starts((sl_se_sha384_multipart_context_t*)
381                                                 hash_type_ctx,
382                                                 cmd_ctx);
383 
384     case SL_SE_HASH_SHA512:
385       return sl_se_hash_sha512_multipart_starts((sl_se_sha512_multipart_context_t*)
386                                                 hash_type_ctx, cmd_ctx);
387 #endif
388 
389     default:
390       return SL_STATUS_INVALID_PARAMETER;
391   }
392 }
393 
394 /***************************************************************************//**
395  * Start a hash stream operation. Deprecated.
396  ******************************************************************************/
sl_se_hash_starts(sl_se_hash_streaming_context_t * hash_ctx,sl_se_command_context_t * cmd_ctx,sl_se_hash_type_t hash_type,void * hash_type_ctx)397 sl_status_t sl_se_hash_starts(sl_se_hash_streaming_context_t *hash_ctx,
398                               sl_se_command_context_t *cmd_ctx,
399                               sl_se_hash_type_t hash_type,
400                               void *hash_type_ctx)
401 {
402   if (hash_ctx == NULL || cmd_ctx == NULL || hash_type_ctx == NULL) {
403     return SL_STATUS_INVALID_PARAMETER;
404   }
405 
406   switch (hash_type) {
407     case SL_SE_HASH_SHA1:
408       return sl_se_hash_sha1_starts(hash_ctx,
409                                     cmd_ctx,
410                                     (sl_se_sha1_streaming_context_t*)
411                                     hash_type_ctx);
412 
413     case SL_SE_HASH_SHA224:
414       return sl_se_hash_sha224_starts(hash_ctx,
415                                       cmd_ctx,
416                                       (sl_se_sha224_streaming_context_t*)
417                                       hash_type_ctx);
418 
419     case SL_SE_HASH_SHA256:
420       return sl_se_hash_sha256_starts(hash_ctx,
421                                       cmd_ctx,
422                                       (sl_se_sha256_streaming_context_t*)
423                                       hash_type_ctx);
424 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
425     case SL_SE_HASH_SHA384:
426       return sl_se_hash_sha384_starts(hash_ctx,
427                                       cmd_ctx,
428                                       (sl_se_sha384_streaming_context_t*)
429                                       hash_type_ctx);
430 
431     case SL_SE_HASH_SHA512:
432       return sl_se_hash_sha512_starts(hash_ctx,
433                                       cmd_ctx,
434                                       (sl_se_sha512_streaming_context_t*)
435                                       hash_type_ctx);
436 #endif
437 
438     default:
439       return SL_STATUS_INVALID_PARAMETER;
440   }
441 }
442 
443 /***************************************************************************//**
444  *   Feeds an input block into an ongoing hash computation.
445  ******************************************************************************/
se_cmd_hash_multipart_update(void * hash_type_ctx,sl_se_command_context_t * cmd_ctx,const uint8_t * input,uint32_t num_blocks)446 static sl_status_t se_cmd_hash_multipart_update(void *hash_type_ctx,
447                                                 sl_se_command_context_t *cmd_ctx,
448                                                 const uint8_t *input,
449                                                 uint32_t num_blocks)
450 {
451   SE_Command_t *se_cmd = &cmd_ctx->command;
452   uint32_t command_word;
453   unsigned int ilen, state_len;
454   uint8_t *state;
455 
456   switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
457     case SL_SE_HASH_SHA1:
458       command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA1;
459       // SHA1 block size is 64 bytes
460       ilen = 64 * num_blocks;
461       // SHA1 state size is 20 bytes
462       state_len = 20;
463       state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
464       break;
465 
466     case SL_SE_HASH_SHA224:
467       command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA224;
468       // SHA224 block size is 64 bytes
469       ilen = 64 * num_blocks;
470       // SHA224 state size is 32 bytes
471       state_len = 32;
472       state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
473       break;
474 
475     case SL_SE_HASH_SHA256:
476       command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA256;
477       // SHA256 block size is 64 bytes
478       ilen = 64 * num_blocks;
479       // SHA256 state size is 32 bytes
480       state_len = 32;
481       state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
482       break;
483 
484 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
485     case SL_SE_HASH_SHA384:
486       command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA384;
487       // SHA384 block size is 128 bytes
488       ilen = 128 * num_blocks;
489       // SHA384 state size is 64 bytes
490       state_len = 64;
491       state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
492       break;
493 
494     case SL_SE_HASH_SHA512:
495       command_word = SE_COMMAND_HASHUPDATE | SE_COMMAND_OPTION_HASH_SHA512;
496       // SHA512 block size is 128 bytes
497       ilen = 128 * num_blocks;
498       // SHA512 state size is 64 bytes
499       state_len = 64;
500       state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
501       break;
502 #endif
503 
504     default:
505       return SL_STATUS_INVALID_PARAMETER;
506   }
507 
508   sli_se_command_init(cmd_ctx, command_word);
509 
510   SE_addParameter(se_cmd, ilen);
511 
512   SE_DataTransfer_t data_in = SE_DATATRANSFER_DEFAULT(input, ilen);
513   SE_DataTransfer_t iv_in = SE_DATATRANSFER_DEFAULT(state, state_len);
514   SE_DataTransfer_t iv_out = SE_DATATRANSFER_DEFAULT(state, state_len);
515 
516   SE_addDataInput(se_cmd, &iv_in);
517   SE_addDataInput(se_cmd, &data_in);
518   SE_addDataOutput(se_cmd, &iv_out);
519 
520   // Execute and wait
521   return sli_se_execute_and_wait(cmd_ctx);
522 }
523 
524 /***************************************************************************//**
525  *   Feeds an input buffer into an ongoing hash computation.
526  ******************************************************************************/
sl_se_hash_multipart_update(void * hash_type_ctx,sl_se_command_context_t * cmd_ctx,const uint8_t * input,size_t input_len)527 sl_status_t sl_se_hash_multipart_update(void *hash_type_ctx,
528                                         sl_se_command_context_t *cmd_ctx,
529                                         const uint8_t *input,
530                                         size_t input_len)
531 {
532   size_t blocksize, countersize, blocks, fill, left;
533   uint32_t *counter;
534   uint8_t *buffer;
535   sl_status_t status;
536 
537   if ( input_len == 0 ) {
538     return SL_STATUS_OK;
539   }
540 
541   if (hash_type_ctx == NULL || cmd_ctx == NULL || input == NULL) {
542     return SL_STATUS_INVALID_PARAMETER;
543   }
544 
545   switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
546     case SL_SE_HASH_SHA1:
547       blocksize = 64;
548       countersize = 64 / 32;
549       counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
550       buffer = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->buffer;
551       break;
552 
553     case SL_SE_HASH_SHA224:
554       blocksize = 64;
555       countersize = 64 / 32;
556       counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
557       buffer = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->buffer;
558       break;
559 
560     case SL_SE_HASH_SHA256:
561       blocksize = 64;
562       countersize = 64 / 32;
563       counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
564       buffer = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->buffer;
565       break;
566 
567 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
568     case SL_SE_HASH_SHA384:
569       blocksize = 128;
570       countersize = 128 / 32;
571       counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
572       buffer = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->buffer;
573       break;
574 
575     case SL_SE_HASH_SHA512:
576       blocksize = 128;
577       countersize = 128 / 32;
578       counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
579       buffer = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->buffer;
580       break;
581 #endif
582 
583     default:
584       return SL_STATUS_INVALID_PARAMETER;
585   }
586 
587   left = (counter[0] & (blocksize - 1));
588   fill = blocksize - left;
589 
590   counter[0] += input_len;
591 
592   // ripple counter
593   if ( counter[0] < input_len ) {
594     counter[1] += 1;
595 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
596     for (size_t i = 1; i < (countersize - 1); i++) {
597       if ( counter[i] == 0 ) {
598         counter[i + 1]++;
599       }
600     }
601 #else
602     (void)countersize;
603 #endif
604   }
605 
606   if ( (left > 0) && (input_len >= fill) ) {
607     memcpy( (void *) (buffer + left), input, fill);
608     status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, buffer, 1);
609     if (status != SL_STATUS_OK) {
610       return status;
611     }
612     input += fill;
613     input_len -= fill;
614     left = 0;
615   }
616 
617   if ( input_len >= blocksize ) {
618     blocks = input_len / blocksize;
619     status = se_cmd_hash_multipart_update(hash_type_ctx, cmd_ctx, input, blocks);
620     if (status != SL_STATUS_OK) {
621       return status;
622     }
623     input += blocksize * blocks;
624     input_len -= blocksize * blocks;
625   }
626 
627   if ( input_len > 0 ) {
628     memcpy( (void *) (buffer + left), input, input_len);
629   }
630 
631   return SL_STATUS_OK;
632 }
633 /***************************************************************************//**
634  *   Feeds an input buffer into an ongoing hash computation. Deprecated.
635  ******************************************************************************/
sl_se_hash_update(sl_se_hash_streaming_context_t * hash_ctx,const uint8_t * input,size_t input_len)636 sl_status_t sl_se_hash_update(sl_se_hash_streaming_context_t *hash_ctx,
637                               const uint8_t *input,
638                               size_t input_len)
639 
640 {
641   if (hash_ctx == NULL) {
642     return SL_STATUS_INVALID_PARAMETER;
643   }
644 
645   switch (hash_ctx->hash_type) {
646     case SL_SE_HASH_SHA1:
647     {
648       sl_se_sha1_multipart_context_t hash_type_ctx_multi;
649 
650       memcpy(hash_type_ctx_multi.total, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
651       memcpy(hash_type_ctx_multi.state, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
652       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
653       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA1;
654       sl_status_t status =  sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
655       if (status != SL_STATUS_OK) {
656         return status;
657       }
658       memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
659       memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
660       memcpy(((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
661       break;
662     }
663     case SL_SE_HASH_SHA224:
664     {
665       sl_se_sha224_multipart_context_t hash_type_ctx_multi;
666       memcpy(hash_type_ctx_multi.total, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
667       memcpy(hash_type_ctx_multi.state, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
668       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
669       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA224;
670       sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
671       if (status != SL_STATUS_OK) {
672         return status;
673       }
674       memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
675       memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
676       memcpy(((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
677 
678       break;
679     }
680     case SL_SE_HASH_SHA256:
681     {
682       sl_se_sha256_multipart_context_t hash_type_ctx_multi;
683 
684       memcpy(hash_type_ctx_multi.total, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
685       memcpy(hash_type_ctx_multi.state, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
686       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
687       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA256;
688       sl_status_t status =  sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
689       if (status != SL_STATUS_OK) {
690         return status;
691       }
692       memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
693       memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
694       memcpy(((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
695       break;
696     }
697 
698 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
699     case SL_SE_HASH_SHA384:
700     {
701       sl_se_sha384_multipart_context_t hash_type_ctx_multi;
702 
703       memcpy(hash_type_ctx_multi.total, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
704       memcpy(hash_type_ctx_multi.state, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
705       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
706       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA384;
707       sl_status_t status =  sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
708       if (status != SL_STATUS_OK) {
709         return status;
710       }
711       memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
712       memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
713       memcpy(((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
714       break;
715     }
716     case SL_SE_HASH_SHA512:
717     {
718       sl_se_sha512_multipart_context_t hash_type_ctx_multi;
719 
720       memcpy(hash_type_ctx_multi.total, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
721       memcpy(hash_type_ctx_multi.state, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
722       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
723       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA512;
724       sl_status_t status = sl_se_hash_multipart_update((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, input, input_len);
725       if (status != SL_STATUS_OK) {
726         return status;
727       }
728       memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, hash_type_ctx_multi.total, sizeof(hash_type_ctx_multi.total));
729       memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, hash_type_ctx_multi.buffer, sizeof(hash_type_ctx_multi.buffer));
730       memcpy(((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, hash_type_ctx_multi.state, sizeof(hash_type_ctx_multi.state));
731 
732       break;
733     }
734   #endif
735     default:
736       return SL_STATUS_INVALID_PARAMETER;
737   }
738   return SL_STATUS_OK;
739 }
740 
741 /***************************************************************************//**
742  *   Finish an ongoing hash streaming computation.
743  ******************************************************************************/
sl_se_hash_multipart_finish(void * hash_type_ctx,sl_se_command_context_t * cmd_ctx,uint8_t * digest_out,size_t digest_len)744 sl_status_t sl_se_hash_multipart_finish(void *hash_type_ctx,
745                                         sl_se_command_context_t *cmd_ctx,
746                                         uint8_t *digest_out,
747                                         size_t   digest_len)
748 {
749   size_t last_data_byte, num_pad_bytes, blocksize, countersize, outputsize;
750   uint8_t msglen[16];
751   uint32_t *counter;
752   uint8_t *state;
753   // Define padding as largest padding we might need
754   #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
755   static const unsigned char sha_padding[128] = {
756     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
757     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
758     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
759     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
760     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
761     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
762     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
763     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
764   };
765   #else
766   static const unsigned char sha_padding[64] = {
767     0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
768     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
769     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
770     0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
771   };
772   #endif
773 
774   if (hash_type_ctx == NULL || cmd_ctx == NULL || digest_out == NULL) {
775     return SL_STATUS_INVALID_PARAMETER;
776   }
777 
778   switch (((sl_se_sha1_multipart_context_t*)hash_type_ctx)->hash_type) {
779     case SL_SE_HASH_SHA1:
780       blocksize = 64;
781       outputsize = 20;
782       countersize = 64 / 32;
783       counter = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->total;
784       state = ((sl_se_sha1_multipart_context_t*)hash_type_ctx)->state;
785       break;
786 
787     case SL_SE_HASH_SHA224:
788       blocksize = 64;
789       outputsize = 28;
790       countersize = 64 / 32;
791       counter = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->total;
792       state = ((sl_se_sha224_multipart_context_t*)hash_type_ctx)->state;
793       break;
794 
795     case SL_SE_HASH_SHA256:
796       blocksize = 64;
797       outputsize = 32;
798       countersize = 64 / 32;
799       counter = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->total;
800       state = ((sl_se_sha256_multipart_context_t*)hash_type_ctx)->state;
801       break;
802 
803 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
804     case SL_SE_HASH_SHA384:
805       blocksize = 128;
806       outputsize = 48;
807       countersize = 128 / 32;
808       counter = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->total;
809       state = ((sl_se_sha384_multipart_context_t*)hash_type_ctx)->state;
810       break;
811 
812     case SL_SE_HASH_SHA512:
813       blocksize = 128;
814       outputsize = 64;
815       countersize = 128 / 32;
816       counter = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->total;
817       state = ((sl_se_sha512_multipart_context_t*)hash_type_ctx)->state;
818       break;
819 #endif
820 
821     default:
822       return SL_STATUS_INVALID_PARAMETER;
823   }
824 
825   if ( digest_len < outputsize ) {
826     return SL_STATUS_INVALID_PARAMETER;
827   }
828 
829   /* Convert counter value to bits, and put in big-endian array */
830   uint8_t residual = 0;
831   for (size_t i = 0; i < countersize; i++) {
832     size_t msglen_index = ( (countersize - i) * sizeof(uint32_t) ) - 1;
833 
834     msglen[msglen_index - 0] = ((counter[i] << 3) + residual) & 0xFF;
835     msglen[msglen_index - 1] = (counter[i] >> 5) & 0xFF;
836     msglen[msglen_index - 2] = (counter[i] >> 13) & 0xFF;
837     msglen[msglen_index - 3] = (counter[i] >> 21) & 0xFF;
838 
839     residual = (counter[i] >> 29) & 0xFF;
840   }
841 
842   last_data_byte = (counter[0] & (blocksize - 1) );
843   num_pad_bytes = (last_data_byte < (blocksize - (countersize * 4)) )
844                   ? ( (blocksize - (countersize * 4)) - last_data_byte)
845                   : ( ((2 * blocksize) - (countersize * 4)) - last_data_byte);
846 
847   sl_status_t status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, sha_padding, num_pad_bytes);
848 
849   if (status == SL_STATUS_OK) {
850     status = sl_se_hash_multipart_update(hash_type_ctx, cmd_ctx, msglen, countersize * 4);
851   }
852 
853   if (status == SL_STATUS_OK) {
854     memcpy(digest_out, state, outputsize);
855   }
856 
857   return status;
858 }
859 
860 /***************************************************************************//**
861  *   Finish an ongoing hash streaming computation. Deprecated.
862  ******************************************************************************/
sl_se_hash_finish(sl_se_hash_streaming_context_t * hash_ctx,uint8_t * digest_out,size_t digest_len)863 sl_status_t sl_se_hash_finish(sl_se_hash_streaming_context_t *hash_ctx,
864                               uint8_t *digest_out,
865                               size_t   digest_len)
866 {
867   if (hash_ctx == NULL) {
868     return SL_STATUS_INVALID_PARAMETER;
869   }
870 
871   switch (hash_ctx->hash_type) {
872     case SL_SE_HASH_SHA1:
873     {
874       sl_se_sha1_multipart_context_t hash_type_ctx_multi;
875       memcpy(hash_type_ctx_multi.total, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
876       memcpy(hash_type_ctx_multi.state, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
877       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha1_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
878 
879       hash_type_ctx_multi.hash_type = SL_SE_HASH_SHA1;
880       return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
881       break;
882     }
883     case SL_SE_HASH_SHA224:
884     {
885       sl_se_sha224_multipart_context_t hash_type_ctx_multi;
886       memcpy(hash_type_ctx_multi.total, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
887       memcpy(hash_type_ctx_multi.state, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
888       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha224_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
889       hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
890       return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
891 
892       break;
893     }
894     case SL_SE_HASH_SHA256:
895     {
896       sl_se_sha256_multipart_context_t hash_type_ctx_multi;
897 
898       memcpy(hash_type_ctx_multi.total, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
899       memcpy(hash_type_ctx_multi.state, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
900       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha256_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
901       hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
902       return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
903 
904       break;
905     }
906 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
907     case SL_SE_HASH_SHA384:
908     {
909       sl_se_sha384_multipart_context_t hash_type_ctx_multi;
910 
911       memcpy(hash_type_ctx_multi.total, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
912       memcpy(hash_type_ctx_multi.state, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
913       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha384_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
914       hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
915       return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
916 
917       break;
918     }
919     case SL_SE_HASH_SHA512:
920     {
921       sl_se_sha512_multipart_context_t hash_type_ctx_multi;
922 
923       memcpy(hash_type_ctx_multi.total, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->total, sizeof(hash_type_ctx_multi.total));
924       memcpy(hash_type_ctx_multi.state, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->state, sizeof(hash_type_ctx_multi.state));
925       memcpy(hash_type_ctx_multi.buffer, ((sl_se_sha512_streaming_context_t*)hash_ctx->hash_type_ctx)->buffer, sizeof(hash_type_ctx_multi.buffer));
926       hash_type_ctx_multi.hash_type = hash_ctx->hash_type;
927       return sl_se_hash_multipart_finish((void*)&hash_type_ctx_multi, hash_ctx->cmd_ctx, digest_out, digest_len);
928       break;
929     }
930   #endif
931 
932     default:
933       return SL_STATUS_INVALID_PARAMETER;
934   }
935 }
936 
937 /***************************************************************************//**
938  *   Produce a message digest (a hash block) using the input data.
939  ******************************************************************************/
sl_se_hash(sl_se_command_context_t * cmd_ctx,sl_se_hash_type_t hash_type,const uint8_t * message,unsigned int message_size,uint8_t * digest,size_t digest_len)940 sl_status_t sl_se_hash(sl_se_command_context_t *cmd_ctx,
941                        sl_se_hash_type_t hash_type,
942                        const uint8_t *message,
943                        unsigned int message_size,
944                        uint8_t* digest,
945                        size_t digest_len)
946 {
947   if (cmd_ctx == NULL
948       || digest == NULL
949       || (message == NULL
950           && message_size != 0)) {
951     return SL_STATUS_INVALID_PARAMETER;
952   }
953 
954   SE_Command_t *se_cmd = &cmd_ctx->command;
955   uint32_t command_word = SE_COMMAND_HASH;
956   uint32_t digest_size = 0;
957 
958   switch (hash_type) {
959     case SL_SE_HASH_SHA1:
960       command_word |= SE_COMMAND_OPTION_HASH_SHA1;
961       digest_size = 20;
962       break;
963     case SL_SE_HASH_SHA224:
964       command_word |= SE_COMMAND_OPTION_HASH_SHA224;
965       digest_size = 28;
966       break;
967     case SL_SE_HASH_SHA256:
968       command_word |= SE_COMMAND_OPTION_HASH_SHA256;
969       digest_size = 32;
970       break;
971 #if (_SILICON_LABS_SECURITY_FEATURE == _SILICON_LABS_SECURITY_FEATURE_VAULT)
972     case SL_SE_HASH_SHA384:
973       command_word |= SE_COMMAND_OPTION_HASH_SHA384;
974       digest_size = 48;
975       break;
976     case SL_SE_HASH_SHA512:
977       digest_size = 64;
978       command_word |= SE_COMMAND_OPTION_HASH_SHA512;
979       break;
980 #endif
981     default:
982       return SL_STATUS_INVALID_PARAMETER;
983   }
984 
985   if ( digest_len < digest_size ) {
986     return SL_STATUS_INVALID_PARAMETER;
987   }
988 
989   sli_se_command_init(cmd_ctx, command_word);
990 
991   SE_addParameter(se_cmd, message_size);
992 
993   SE_DataTransfer_t data_in = SE_DATATRANSFER_DEFAULT(message, message_size);
994   SE_DataTransfer_t data_out = SE_DATATRANSFER_DEFAULT(digest, digest_size);
995 
996   SE_addDataInput(se_cmd, &data_in);
997   SE_addDataOutput(se_cmd, &data_out);
998 
999   // Execute and wait
1000   return sli_se_execute_and_wait(cmd_ctx);
1001 }
1002 
1003 /** @} (end addtogroup sl_se) */
1004 
1005 #endif // defined(SEMAILBOX_PRESENT)
1006