npcm_sha.c 35 KB

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