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