blob: 7ebdfa16f4fcd37d25cd1b87e59edd40edf041de [file] [log] [blame]
Jim Liu74dbae22022-06-07 16:32:09 +08001// SPDX-License-Identifier: GPL-2.0+
2/*
3 * Copyright (c) 2022 Nuvoton Technology Corp.
4 */
5
Tom Riniabb9a042024-05-18 20:20:43 -06006#include <common.h>
Jim Liu74dbae22022-06-07 16:32:09 +08007#include <dm.h>
8#include <hash.h>
9#include <malloc.h>
10#include <uboot_aes.h>
11#include <asm/io.h>
12
13#define HASH_DIG_H_NUM 8
14
15#define HASH_CTR_STS_SHA_EN BIT(0)
16#define HASH_CTR_STS_SHA_BUSY BIT(1)
17#define HASH_CTR_STS_SHA_RST BIT(2)
18#define HASH_CFG_SHA1_SHA2 BIT(0)
19
20/* SHA type */
21enum npcm_sha_type {
22 npcm_sha_type_sha2 = 0,
23 npcm_sha_type_sha1,
24 npcm_sha_type_num
25};
26
27struct npcm_sha_regs {
28 unsigned int hash_data_in;
29 unsigned char hash_ctr_sts;
30 unsigned char reserved_0[0x03];
31 unsigned char hash_cfg;
32 unsigned char reserved_1[0x03];
33 unsigned char hash_ver;
34 unsigned char reserved_2[0x13];
35 unsigned int hash_dig[HASH_DIG_H_NUM];
36};
37
38struct npcm_sha_priv {
39 struct npcm_sha_regs *regs;
40};
41
42static struct npcm_sha_priv *sha_priv;
43
44#ifdef SHA_DEBUG_MODULE
45#define sha_print(fmt, args...) printf(fmt, ##args)
46#else
47#define sha_print(fmt, args...) (void)0
48#endif
49
50#define SHA_BLOCK_LENGTH (512 / 8)
51#define SHA_2_HASH_LENGTH (256 / 8)
52#define SHA_1_HASH_LENGTH (160 / 8)
53#define SHA_HASH_LENGTH(type) ((type == npcm_sha_type_sha2) ? \
54 (SHA_2_HASH_LENGTH) : (SHA_1_HASH_LENGTH))
55
56#define SHA_SECRUN_BUFF_SIZE 64
57#define SHA_TIMEOUT 100
58#define SHA_DATA_LAST_BYTE 0x80
59
60#define SHA2_NUM_OF_SELF_TESTS 3
61#define SHA1_NUM_OF_SELF_TESTS 4
62
63#define NUVOTON_ALIGNMENT 4
64
65/*-----------------------------------------------------------------------------*/
66/* SHA instance struct handler */
67/*-----------------------------------------------------------------------------*/
68struct SHA_HANDLE_T {
69 u32 hv[SHA_2_HASH_LENGTH / sizeof(u32)];
70 u32 length0;
71 u32 length1;
72 u32 block[SHA_BLOCK_LENGTH / sizeof(u32)];
73 u8 type;
74 bool active;
75};
76
77// The # of bytes currently in the sha block buffer
78#define SHA_BUFF_POS(length) ((length) & (SHA_BLOCK_LENGTH - 1))
79
80// The # of free bytes in the sha block buffer
81#define SHA_BUFF_FREE(length) (SHA_BLOCK_LENGTH - SHA_BUFF_POS(length))
82
83static void SHA_FlushLocalBuffer_l(const u32 *buff);
84static int SHA_BusyWait_l(void);
85static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type);
86static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type);
87static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block);
88static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block);
89static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block);
90
91static int SHA_Init(struct SHA_HANDLE_T *handleptr);
92static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type);
93static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len);
94static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest);
95static int SHA_Reset(void);
96static int SHA_Power(bool on);
97#ifdef SHA_PRINT
98static void SHA_PrintRegs(void);
99static void SHA_PrintVersion(void);
100#endif
101
102static struct SHA_HANDLE_T sha_handle;
103
104/*----------------------------------------------------------------------------*/
105/* Checks if give function returns int error, and returns the error */
106/* immediately after SHA disabling */
107/*----------------------------------------------------------------------------*/
108int npcm_sha_check(int status)
109{
110 if (status != 0) {
111 SHA_Power(false);
112 return status;
113 }
114 return 0;
115}
116
117/*----------------------------------------------------------------------------*/
118/* Function: npcm_sha_calc */
119/* */
120/* Parameters: type - SHA module type */
121/* inBuff - Pointer to a buffer containing the data to */
122/* be hashed */
123/* len - Length of the data to hash */
124/* hashDigest - Pointer to a buffer where the reseulting */
125/* digest will be copied to */
126/* */
127/* Returns: 0 on success or other int error code on error */
128/* Side effects: */
129/* Description: */
130/* This routine performs complete SHA calculation in one */
131/* step */
132/*----------------------------------------------------------------------------*/
133int npcm_sha_calc(u8 type, const u8 *inbuff, u32 len, u8 *hashdigest)
134{
135 int status;
136 struct SHA_HANDLE_T handle;
137
138 SHA_Init(&handle);
139 SHA_Power(true);
140 SHA_Reset();
141 SHA_Start(&handle, type);
142 status = SHA_Update(&handle, inbuff, len);
143 npcm_sha_check(status);
144 status = SHA_Finish(&handle, hashdigest);
145 npcm_sha_check(status);
146 SHA_Power(false);
147
148 return 0;
149}
150
151/*
152 * Computes hash value of input pbuf using h/w acceleration
153 *
154 * @param in_addr A pointer to the input buffer
155 * @param bufleni Byte length of input buffer
156 * @param out_addr A pointer to the output buffer. When complete
157 * 32 bytes are copied to pout[0]...pout[31]. Thus, a user
158 * should allocate at least 32 bytes at pOut in advance.
159 * @param chunk_size chunk size for sha256
160 */
161void hw_sha256(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
162{
163 puts("\nhw_sha256 using BMC HW accelerator\t");
164 npcm_sha_calc(npcm_sha_type_sha2, (u8 *)in_addr, buflen, (u8 *)out_addr);
165}
166
167/*
168 * Computes hash value of input pbuf using h/w acceleration
169 *
170 * @param in_addr A pointer to the input buffer
171 * @param bufleni Byte length of input buffer
172 * @param out_addr A pointer to the output buffer. When complete
173 * 32 bytes are copied to pout[0]...pout[31]. Thus, a user
174 * should allocate at least 32 bytes at pOut in advance.
175 * @param chunk_size chunk_size for sha1
176 */
177void hw_sha1(const uchar *in_addr, uint buflen, uchar *out_addr, uint chunk_size)
178{
179 puts("\nhw_sha1 using BMC HW accelerator\t");
180 npcm_sha_calc(npcm_sha_type_sha1, (u8 *)in_addr, buflen, (u8 *)out_addr);
181}
182
183/*
184 * Create the context for sha progressive hashing using h/w acceleration
185 *
186 * @algo: Pointer to the hash_algo struct
187 * @ctxp: Pointer to the pointer of the context for hashing
188 * @return 0 if ok, -ve on error
189 */
190int hw_sha_init(struct hash_algo *algo, void **ctxp)
191{
192 const char *algo_name1 = "sha1";
193 const char *algo_name2 = "sha256";
194
195 SHA_Init(&sha_handle);
196 SHA_Power(true);
197 SHA_Reset();
198 if (!strcmp(algo_name1, algo->name))
199 return SHA_Start(&sha_handle, npcm_sha_type_sha1);
200 else if (!strcmp(algo_name2, algo->name))
201 return SHA_Start(&sha_handle, npcm_sha_type_sha2);
202 else
203 return -EPROTO;
204}
205
206/*
207 * Update buffer for sha progressive hashing using h/w acceleration
208 *
209 * The context is freed by this function if an error occurs.
210 *
211 * @algo: Pointer to the hash_algo struct
212 * @ctx: Pointer to the context for hashing
213 * @buf: Pointer to the buffer being hashed
214 * @size: Size of the buffer being hashed
215 * @is_last: 1 if this is the last update; 0 otherwise
216 * @return 0 if ok, -ve on error
217 */
218int hw_sha_update(struct hash_algo *algo, void *ctx, const void *buf,
219 unsigned int size, int is_last)
220{
221 return SHA_Update(&sha_handle, buf, size);
222}
223
224/*
225 * Copy sha hash result at destination location
226 *
227 * The context is freed after completion of hash operation or after an error.
228 *
229 * @algo: Pointer to the hash_algo struct
230 * @ctx: Pointer to the context for hashing
231 * @dest_buf: Pointer to the destination buffer where hash is to be copied
232 * @size: Size of the buffer being hashed
233 * @return 0 if ok, -ve on error
234 */
235int hw_sha_finish(struct hash_algo *algo, void *ctx, void *dest_buf, int size)
236{
237 int status;
238
239 status = SHA_Finish(&sha_handle, dest_buf);
240 npcm_sha_check(status);
241 return SHA_Power(false);
242}
243
244/*----------------------------------------------------------------------------*/
245/* Function: SHA_Init */
246/* */
247/* Parameters: handlePtr - SHA processing handle pointer */
248/* Returns: 0 on success or other int error code on error. */
249/* Side effects: */
250/* Description: */
251/* This routine initialize the SHA module */
252/*----------------------------------------------------------------------------*/
253static int SHA_Init(struct SHA_HANDLE_T *handleptr)
254{
255 handleptr->active = false;
256
257 return 0;
258}
259
260/*----------------------------------------------------------------------------*/
261/* Function: SHA_Start */
262/* */
263/* Parameters: handlePtr - SHA processing handle pointer */
264/* type - SHA module type */
265/* */
266/* Returns: 0 on success or other int error code on error. */
267/* Side effects: */
268/* Description: */
269/* This routine start a single SHA process */
270/*----------------------------------------------------------------------------*/
271static int SHA_Start(struct SHA_HANDLE_T *handleptr, u8 type)
272{
273 struct npcm_sha_regs *regs = sha_priv->regs;
274
275 // Initialize handle
276 handleptr->length0 = 0;
277 handleptr->length1 = 0;
278 handleptr->type = type;
279 handleptr->active = true;
280
281 // Set SHA type
282 writeb(handleptr->type & HASH_CFG_SHA1_SHA2, &regs->hash_cfg);
283
284 // Reset SHA hardware
285 SHA_Reset();
286
287 /* The handlePtr->hv is initialized with the correct IV as the SHA engine
288 * automatically fill the HASH_DIG_Hn registers according to SHA spec
289 * (following SHA_RST assertion)
290 */
291 SHA_GetShaDigest_l((u8 *)handleptr->hv, type);
292
293 // Init block with zeros
294 memset(handleptr->block, 0, sizeof(handleptr->block));
295
296 return 0;
297}
298
299/*----------------------------------------------------------------------------*/
300/* Function: SHA_Update */
301/* */
302/* Parameters: handlePtr - SHA processing handle pointer */
303/* buffer - Pointer to the data that will be added to */
304/* the hash calculation */
305/* len - Length of data to add to SHA calculation */
306/* */
307/* */
308/* Returns: 0 on success or other int error code on error */
309/* Side effects: */
310/* Description: */
311/* This routine adds data to previously started SHA */
312/* calculation */
313/*----------------------------------------------------------------------------*/
314static int SHA_Update(struct SHA_HANDLE_T *handleptr, const u8 *buffer, u32 len)
315{
316 struct npcm_sha_regs *regs = sha_priv->regs;
317 u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
318 u32 bufferlen = len;
319 u16 pos = 0;
320 u8 *blockptr;
321 int status;
322
323 // Error check
324 if (!handleptr->active)
325 return -EPROTO;
326
327 // Wait till SHA is not busy
328 status = SHA_BusyWait_l();
329 npcm_sha_check(status);
330
331 // Set SHA type
332 writeb(handleptr->type & HASH_CFG_SHA1_SHA2, &regs->hash_cfg);
333
334 // Write SHA latest digest into SHA module
335 SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
336
337 // Set number of unhashed bytes which remained from last update
338 pos = SHA_BUFF_POS(handleptr->length0);
339
340 // Copy unhashed bytes which remained from last update to secrun buffer
341 SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
342
343 while (len) {
344 // Wait for the hardware to be available (in case we are hashing)
345 status = SHA_BusyWait_l();
346 npcm_sha_check(status);
347
348 // Move as much bytes as we can into the secrun buffer
349 bufferlen = min(len, SHA_BUFF_FREE(handleptr->length0));
350
351 // Copy current given buffer to the secrun buffer
352 SHA_SetBlock_l((u8 *)buffer, bufferlen, pos, localbuffer);
353
354 // Update size of hashed bytes
355 handleptr->length0 += bufferlen;
356
357 if (handleptr->length0 < bufferlen)
358 handleptr->length1++;
359
360 // Update length of data left to digest
361 len -= bufferlen;
362
363 // Update given buffer pointer
364 buffer += bufferlen;
365
366 // If secrun buffer is full
367 if (SHA_BUFF_POS(handleptr->length0) == 0) {
368 /* We just filled up the buffer perfectly, so let it hash (we'll
369 * unload the hash only when we are done with all hashing)
370 */
371 SHA_FlushLocalBuffer_l(localbuffer);
372
373 pos = 0;
374 bufferlen = 0;
375 }
376 }
377
378 // Wait till SHA is not busy
379 status = SHA_BusyWait_l();
380 npcm_sha_check(status);
381
382 /* Copy unhashed bytes from given buffer to handle block for next update/finish */
383 blockptr = (u8 *)handleptr->block;
384 while (bufferlen)
385 blockptr[--bufferlen + pos] = *(--buffer);
386
387 // Save SHA current digest
388 SHA_GetShaDigest_l((u8 *)handleptr->hv, handleptr->type);
389
390 return 0;
391}
392
393/*----------------------------------------------------------------------------*/
394/* Function: SHA_Finish */
395/* */
396/* Parameters: handlePtr - SHA processing handle pointer */
397/* hashDigest - Pointer to a buffer where the final digest */
398/* will be copied to */
399/* */
400/* Returns: 0 on success or other int error code on error */
401/* Side effects: */
402/* Description: */
403/* This routine finish SHA calculation and get */
404/* the resulting SHA digest */
405/*----------------------------------------------------------------------------*/
406static int SHA_Finish(struct SHA_HANDLE_T *handleptr, u8 *hashdigest)
407{
408 struct npcm_sha_regs *regs = sha_priv->regs;
409 u32 localbuffer[SHA_SECRUN_BUFF_SIZE / sizeof(u32)];
410 const u8 lastbyte = SHA_DATA_LAST_BYTE;
411 u16 pos;
412 int status;
413
414 // Error check
415 if (!handleptr->active)
416 return -EPROTO;
417
418 // Set SHA type
419 writeb(handleptr->type & HASH_CFG_SHA1_SHA2, &regs->hash_cfg);
420
421 // Wait till SHA is not busy
422 status = SHA_BusyWait_l();
423 npcm_sha_check(status);
424
425 // Finish off the current buffer with the SHA spec'ed padding
426 pos = SHA_BUFF_POS(handleptr->length0);
427
428 // Init SHA digest
429 SHA_SetShaDigest_l(handleptr->hv, handleptr->type);
430
431 // Load data into secrun buffer
432 SHA_SetBlock_l((u8 *)handleptr->block, pos, 0, localbuffer);
433
434 // Set data last byte as in SHA algorithm spec
435 SHA_SetBlock_l(&lastbyte, 1, pos++, localbuffer);
436
437 // If the remainder of data is longer then one block
438 if (pos > (SHA_BLOCK_LENGTH - 8)) {
439 /* The length will be in the next block Pad the rest of the last block with 0's */
440 SHA_ClearBlock_l((SHA_BLOCK_LENGTH - pos), pos, localbuffer);
441
442 // Hash the current block
443 SHA_FlushLocalBuffer_l(localbuffer);
444
445 pos = 0;
446
447 // Wait till SHA is not busy
448 status = SHA_BusyWait_l();
449 npcm_sha_check(status);
450 }
451
452 // Pad the rest of the last block with 0's except for the last 8-3 bytes
453 SHA_ClearBlock_l((SHA_BLOCK_LENGTH - (8 - 3)) - pos, pos, localbuffer);
454
455 /* The last 8-3 bytes are set to the bit-length of the message in big-endian form */
456 SHA_SetLength32_l(handleptr, localbuffer);
457
458 // Hash all that, and save the hash for the caller
459 SHA_FlushLocalBuffer_l(localbuffer);
460
461 // Wait till SHA is not busy
462 status = SHA_BusyWait_l();
463 npcm_sha_check(status);
464
465 // Save SHA final digest into given buffer
466 SHA_GetShaDigest_l(hashdigest, handleptr->type);
467
468 // Free handle
469 handleptr->active = false;
470
471 return 0;
472}
473
474/*----------------------------------------------------------------------------*/
475/* Function: SHA_Reset */
476/* */
477/* Parameters: none */
478/* Returns: none */
479/* Side effects: */
480/* Description: */
481/* This routine reset SHA module */
482/*----------------------------------------------------------------------------*/
483static int SHA_Reset(void)
484{
485 struct npcm_sha_regs *regs = sha_priv->regs;
486
487 writel(readl(&regs->hash_ctr_sts) | HASH_CTR_STS_SHA_RST, &regs->hash_ctr_sts);
488
489 return 0;
490}
491
492/*----------------------------------------------------------------------------*/
493/* Function: SHA_Power */
494/* */
495/* Parameters: on - true enable the module, false disable the module */
496/* Returns: none */
497/* Side effects: */
498/* Description: */
499/* This routine set SHA module power on/off */
500/*----------------------------------------------------------------------------*/
501static int SHA_Power(bool on)
502{
503 struct npcm_sha_regs *regs = sha_priv->regs;
504 u8 hash_sts;
505
506 hash_sts = readb(&regs->hash_ctr_sts) & ~HASH_CTR_STS_SHA_EN;
507 writeb(hash_sts | (on & HASH_CTR_STS_SHA_EN), &regs->hash_ctr_sts);
508
509 return 0;
510}
511
512#ifdef SHA_PRINT
513/*----------------------------------------------------------------------------*/
514/* Function: SHA_PrintRegs */
515/* */
516/* Parameters: none */
517/* Returns: none */
518/* Side effects: */
519/* Description: */
520/* This routine prints the module registers */
521/*----------------------------------------------------------------------------*/
522static void SHA_PrintRegs(void)
523{
524#ifdef SHA_DEBUG_MODULE
525 struct npcm_sha_regs *regs = sha_priv->regs;
526#endif
527 unsigned int i;
528
529 sha_print("/*--------------*/\n");
530 sha_print("/* SHA */\n");
531 sha_print("/*--------------*/\n\n");
532
533 sha_print("HASH_CTR_STS = 0x%02X\n", readb(&regs->hash_ctr_sts));
534 sha_print("HASH_CFG = 0x%02X\n", readb(&regs->hash_cfg));
535
536 for (i = 0; i < HASH_DIG_H_NUM; i++)
537 sha_print("HASH_DIG_H%d = 0x%08X\n", i, readl(&regs->hash_dig[i]));
538
539 sha_print("HASH_VER = 0x%08X\n", readb(&regs->hash_ver));
540
541 sha_print("\n");
542}
543
544/*----------------------------------------------------------------------------*/
545/* Function: SHA_PrintVersion */
546/* */
547/* Parameters: none */
548/* Returns: none */
549/* Side effects: */
550/* Description: */
551/* This routine prints the module version */
552/*----------------------------------------------------------------------------*/
553static void SHA_PrintVersion(void)
554{
555 struct npcm_sha_regs *regs = sha_priv->regs;
556
557 printf("SHA MODULE VER = %d\n", readb(&regs->hash_ver));
558}
559#endif
560
561/*----------------------------------------------------------------------------*/
562/* Function: npcm_sha_selftest */
563/* */
564/* Parameters: type - SHA module type */
565/* Returns: 0 on success or other int error code on error */
566/* Side effects: */
567/* Description: */
568/* This routine performs various tests on the SHA HW and SW */
569/*----------------------------------------------------------------------------*/
570int npcm_sha_selftest(u8 type)
571{
572 int status;
573 struct SHA_HANDLE_T handle;
574 u8 hashdigest[max(SHA_1_HASH_LENGTH, SHA_2_HASH_LENGTH)];
575 u16 i, j;
576
577 /*------------------------------------------------------------------------*/
578 /* SHA1 tests info */
579 /*------------------------------------------------------------------------*/
580
581 static const u8 sha1selftestbuff[SHA1_NUM_OF_SELF_TESTS][94] = {
582 {"abc"},
583 {"abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"},
584 {"0123456789012345678901234567890123456789012345678901234567890123"},
585 {0x30, 0x5c, 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b,
586 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a,
587 0x01, 0x0c, 0x04, 0x14, 0xe1, 0xb6, 0x93, 0xfe, 0x33, 0x43, 0xc1, 0x20,
588 0x5d, 0x4b, 0xaa, 0xb8, 0x63, 0xfb, 0xcf, 0x6c, 0x46, 0x1e, 0x88, 0x04,
589 0x30, 0x2c, 0x02, 0x01, 0x00, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03,
590 0x02, 0x1a, 0x05, 0x00, 0x30, 0x06, 0x06, 0x04, 0x67, 0x2a, 0x01, 0x0c,
591 0x04, 0x14, 0x13, 0xc1, 0x0c, 0xfc, 0xc8, 0x92, 0xd7, 0xde, 0x07, 0x1c,
592 0x40, 0xde, 0x4f, 0xcd, 0x07, 0x5b, 0x68, 0x20, 0x5a, 0x6c}
593 };
594
595 static const u8 sha1selftestbufflen[SHA1_NUM_OF_SELF_TESTS] = {
596 3, 56, 64, 94
597 };
598
599 static const u8 sha1selftestexpres[SHA1_NUM_OF_SELF_TESTS][SHA_1_HASH_LENGTH] = {
600 {0xA9, 0x99, 0x3E, 0x36,
601 0x47, 0x06, 0x81, 0x6A,
602 0xBA, 0x3E, 0x25, 0x71,
603 0x78, 0x50, 0xC2, 0x6C,
604 0x9C, 0xD0, 0xD8, 0x9D},
605 {0x84, 0x98, 0x3E, 0x44,
606 0x1C, 0x3B, 0xD2, 0x6E,
607 0xBA, 0xAE, 0x4A, 0xA1,
608 0xF9, 0x51, 0x29, 0xE5,
609 0xE5, 0x46, 0x70, 0xF1},
610 {0xCF, 0x08, 0x00, 0xF7,
611 0x64, 0x4A, 0xCE, 0x3C,
612 0xB4, 0xC3, 0xFA, 0x33,
613 0x38, 0x8D, 0x3B, 0xA0,
614 0xEA, 0x3C, 0x8B, 0x6E},
615 {0xc9, 0x84, 0x45, 0xc8,
616 0x64, 0x04, 0xb1, 0xe3,
617 0x3c, 0x6b, 0x0a, 0x8c,
618 0x8b, 0x80, 0x94, 0xfc,
619 0xf3, 0xc9, 0x98, 0xab}
620 };
621
622 /*------------------------------------------------------------------------*/
623 /* SHA2 tests info */
624 /*------------------------------------------------------------------------*/
625
626 static const u8 sha2selftestbuff[SHA2_NUM_OF_SELF_TESTS][100] = {
627 { "abc" },
628 { "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq" },
629 {'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
630 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
631 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
632 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
633 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
634 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
635 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
636 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
637 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a',
638 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a', 'a'}
639 };
640
641 static const u8 sha2selftestbufflen[SHA2_NUM_OF_SELF_TESTS] = {
642 3, 56, 100
643 };
644
645 static const u8 sha2selftestexpres[SHA2_NUM_OF_SELF_TESTS][SHA_2_HASH_LENGTH] = {
646 /*
647 * SHA-256 test vectors
648 */
649 { 0xBA, 0x78, 0x16, 0xBF, 0x8F, 0x01, 0xCF, 0xEA,
650 0x41, 0x41, 0x40, 0xDE, 0x5D, 0xAE, 0x22, 0x23,
651 0xB0, 0x03, 0x61, 0xA3, 0x96, 0x17, 0x7A, 0x9C,
652 0xB4, 0x10, 0xFF, 0x61, 0xF2, 0x00, 0x15, 0xAD },
653 { 0x24, 0x8D, 0x6A, 0x61, 0xD2, 0x06, 0x38, 0xB8,
654 0xE5, 0xC0, 0x26, 0x93, 0x0C, 0x3E, 0x60, 0x39,
655 0xA3, 0x3C, 0xE4, 0x59, 0x64, 0xFF, 0x21, 0x67,
656 0xF6, 0xEC, 0xED, 0xD4, 0x19, 0xDB, 0x06, 0xC1 },
657 { 0xCD, 0xC7, 0x6E, 0x5C, 0x99, 0x14, 0xFB, 0x92,
658 0x81, 0xA1, 0xC7, 0xE2, 0x84, 0xD7, 0x3E, 0x67,
659 0xF1, 0x80, 0x9A, 0x48, 0xA4, 0x97, 0x20, 0x0E,
660 0x04, 0x6D, 0x39, 0xCC, 0xC7, 0x11, 0x2C, 0xD0 },
661 };
662
663 if (type == npcm_sha_type_sha1) {
664 /*--------------------------------------------------------------------*/
665 /* SHA 1 TESTS */
666 /*--------------------------------------------------------------------*/
667 for (i = 0; i < SHA1_NUM_OF_SELF_TESTS; i++) {
668 if (i != 3) {
669 status = npcm_sha_calc(npcm_sha_type_sha1, sha1selftestbuff[i], sha1selftestbufflen[i], hashdigest);
670 npcm_sha_check(status);
671 } else {
672 SHA_Power(true);
673 SHA_Reset();
674 status = SHA_Start(&handle, npcm_sha_type_sha1);
675 npcm_sha_check(status);
676 status = SHA_Update(&handle, sha1selftestbuff[i], 73);
677 npcm_sha_check(status);
678 status = SHA_Update(&handle, &sha1selftestbuff[i][73], sha1selftestbufflen[i] - 73);
679 npcm_sha_check(status);
680 status = SHA_Finish(&handle, hashdigest);
681 npcm_sha_check(status);
682 SHA_Power(false);
683 }
684
685 if (memcmp(hashdigest, sha1selftestexpres[i], SHA_1_HASH_LENGTH))
686 return -1;
687 }
688
689 } else {
690 /*--------------------------------------------------------------------*/
691 /* SHA 2 TESTS */
692 /*--------------------------------------------------------------------*/
693 for (i = 0; i < SHA2_NUM_OF_SELF_TESTS; i++) {
694 SHA_Power(true);
695 SHA_Reset();
696 status = SHA_Start(&handle, npcm_sha_type_sha2);
697 npcm_sha_check(status);
698 if (i == 2) {
699 for (j = 0; j < 10000; j++) { //not working
700 status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
701 npcm_sha_check(status);
702 }
703 } else {
704 status = SHA_Update(&handle, sha2selftestbuff[i], sha2selftestbufflen[i]);
705 npcm_sha_check(status);
706 }
707
708 status = SHA_Finish(&handle, hashdigest);
709 npcm_sha_check(status);
710 SHA_Power(false);
711 if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
712 return -1;
713
714 npcm_sha_calc(npcm_sha_type_sha2, sha2selftestbuff[i], sha2selftestbufflen[i], hashdigest);
715 if (memcmp(hashdigest, sha2selftestexpres[i], SHA_2_HASH_LENGTH))
716 return -1;
717 }
718 }
719
720 return 0;
721}
722
723/*----------------------------------------------------------------------------*/
724/* Function: SHA_FlushLocalBuffer_l */
725/* */
726/* Parameters: */
727/* Returns: none */
728/* Side effects: */
729/* Description: This routine flush secrun buffer to SHA module */
730/*----------------------------------------------------------------------------*/
731static void SHA_FlushLocalBuffer_l(const u32 *buff)
732{
733 struct npcm_sha_regs *regs = sha_priv->regs;
734 u32 i;
735
736 for (i = 0; i < (SHA_BLOCK_LENGTH / sizeof(u32)); i++)
737 writel(buff[i], &regs->hash_data_in);
738}
739
740/*----------------------------------------------------------------------------*/
741/* Function: SHA_BusyWait_l */
742/* */
743/* Parameters: */
744/* Returns: 0 if no error was found or DEFS_STATUS_ERROR otherwise */
745/* Side effects: */
746/* Description: This routine wait for SHA unit to no longer be busy */
747/*----------------------------------------------------------------------------*/
748static int SHA_BusyWait_l(void)
749{
750 struct npcm_sha_regs *regs = sha_priv->regs;
751 u32 timeout = SHA_TIMEOUT;
752
753 do {
754 if (timeout-- == 0)
755 return -ETIMEDOUT;
756 } while ((readb(&regs->hash_ctr_sts) & HASH_CTR_STS_SHA_BUSY)
757 == HASH_CTR_STS_SHA_BUSY);
758
759 return 0;
760}
761
762/*----------------------------------------------------------------------------*/
763/* Function: SHA_GetShaDigest_l */
764/* */
765/* Parameters: hashDigest - buffer for the hash output. */
766/* type - SHA module type */
767/* Returns: none */
768/* Side effects: */
769/* Description: This routine copy the hash digest from the hardware */
770/* and into given buffer (in ram) */
771/*----------------------------------------------------------------------------*/
772static void SHA_GetShaDigest_l(u8 *hashdigest, u8 type)
773{
774 struct npcm_sha_regs *regs = sha_priv->regs;
775 u16 j;
776 u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
777
778 // Copy Bytes from SHA module to given buffer
779 for (j = 0; j < len; j++)
780 ((u32 *)hashdigest)[j] = readl(&regs->hash_dig[j]);
781}
782
783/*----------------------------------------------------------------------------*/
784/* Function: SHA_SetShaDigest_l */
785/* */
786/* Parameters: hashDigest - input buffer to set as hash digest */
787/* type - SHA module type */
788/* Returns: none */
789/* Side effects: */
790/* Description: This routine set the hash digest in the hardware from */
791/* a given buffer (in ram) */
792/*----------------------------------------------------------------------------*/
793static void SHA_SetShaDigest_l(const u32 *hashdigest, u8 type)
794{
795 struct npcm_sha_regs *regs = sha_priv->regs;
796 u16 j;
797 u8 len = SHA_HASH_LENGTH(type) / sizeof(u32);
798
799 // Copy Bytes from given buffer to SHA module
800 for (j = 0; j < len; j++)
801 writel(hashdigest[j], &regs->hash_dig[j]);
802}
803
804/*----------------------------------------------------------------------------*/
805/* Function: SHA_SetBlock_l */
806/* */
807/* Parameters: data - data to copy */
808/* len - size of data */
809/* position - byte offset into the block at which data */
810/* should be placed */
811/* block - block buffer */
812/* Returns: none */
813/* Side effects: */
814/* Description: This routine load bytes into block buffer */
815/*----------------------------------------------------------------------------*/
816static void SHA_SetBlock_l(const u8 *data, u32 len, u16 position, u32 *block)
817{
818 u8 *dest = (u8 *)block;
819
820 memcpy(dest + position, data, len);
821}
822
823/*----------------------------------------------------------------------------*/
824/* Function: SHA_SetBlock_l */
825/* */
826/* Parameters: */
827/* len - size of data */
828/* position - byte offset into the block at which data */
829/* should be placed */
830/* block - block buffer */
831/* Returns: none */
832/* Side effects: */
833/* Description: This routine load zero's into the block buffer */
834/*----------------------------------------------------------------------------*/
835static void SHA_ClearBlock_l(u16 len, u16 position, u32 *block)
836{
837 u8 *dest = (u8 *)block;
838
839 memset(dest + position, 0, len);
840}
841
842/*----------------------------------------------------------------------------*/
843/* Function: SHA_SetLength32_l */
844/* */
845/* Parameters: */
846/* handlePtr - SHA processing handle pointer */
847/* block - block buffer */
848/* Returns: none */
849/* Side effects: */
850/* Description: This routine set the length of the hash's data */
851/* len is the 32-bit byte length of the message */
852/*lint -efunc(734,SHA_SetLength32_l) Supperess loss of percision lint warning */
853/*----------------------------------------------------------------------------*/
854static void SHA_SetLength32_l(struct SHA_HANDLE_T *handleptr, u32 *block)
855{
856 u16 *secrunbufferswappedptr = (u16 *)(void *)(block);
857
858 secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 1] = (u16)
859 ((handleptr->length0 << 3) << 8) | ((u16)(handleptr->length0 << 3) >> 8);
860 secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 2] = (u16)
861 ((handleptr->length0 >> (16 - 3)) >> 8) | ((u16)(handleptr->length0 >> (16 - 3)) << 8);
862 secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 3] = (u16)
863 ((handleptr->length1 << 3) << 8) | ((u16)(handleptr->length1 << 3) >> 8);
864 secrunbufferswappedptr[(SHA_BLOCK_LENGTH / sizeof(u16)) - 4] = (u16)
865 ((handleptr->length1 >> (16 - 3)) >> 8) | ((u16)(handleptr->length1 >> (16 - 3)) << 8);
866}
867
868static int npcm_sha_bind(struct udevice *dev)
869{
870 sha_priv = calloc(1, sizeof(struct npcm_sha_priv));
871 if (!sha_priv)
872 return -ENOMEM;
873
874 sha_priv->regs = dev_remap_addr_index(dev, 0);
875 if (!sha_priv->regs) {
876 printf("Cannot find sha reg address, binding failed\n");
877 return -EINVAL;
878 }
879
880 printf("SHA: NPCM SHA module bind OK\n");
881
882 return 0;
883}
884
885static const struct udevice_id npcm_sha_ids[] = {
886 { .compatible = "nuvoton,npcm845-sha" },
887 { .compatible = "nuvoton,npcm750-sha" },
888 { }
889};
890
891U_BOOT_DRIVER(npcm_sha) = {
892 .name = "npcm_sha",
893 .id = UCLASS_MISC,
894 .of_match = npcm_sha_ids,
895 .priv_auto = sizeof(struct npcm_sha_priv),
896 .bind = npcm_sha_bind,
897};