1 /* pic32mz-crypt.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
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26
27 #include <wolfssl/wolfcrypt/settings.h>
28
29 #ifdef WOLFSSL_MICROCHIP_PIC32MZ
30
31 #ifdef NO_INLINE
32 #include <wolfssl/wolfcrypt/misc.h>
33 #else
34 #define WOLFSSL_MISC_INCLUDED
35 #include <wolfcrypt/src/misc.c>
36 #endif
37
38 #include <wolfssl/wolfcrypt/logging.h>
39 #include <wolfssl/wolfcrypt/error-crypt.h>
40
41 #include <wolfssl/wolfcrypt/port/pic32/pic32mz-crypt.h>
42
43 #ifdef WOLFSSL_PIC32MZ_CRYPT
44 #include <wolfssl/wolfcrypt/aes.h>
45 #include <wolfssl/wolfcrypt/des3.h>
46 #endif
47
48 #ifdef WOLFSSL_PIC32MZ_HASH
49 #include <wolfssl/wolfcrypt/md5.h>
50 #include <wolfssl/wolfcrypt/sha.h>
51 #include <wolfssl/wolfcrypt/sha256.h>
52 #endif
53
54
55 #if defined(WOLFSSL_PIC32MZ_CRYPT) || defined(WOLFSSL_PIC32MZ_HASH)
56
Pic32GetBlockSize(int algo)57 static int Pic32GetBlockSize(int algo)
58 {
59 switch (algo) {
60 case PIC32_ALGO_HMAC1:
61 return PIC32_BLOCKSIZE_HMAC;
62 case PIC32_ALGO_SHA256:
63 return PIC32_BLOCKSIZE_SHA256;
64 case PIC32_ALGO_SHA1:
65 return PIC32_BLOCKSIZE_SHA1;
66 case PIC32_ALGO_MD5:
67 return PIC32_BLOCKSIZE_MD5;
68 case PIC32_ALGO_AES:
69 return PIC32_BLOCKSIZE_AES;
70 case PIC32_ALGO_TDES:
71 return PIC32_BLOCKSIZE_TDES;
72 case PIC32_ALGO_DES:
73 return PIC32_BLOCKSIZE_DES;
74 }
75 return 0;
76 }
77
Pic32Crypto(const byte * pIn,int inLen,word32 * pOut,int outLen,int dir,int algo,int cryptoalgo,word32 * key,int keyLen,word32 * iv,int ivLen)78 static int Pic32Crypto(const byte* pIn, int inLen, word32* pOut, int outLen,
79 int dir, int algo, int cryptoalgo,
80
81 /* For DES/AES only */
82 word32* key, int keyLen, word32* iv, int ivLen)
83 {
84 int ret = 0;
85 int blockSize = Pic32GetBlockSize(algo);
86 volatile bufferDescriptor bd __attribute__((aligned (8)));
87 securityAssociation sa __attribute__((aligned (8)));
88 securityAssociation *sa_p;
89 bufferDescriptor *bd_p;
90 byte *in_p;
91 byte *out_p;
92 word32* dst;
93 word32 padRemain;
94 int timeout = 0xFFFFFF;
95 word32* in = (word32*)pIn;
96 word32* out = pOut;
97 int isDynamic = 0;
98
99 /* check args */
100 if (in == NULL || inLen <= 0 || out == NULL || blockSize == 0) {
101 return BAD_FUNC_ARG;
102 }
103
104 /* check pointer alignment - must be word aligned */
105 if (((size_t)in % sizeof(word32)) || ((size_t)out % sizeof(word32))) {
106 /* dynamically allocate aligned pointers */
107 isDynamic = 1;
108 in = (word32*)XMALLOC(inLen, NULL, DYNAMIC_TYPE_AES_BUFFER);
109 if (in == NULL)
110 return MEMORY_E;
111 if ((word32*)pIn == pOut) /* inline */
112 out = (word32*)in;
113 else {
114 out = (word32*)XMALLOC(outLen, NULL, DYNAMIC_TYPE_AES_BUFFER);
115 if (out == NULL) {
116 XFREE(in, NULL, DYNAMIC_TYPE_AES_BUFFER);
117 return MEMORY_E;
118 }
119 }
120 XMEMCPY(in, pIn, inLen);
121 }
122
123 /* get uncached address */
124 sa_p = KVA0_TO_KVA1(&sa);
125 bd_p = KVA0_TO_KVA1(&bd);
126 out_p= KVA0_TO_KVA1(out);
127 in_p = KVA0_TO_KVA1(in);
128
129 /* Sync cache if in physical memory (not flash) */
130 if (PIC32MZ_IF_RAM(in_p)) {
131 XMEMCPY(in_p, in, inLen);
132 }
133
134 /* Set up the Security Association */
135 XMEMSET(sa_p, 0, sizeof(sa));
136 sa_p->SA_CTRL.ALGO = algo;
137 sa_p->SA_CTRL.ENCTYPE = dir;
138 sa_p->SA_CTRL.FB = 1; /* first block */
139 sa_p->SA_CTRL.LNC = 1; /* Load new set of keys */
140 if (key) {
141 /* cipher */
142 sa_p->SA_CTRL.CRYPTOALGO = cryptoalgo;
143
144 switch (keyLen) {
145 case 32:
146 sa_p->SA_CTRL.KEYSIZE = PIC32_KEYSIZE_256;
147 break;
148 case 24:
149 case 8: /* DES */
150 sa_p->SA_CTRL.KEYSIZE = PIC32_KEYSIZE_192;
151 break;
152 case 16:
153 sa_p->SA_CTRL.KEYSIZE = PIC32_KEYSIZE_128;
154 break;
155 }
156
157 dst = (word32*)KVA0_TO_KVA1(sa.SA_ENCKEY +
158 (sizeof(sa.SA_ENCKEY)/sizeof(word32)) - (keyLen/sizeof(word32)));
159 ByteReverseWords(dst, key, keyLen);
160
161 if (iv && ivLen > 0) {
162 sa_p->SA_CTRL.LOADIV = 1;
163 dst = (word32*)KVA0_TO_KVA1(sa.SA_ENCIV +
164 (sizeof(sa.SA_ENCIV)/sizeof(word32)) - (ivLen/sizeof(word32)));
165 ByteReverseWords(dst, iv, ivLen);
166 }
167 }
168 else {
169 /* hashing */
170 sa_p->SA_CTRL.LOADIV = 1;
171 sa_p->SA_CTRL.IRFLAG = 0; /* immediate result for hashing */
172
173 dst = (word32*)KVA0_TO_KVA1(sa.SA_AUTHIV +
174 (sizeof(sa.SA_AUTHIV)/sizeof(word32)) - (outLen/sizeof(word32)));
175 ByteReverseWords(dst, out, outLen);
176 }
177
178 /* Set up the Buffer Descriptor */
179 XMEMSET(bd_p, 0, sizeof(bd));
180 bd_p->BD_CTRL.BUFLEN = inLen;
181 padRemain = (inLen % 4); /* make sure buffer is 4-byte multiple */
182 if (padRemain != 0) {
183 bd_p->BD_CTRL.BUFLEN += (4 - padRemain);
184 }
185 bd_p->BD_CTRL.SA_FETCH_EN = 1; /* Fetch the security association */
186 bd_p->BD_CTRL.PKT_INT_EN = 1; /* enable interrupt */
187 bd_p->BD_CTRL.LAST_BD = 1; /* last buffer desc in chain */
188 bd_p->BD_CTRL.LIFM = 1; /* last in frame */
189 bd_p->SA_ADDR = (unsigned int)KVA_TO_PA(&sa);
190 bd_p->SRCADDR = (unsigned int)KVA_TO_PA(in);
191 if (key) {
192 /* cipher */
193 if (in != out)
194 XMEMSET(out_p, 0, outLen); /* clear output buffer */
195 bd_p->DSTADDR = (unsigned int)KVA_TO_PA(out);
196 }
197 else {
198 /* hashing */
199 /* digest result returned in UPDPTR */
200 bd_p->UPDPTR = (unsigned int)KVA_TO_PA(out);
201 }
202 bd_p->NXTPTR = (unsigned int)KVA_TO_PA(&bd);
203 bd_p->MSGLEN = inLen; /* actual message size */
204 bd_p->BD_CTRL.DESC_EN = 1; /* enable this descriptor */
205
206 /* begin access to hardware */
207 ret = wolfSSL_CryptHwMutexLock();
208 if (ret == 0) {
209 /* Software Reset the Crypto Engine */
210 CECON = 1 << 6;
211 while (CECON);
212
213 /* Clear the interrupt flags */
214 CEINTSRC = 0xF;
215
216 /* Run the engine */
217 CEBDPADDR = (unsigned int)KVA_TO_PA(&bd);
218 CEINTEN = 0x07; /* enable DMA Packet Completion Interrupt */
219
220 /* input swap, enable BD fetch and start DMA */
221 #if PIC32_NO_OUT_SWAP
222 CECON = 0x25;
223 #else
224 CECON = 0xa5; /* bit 7 = enable out swap */
225 #endif
226
227 /* wait for operation to complete */
228 while (CEINTSRCbits.PKTIF == 0 && --timeout > 0) {};
229
230 /* Clear the interrupt flags */
231 CEINTSRC = 0xF;
232
233 /* check for errors */
234 if (CESTATbits.ERROP || timeout <= 0) {
235 #if 0
236 printf("PIC32 Crypto: ERROP %x, ERRPHASE %x, TIMEOUT %s\n",
237 CESTATbits.ERROP, CESTATbits.ERRPHASE, timeout <= 0 ? "yes" : "no");
238 #endif
239 ret = ASYNC_OP_E;
240 }
241
242 wolfSSL_CryptHwMutexUnLock();
243
244 /* copy result to output */
245 #if PIC32_NO_OUT_SWAP
246 /* swap bytes */
247 ByteReverseWords(out, (word32*)out_p, outLen);
248 #elif defined(_SYS_DEVCON_LOCAL_H)
249 /* sync cache */
250 SYS_DEVCON_DataCacheInvalidate((word32)out, outLen);
251 #else
252 XMEMCPY(out, out_p, outLen);
253 #endif
254 }
255
256 /* handle unaligned */
257 if (isDynamic) {
258 /* return result */
259 XMEMCPY(pOut, out, outLen);
260
261 /* free dynamic buffers */
262 XFREE(in, NULL, DYNAMIC_TYPE_AES_BUFFER);
263 if ((word32*)pIn != pOut)
264 XFREE(out, NULL, DYNAMIC_TYPE_AES_BUFFER);
265 }
266
267 return ret;
268 }
269 #endif /* WOLFSSL_PIC32MZ_CRYPT || WOLFSSL_PIC32MZ_HASH */
270
271
272 #ifdef WOLFSSL_PIC32MZ_HASH
273
274 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
275
276 /* tunable large hash block size */
277 #ifndef PIC32_BLOCK_SIZE
278 #define PIC32_BLOCK_SIZE 256
279 #endif
280
281 #define PIC32MZ_MIN_BLOCK 64
282 #define PIC32MZ_MAX_BLOCK (32*1024)
283
284 #ifndef PIC32MZ_MAX_BD
285 #define PIC32MZ_MAX_BD 2
286 #endif
287
288 #if PIC32_BLOCK_SIZE < PIC32MZ_MIN_BLOCK
289 #error Encryption block size must be at least 64 bytes.
290 #endif
291
292 /* Crypt Engine descriptor */
293 typedef struct {
294 int currBd;
295 int err;
296 unsigned int msgSize;
297 uint32_t processed;
298 uint32_t dbPtr;
299 int engine_ready;
300 volatile bufferDescriptor bd[PIC32MZ_MAX_BD] __attribute__((aligned (8)));
301 securityAssociation sa __attribute__((aligned (8)));
302 } pic32mz_desc;
303
304 static pic32mz_desc gLHDesc __attribute__((coherent));
305 static uint8_t gLHDataBuf[PIC32MZ_MAX_BD][PIC32_BLOCK_SIZE] __attribute__((aligned (4), coherent));
306
reset_engine(int algo)307 static void reset_engine(int algo)
308 {
309 int i;
310
311 wolfSSL_CryptHwMutexLock();
312
313 /* Software reset */
314 CECON = 1 << 6;
315 while (CECON);
316
317 /* Clear the interrupt flags */
318 CEINTSRC = 0xF;
319
320 /* Make sure everything is clear first before we setup */
321 XMEMSET(&gLHDesc, 0, sizeof(pic32mz_desc));
322
323 /* Set up the Security Association */
324 gLHDesc.sa.SA_CTRL.ALGO = algo;
325 gLHDesc.sa.SA_CTRL.LNC = 1;
326 gLHDesc.sa.SA_CTRL.FB = 1;
327 gLHDesc.sa.SA_CTRL.ENCTYPE = 1;
328 gLHDesc.sa.SA_CTRL.LOADIV = 1;
329
330 /* Set up the Buffer Descriptor */
331 gLHDesc.err = 0;
332 for (i = 0; i < PIC32MZ_MAX_BD; i++) {
333 XMEMSET((void *)&gLHDesc.bd[i], 0, sizeof(gLHDesc.bd[i]));
334 gLHDesc.bd[i].BD_CTRL.LAST_BD = 1;
335 gLHDesc.bd[i].BD_CTRL.LIFM = 1;
336 gLHDesc.bd[i].BD_CTRL.PKT_INT_EN = 1;
337 gLHDesc.bd[i].SA_ADDR = KVA_TO_PA(&gLHDesc.sa);
338 gLHDesc.bd[i].SRCADDR = KVA_TO_PA(&gLHDataBuf[i]);
339 if (PIC32MZ_MAX_BD > i+1)
340 gLHDesc.bd[i].NXTPTR = KVA_TO_PA(&gLHDesc.bd[i+1]);
341 else
342 gLHDesc.bd[i].NXTPTR = KVA_TO_PA(&gLHDesc.bd[0]);
343 XMEMSET((void *)&gLHDataBuf[i], 0, PIC32_BLOCK_SIZE);
344 }
345 gLHDesc.bd[0].BD_CTRL.SA_FETCH_EN = 1; /* Fetch the security association on the first BD */
346 gLHDesc.dbPtr = 0;
347 gLHDesc.currBd = 0;
348 gLHDesc.msgSize = 0;
349 gLHDesc.processed = 0;
350 CEBDPADDR = KVA_TO_PA(&(gLHDesc.bd[0]));
351
352 CEPOLLCON = 10;
353
354 #if PIC32_NO_OUT_SWAP
355 CECON = 0x27;
356 #else
357 CECON = 0xa7;
358 #endif
359 }
360
update_engine(const byte * input,word32 len,word32 * hash)361 static void update_engine(const byte *input, word32 len, word32 *hash)
362 {
363 int total;
364
365 gLHDesc.bd[gLHDesc.currBd].UPDPTR = KVA_TO_PA(hash);
366
367 /* Add the data to the current buffer. If the buffer fills, start processing it
368 and fill the next one. */
369 while (len) {
370 /* If we've been given the message size, we can process along the
371 way.
372 Enable the current buffer descriptor if it is full. */
373 if (gLHDesc.dbPtr >= PIC32_BLOCK_SIZE) {
374 /* Wrap up the buffer descriptor and enable it so the engine can process */
375 gLHDesc.bd[gLHDesc.currBd].MSGLEN = gLHDesc.msgSize;
376 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.BUFLEN = gLHDesc.dbPtr;
377 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LAST_BD = 0;
378 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LIFM = 0;
379 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN = 1;
380 /* Move to the next buffer descriptor, or wrap around. */
381 gLHDesc.currBd++;
382 if (gLHDesc.currBd >= PIC32MZ_MAX_BD)
383 gLHDesc.currBd = 0;
384 /* Wait until the engine has processed the new BD. */
385 while (gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN);
386 gLHDesc.bd[gLHDesc.currBd].UPDPTR = KVA_TO_PA(hash);
387 gLHDesc.dbPtr = 0;
388 }
389 if (!PIC32MZ_IF_RAM(input)) {
390 /* If we're inputting from flash, let the BD have
391 the address and max the buffer size */
392 gLHDesc.bd[gLHDesc.currBd].SRCADDR = KVA_TO_PA(input);
393 total = (len > PIC32MZ_MAX_BLOCK ? PIC32MZ_MAX_BLOCK : len);
394 gLHDesc.dbPtr = total;
395 len -= total;
396 input += total;
397 }
398 else {
399 if (len > PIC32_BLOCK_SIZE - gLHDesc.dbPtr) {
400 /* We have more data than can be put in the buffer. Fill what we can.*/
401 total = PIC32_BLOCK_SIZE - gLHDesc.dbPtr;
402 XMEMCPY(&gLHDataBuf[gLHDesc.currBd][gLHDesc.dbPtr], input, total);
403 len -= total;
404 gLHDesc.dbPtr = PIC32_BLOCK_SIZE;
405 input += total;
406 }
407 else {
408 /* Fill up what we have, but don't turn on the engine.*/
409 XMEMCPY(&gLHDataBuf[gLHDesc.currBd][gLHDesc.dbPtr], input, len);
410 gLHDesc.dbPtr += len;
411 len = 0;
412 }
413 }
414 }
415 }
416
start_engine(void)417 static void start_engine(void)
418 {
419 /* Wrap up the last buffer descriptor and enable it */
420 int bufferLen;
421
422 bufferLen = gLHDesc.dbPtr;
423 if (bufferLen % 4)
424 bufferLen = (bufferLen + 4) - (bufferLen % 4);
425 /* initialize the MSGLEN on engine startup to avoid infinite loop when
426 * length is less than 257 (size of PIC32_BLOCK_SIZE) */
427 gLHDesc.bd[gLHDesc.currBd].MSGLEN = gLHDesc.msgSize;
428 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.BUFLEN = bufferLen;
429 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LAST_BD = 1;
430 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.LIFM = 1;
431 gLHDesc.bd[gLHDesc.currBd].BD_CTRL.DESC_EN = 1;
432 }
433
wait_engine(char * hash,int hash_sz)434 void wait_engine(char *hash, int hash_sz)
435 {
436 int i;
437 unsigned int engineRunning;
438
439 do {
440 engineRunning = 0;
441 for (i = 0; i < PIC32MZ_MAX_BD; i++) {
442 engineRunning = engineRunning || gLHDesc.bd[i].BD_CTRL.DESC_EN;
443 }
444 } while (engineRunning);
445
446 #if PIC32_NO_OUT_SWAP
447 /* swap bytes */
448 ByteReverseWords(hash, KVA0_TO_KVA1(hash), hash_sz);
449 #else
450 /* copy output - hardware already swapped */
451 XMEMCPY(hash, KVA0_TO_KVA1(hash), hash_sz);
452 #endif
453
454 wolfSSL_CryptHwMutexUnLock();
455 }
456
457 #endif /* WOLFSSL_PIC32MZ_LARGE_HASH */
458
wc_Pic32Hash(const byte * in,int inLen,word32 * out,int outLen,int algo)459 int wc_Pic32Hash(const byte* in, int inLen, word32* out, int outLen, int algo)
460 {
461 return Pic32Crypto(in, inLen, out, outLen, PIC32_ENCRYPTION, algo, 0,
462 NULL, 0, NULL, 0);
463 }
464
wc_Pic32HashCopy(hashUpdCache * src,hashUpdCache * dst)465 int wc_Pic32HashCopy(hashUpdCache* src, hashUpdCache* dst)
466 {
467 /* mark destination as copy, so cache->buf is not free'd */
468 if (dst) {
469 dst->isCopy = 1;
470 }
471 return 0;
472 }
473
wc_Pic32HashUpdate(hashUpdCache * cache,byte * stdBuf,int stdBufLen,word32 * digest,int digestSz,const byte * data,int len,int algo,void * heap)474 static int wc_Pic32HashUpdate(hashUpdCache* cache, byte* stdBuf, int stdBufLen,
475 word32* digest, int digestSz, const byte* data, int len, int algo, void* heap)
476 {
477 int ret = 0;
478 word32 newLenUpd, newLenPad, padRemain;
479 byte* newBuf;
480 int isNewBuf = 0;
481
482 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
483 /* if final length is set then pass straight to hardware */
484 if (cache->finalLen) {
485 if (cache->bufLen == 0) {
486 reset_engine(algo);
487 gLHDesc.msgSize = cache->finalLen;
488 }
489 update_engine(data, len, digest);
490 cache->bufLen += len; /* track progress for blockType */
491 return 0;
492 }
493 #endif
494
495 /* cache updates */
496 /* calculate new len */
497 newLenUpd = cache->updLen + len;
498
499 /* calculate padded len - pad buffer at 64-bytes for hardware */
500 newLenPad = newLenUpd;
501 padRemain = (newLenUpd % PIC32_BLOCKSIZE_HASH);
502 if (padRemain != 0) {
503 newLenPad += (PIC32_BLOCKSIZE_HASH - padRemain);
504 }
505
506 /* determine buffer source */
507 if (newLenPad <= stdBufLen) {
508 /* use standard buffer */
509 newBuf = stdBuf;
510 }
511 else if (newLenPad > cache->bufLen) {
512 /* alloc buffer */
513 newBuf = (byte*)XMALLOC(newLenPad, heap, DYNAMIC_TYPE_HASH_TMP);
514 if (newBuf == NULL) {
515 if (cache->buf != stdBuf && !cache->isCopy) {
516 XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
517 cache->buf = NULL;
518 cache->updLen = cache->bufLen = 0;
519 }
520 return MEMORY_E;
521 }
522 isNewBuf = 1;
523 cache->isCopy = 0; /* no longer using copy buffer */
524 }
525 else {
526 /* use existing buffer */
527 newBuf = cache->buf;
528 }
529 if (cache->buf && cache->updLen > 0) {
530 XMEMCPY(newBuf, cache->buf, cache->updLen);
531 if (isNewBuf && cache->buf != stdBuf) {
532 XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
533 cache->buf = NULL;
534 }
535 }
536 XMEMCPY(newBuf + cache->updLen, data, len);
537
538 cache->buf = newBuf;
539 cache->updLen = newLenUpd;
540 cache->bufLen = newLenPad;
541
542 return ret;
543 }
544
wc_Pic32HashFinal(hashUpdCache * cache,byte * stdBuf,word32 * digest,byte * hash,int digestSz,int algo,void * heap)545 static int wc_Pic32HashFinal(hashUpdCache* cache, byte* stdBuf,
546 word32* digest, byte* hash, int digestSz, int algo, void* heap)
547 {
548 int ret = 0;
549
550 /* if room add the pad */
551 if (cache->buf && cache->updLen < cache->bufLen) {
552 cache->buf[cache->updLen] = 0x80;
553 }
554
555 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
556 if (cache->finalLen) {
557 /* Only submit to hardware if update data provided matches expected */
558 if (cache->bufLen == cache->finalLen) {
559 start_engine();
560 wait_engine((char*)digest, digestSz);
561 XMEMCPY(hash, digest, digestSz);
562 }
563 else {
564 wolfSSL_CryptHwMutexUnLock();
565 ret = BUFFER_E;
566 }
567 cache->finalLen = 0;
568 }
569 else
570 #endif
571 {
572 if (cache->updLen == 0) {
573 /* handle empty input */
574 switch (algo) {
575 case PIC32_ALGO_SHA256: {
576 const char* sha256EmptyHash =
577 "\xe3\xb0\xc4\x42\x98\xfc\x1c\x14\x9a\xfb\xf4\xc8\x99\x6f\xb9"
578 "\x24\x27\xae\x41\xe4\x64\x9b\x93\x4c\xa4\x95\x99\x1b\x78\x52"
579 "\xb8\x55";
580 XMEMCPY(hash, sha256EmptyHash, digestSz);
581 break;
582 }
583 case PIC32_ALGO_SHA1: {
584 const char* shaEmptyHash =
585 "\xda\x39\xa3\xee\x5e\x6b\x4b\x0d\x32\x55\xbf\xef\x95\x60\x18"
586 "\x90\xaf\xd8\x07\x09";
587 XMEMCPY(hash, shaEmptyHash, digestSz);
588 break;
589 }
590 case PIC32_ALGO_MD5: {
591 const char* md5EmptyHash =
592 "\xd4\x1d\x8c\xd9\x8f\x00\xb2\x04\xe9\x80\x09\x98\xec\xf8\x42"
593 "\x7e";
594 XMEMCPY(hash, md5EmptyHash, digestSz);
595 break;
596 }
597 } /* switch */
598 }
599 else {
600 ret = wc_Pic32Hash(cache->buf, cache->updLen, digest, digestSz, algo);
601 if (ret == 0) {
602 XMEMCPY(hash, digest, digestSz);
603 }
604 }
605
606 if (cache->buf && cache->buf != stdBuf && !cache->isCopy) {
607 XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
608 cache->buf = NULL;
609 }
610 }
611
612 cache->buf = NULL;
613 cache->bufLen = cache->updLen = 0;
614
615 return ret;
616 }
617
wc_Pic32HashFree(hashUpdCache * cache,void * heap)618 static void wc_Pic32HashFree(hashUpdCache* cache, void* heap)
619 {
620 if (cache && cache->buf && !cache->isCopy) {
621 XFREE(cache->buf, heap, DYNAMIC_TYPE_HASH_TMP);
622 cache->buf = NULL;
623 }
624 }
625
626 /* API's for compatibility with Harmony wrappers - not used */
627 #ifndef NO_MD5
wc_InitMd5_ex(wc_Md5 * md5,void * heap,int devId)628 int wc_InitMd5_ex(wc_Md5* md5, void* heap, int devId)
629 {
630 if (md5 == NULL)
631 return BAD_FUNC_ARG;
632
633 XMEMSET(md5, 0, sizeof(wc_Md5));
634 md5->heap = heap;
635 (void)devId;
636 return 0;
637 }
wc_Md5Update(wc_Md5 * md5,const byte * data,word32 len)638 int wc_Md5Update(wc_Md5* md5, const byte* data, word32 len)
639 {
640 if (md5 == NULL || (data == NULL && len > 0))
641 return BAD_FUNC_ARG;
642 return wc_Pic32HashUpdate(&md5->cache, (byte*)md5->buffer,
643 sizeof(md5->buffer), md5->digest, MD5_DIGEST_SIZE,
644 data, len, PIC32_ALGO_MD5, md5->heap);
645 }
wc_Md5Final(wc_Md5 * md5,byte * hash)646 int wc_Md5Final(wc_Md5* md5, byte* hash)
647 {
648 int ret;
649
650 if (md5 == NULL || hash == NULL)
651 return BAD_FUNC_ARG;
652
653 ret = wc_Pic32HashFinal(&md5->cache, (byte*)md5->buffer,
654 md5->digest, hash, MD5_DIGEST_SIZE,
655 PIC32_ALGO_MD5, md5->heap);
656
657 wc_InitMd5_ex(md5, md5->heap, INVALID_DEVID); /* reset state */
658
659 return ret;
660 }
wc_Md5SizeSet(wc_Md5 * md5,word32 len)661 void wc_Md5SizeSet(wc_Md5* md5, word32 len)
662 {
663 if (md5) {
664 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
665 md5->cache.finalLen = len;
666 #else
667 (void)len;
668 #endif
669 }
670 }
wc_Md5Pic32Free(wc_Md5 * md5)671 void wc_Md5Pic32Free(wc_Md5* md5)
672 {
673 if (md5) {
674 wc_Pic32HashFree(&md5->cache, md5->heap);
675 }
676 }
677 #endif /* !NO_MD5 */
678 #ifndef NO_SHA
wc_InitSha_ex(wc_Sha * sha,void * heap,int devId)679 int wc_InitSha_ex(wc_Sha* sha, void* heap, int devId)
680 {
681 if (sha == NULL)
682 return BAD_FUNC_ARG;
683
684 XMEMSET(sha, 0, sizeof(wc_Sha));
685 sha->heap = heap;
686 (void)devId;
687 return 0;
688 }
wc_ShaUpdate(wc_Sha * sha,const byte * data,word32 len)689 int wc_ShaUpdate(wc_Sha* sha, const byte* data, word32 len)
690 {
691 if (sha == NULL || (data == NULL && len > 0))
692 return BAD_FUNC_ARG;
693 return wc_Pic32HashUpdate(&sha->cache, (byte*)sha->buffer,
694 sizeof(sha->buffer), sha->digest, SHA_DIGEST_SIZE,
695 data, len, PIC32_ALGO_SHA1, sha->heap);
696 }
wc_ShaFinal(wc_Sha * sha,byte * hash)697 int wc_ShaFinal(wc_Sha* sha, byte* hash)
698 {
699 int ret;
700
701 if (sha == NULL || hash == NULL)
702 return BAD_FUNC_ARG;
703
704 ret = wc_Pic32HashFinal(&sha->cache, (byte*)sha->buffer,
705 sha->digest, hash, SHA_DIGEST_SIZE,
706 PIC32_ALGO_SHA1, sha->heap);
707
708 wc_InitSha_ex(sha, sha->heap, INVALID_DEVID); /* reset state */
709
710 return ret;
711 }
wc_ShaSizeSet(wc_Sha * sha,word32 len)712 void wc_ShaSizeSet(wc_Sha* sha, word32 len)
713 {
714 if (sha) {
715 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
716 sha->cache.finalLen = len;
717 #else
718 (void)len;
719 #endif
720 }
721 }
wc_ShaPic32Free(wc_Sha * sha)722 void wc_ShaPic32Free(wc_Sha* sha)
723 {
724 if (sha) {
725 wc_Pic32HashFree(&sha->cache, sha->heap);
726 }
727 }
728 #endif /* !NO_SHA */
729 #ifndef NO_SHA256
wc_InitSha256_ex(wc_Sha256 * sha256,void * heap,int devId)730 int wc_InitSha256_ex(wc_Sha256* sha256, void* heap, int devId)
731 {
732 if (sha256 == NULL)
733 return BAD_FUNC_ARG;
734
735 XMEMSET(sha256, 0, sizeof(wc_Sha256));
736 sha256->heap = heap;
737 (void)devId;
738 return 0;
739 }
wc_Sha256Update(wc_Sha256 * sha256,const byte * data,word32 len)740 int wc_Sha256Update(wc_Sha256* sha256, const byte* data, word32 len)
741 {
742 if (sha256 == NULL || (data == NULL && len > 0))
743 return BAD_FUNC_ARG;
744 return wc_Pic32HashUpdate(&sha256->cache, (byte*)sha256->buffer,
745 sizeof(sha256->buffer), sha256->digest, SHA256_DIGEST_SIZE,
746 data, len, PIC32_ALGO_SHA256, sha256->heap);
747 }
wc_Sha256Final(wc_Sha256 * sha256,byte * hash)748 int wc_Sha256Final(wc_Sha256* sha256, byte* hash)
749 {
750 int ret;
751
752 if (sha256 == NULL || hash == NULL)
753 return BAD_FUNC_ARG;
754
755 ret = wc_Pic32HashFinal(&sha256->cache, (byte*)sha256->buffer,
756 sha256->digest, hash, SHA256_DIGEST_SIZE,
757 PIC32_ALGO_SHA256, sha256->heap);
758
759 wc_InitSha256_ex(sha256, sha256->heap, INVALID_DEVID); /* reset state */
760
761 return ret;
762 }
wc_Sha256SizeSet(wc_Sha256 * sha256,word32 len)763 void wc_Sha256SizeSet(wc_Sha256* sha256, word32 len)
764 {
765 if (sha256) {
766 #ifdef WOLFSSL_PIC32MZ_LARGE_HASH
767 sha256->cache.finalLen = len;
768 #else
769 (void)len;
770 #endif
771 }
772 }
wc_Sha256Pic32Free(wc_Sha256 * sha256)773 void wc_Sha256Pic32Free(wc_Sha256* sha256)
774 {
775 if (sha256) {
776 wc_Pic32HashFree(&sha256->cache, sha256->heap);
777 }
778 }
779 #endif /* !NO_SHA256 */
780 #endif /* WOLFSSL_PIC32MZ_HASH */
781
782
783 #ifdef WOLFSSL_PIC32MZ_CRYPT
784 #if !defined(NO_AES)
wc_Pic32AesCrypt(word32 * key,int keyLen,word32 * iv,int ivLen,byte * out,const byte * in,word32 sz,int dir,int algo,int cryptoalgo)785 int wc_Pic32AesCrypt(word32 *key, int keyLen, word32 *iv, int ivLen,
786 byte* out, const byte* in, word32 sz,
787 int dir, int algo, int cryptoalgo)
788 {
789 return Pic32Crypto(in, sz, (word32*)out, sz, dir, algo, cryptoalgo,
790 key, keyLen, iv, ivLen);
791 }
792 #endif /* !NO_AES */
793
794 #ifndef NO_DES3
wc_Pic32DesCrypt(word32 * key,int keyLen,word32 * iv,int ivLen,byte * out,const byte * in,word32 sz,int dir,int algo,int cryptoalgo)795 int wc_Pic32DesCrypt(word32 *key, int keyLen, word32 *iv, int ivLen,
796 byte* out, const byte* in, word32 sz,
797 int dir, int algo, int cryptoalgo)
798 {
799 return Pic32Crypto(in, sz, (word32*)out, sz, dir, algo, cryptoalgo,
800 key, keyLen, iv, ivLen);
801 }
802 #endif /* !NO_DES3 */
803 #endif /* WOLFSSL_PIC32MZ_CRYPT */
804
805 #endif /* WOLFSSL_MICROCHIP_PIC32MZ */
806