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