fsl_hashcrypt.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302
  1. /*
  2. * Copyright 2017-2018 NXP
  3. * All rights reserved.
  4. *
  5. * SPDX-License-Identifier: BSD-3-Clause
  6. */
  7. #include "fsl_hashcrypt.h"
  8. /*******************************************************************************
  9. * Definitions
  10. *******************************************************************************/
  11. /*!< SHA-1 and SHA-256 block size */
  12. #define SHA_BLOCK_SIZE 64
  13. /*!< max number of blocks that can be proccessed in one run (master mode) */
  14. #define SHA_MASTER_MAX_BLOCKS 2048
  15. /*!< Use standard C library memcpy */
  16. #define hashcrypt_memcpy memcpy
  17. /*! Internal states of the HASH creation process */
  18. typedef enum _hashcrypt_sha_algo_state
  19. {
  20. kHASHCRYPT_HashInit = 1u, /*!< Init state, the NEW bit in SHA Control register has not been written yet. */
  21. kHASHCRYPT_HashUpdate, /*!< Update state, DIGEST registers contain running hash, NEW bit in SHA control register has
  22. been written. */
  23. } hashcrypt_sha_algo_state_t;
  24. /*! 64-byte block represented as byte array of 16 32-bit words */
  25. typedef union _sha_hash_block
  26. {
  27. uint32_t w[SHA_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
  28. uint8_t b[SHA_BLOCK_SIZE]; /*!< byte array */
  29. } hashcrypt_sha_block_t;
  30. /*! internal sha context structure */
  31. typedef struct _hashcrypt_sha_ctx_internal
  32. {
  33. hashcrypt_sha_block_t blk; /*!< memory buffer. only full 64-byte blocks are written to SHA during hash updates */
  34. size_t blksz; /*!< number of valid bytes in memory buffer */
  35. hashcrypt_algo_t algo; /*!< selected algorithm from the set of supported algorithms */
  36. hashcrypt_sha_algo_state_t state; /*!< finite machine state of the hash software process */
  37. size_t fullMessageSize; /*!< track message size during SHA_Update(). The value is used for padding. */
  38. uint32_t remainingBlcks; /*!< number of remaining blocks to process in AHB master mode */
  39. hashcrypt_callback_t hashCallback; /*!< pointer to HASH callback function */
  40. void
  41. *userData; /*!< user data to be passed as an argument to callback function, once callback is invoked from isr */
  42. } hashcrypt_sha_ctx_internal_t;
  43. /*!< SHA-1 and SHA-256 digest length in bytes */
  44. enum _hashcrypt_sha_digest_len
  45. {
  46. kHASHCRYPT_OutLenSha1 = 20u,
  47. kHASHCRYPT_OutLenSha256 = 32u,
  48. };
  49. /*!< pointer to hash context structure used by isr */
  50. static hashcrypt_hash_ctx_t *s_ctx;
  51. /*!< macro for checking build time condition. It is used to assure the hashcrypt_sha_ctx_internal_t can fit into
  52. * hashcrypt_hash_ctx_t */
  53. #define BUILD_ASSERT(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
  54. /*******************************************************************************
  55. * Code
  56. ******************************************************************************/
  57. /*!
  58. * @brief Swap bytes withing 32-bit word.
  59. *
  60. * This function changes endianess of a 32-bit word.
  61. *
  62. * @param in 32-bit unsigned integer
  63. * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
  64. */
  65. #define swap_bytes(in) __REV(in)
  66. /*!
  67. * @brief Increment a 16 byte integer.
  68. *
  69. * This function increments by one a 16 byte integer.
  70. *
  71. * @param input Pointer to a 16 byte integer to be incremented by one.
  72. */
  73. static void ctrIncrement(uint8_t *input)
  74. {
  75. int i = 15;
  76. while (input[i] == (uint8_t)0xFFu)
  77. {
  78. input[i] = (uint8_t)0x00u;
  79. i--;
  80. if (i < 0)
  81. {
  82. return;
  83. }
  84. }
  85. if (i >= 0)
  86. {
  87. input[i] += (uint8_t)1u;
  88. }
  89. }
  90. /*!
  91. * @brief LDM to SHA engine INDATA and ALIAS registers.
  92. *
  93. * This function writes 16 words starting from the src address (must be word aligned)
  94. * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
  95. * Src address increments to load 16 consecutive words.
  96. *
  97. * @param dst peripheral register address (word aligned)
  98. * @param src address of the input 512-bit block (16 words) (word aligned)
  99. *
  100. */
  101. __STATIC_FORCEINLINE void hashcrypt_sha_ldm_stm_16_words(HASHCRYPT_Type *base, const uint32_t *src)
  102. {
  103. /*
  104. typedef struct _one_block
  105. {
  106. uint32_t a[8];
  107. } one_block_t;
  108. volatile one_block_t *ldst = (void *)(uintptr_t)(&base->INDATA);
  109. one_block_t *lsrc = (void *)(uintptr_t)src;
  110. *ldst = lsrc[0];
  111. *ldst = lsrc[1];
  112. */
  113. base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(src);
  114. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(1);
  115. }
  116. /*!
  117. * @brief Loads data to Hashcrypt engine INDATA register.
  118. *
  119. * This function writes desired number of bytes starting from the src address (must be word aligned)
  120. * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
  121. * Src address increments to load consecutive words.
  122. *
  123. * @param dst peripheral register address (word aligned)
  124. * @param src address of the input block (word aligned)
  125. * @param size number of bytes to write (word aligned)
  126. *
  127. */
  128. __STATIC_INLINE void hashcrypt_load_data(HASHCRYPT_Type *base, const uint32_t *src, size_t size)
  129. {
  130. if (size >= sizeof(uint32_t))
  131. {
  132. base->INDATA = src[0];
  133. size -= sizeof(uint32_t);
  134. }
  135. for (int i = 0; i < size / 4; i++)
  136. {
  137. base->ALIAS[i] = src[i + 1];
  138. }
  139. }
  140. /*!
  141. * @brief Read OUTDATA registers.
  142. *
  143. * This function copies OUTDATA to output buffer.
  144. *
  145. * @param base Hachcrypt peripheral base address.
  146. * @param[out] output Output buffer.
  147. * @param Number of bytes to copy.
  148. */
  149. static void hashcrypt_get_data(HASHCRYPT_Type *base, uint32_t *output, size_t outputSize)
  150. {
  151. uint32_t digest[8];
  152. while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
  153. {
  154. }
  155. for (int i = 0; i < 8; i++)
  156. {
  157. digest[i] = swap_bytes(base->OUTDATA0[i]);
  158. }
  159. if (outputSize > sizeof(digest))
  160. {
  161. outputSize = sizeof(digest);
  162. }
  163. hashcrypt_memcpy(output, digest, outputSize);
  164. }
  165. /*!
  166. * @brief Initialize the Hashcrypt engine for new operation.
  167. *
  168. * This function sets NEW and MODE fields in Hashcrypt Control register to start new operation.
  169. *
  170. * @param base Hashcrypt peripheral base address.
  171. * @param hashcrypt_algo_t Internal context.
  172. */
  173. static void hashcrypt_engine_init(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
  174. {
  175. /* NEW bit must be set before we switch from previous mode otherwise new mode will not work correctly */
  176. base->CTRL = HASHCRYPT_CTRL_NEW_HASH(1);
  177. base->CTRL = HASHCRYPT_CTRL_MODE(algo) | HASHCRYPT_CTRL_NEW_HASH(1);
  178. }
  179. /*!
  180. * @brief Loads user key to INDATA register.
  181. *
  182. * This function writes user key stored in handle into HashCrypt INDATA register.
  183. *
  184. * @param base Hashcrypt peripheral base address.
  185. * @param handle Handle used for this request.
  186. */
  187. static void hashcrypt_aes_load_userKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle)
  188. {
  189. size_t keySize = 0;
  190. switch (handle->keySize)
  191. {
  192. case kHASHCRYPT_Aes128:
  193. keySize = 16;
  194. break;
  195. case kHASHCRYPT_Aes192:
  196. keySize = 24;
  197. break;
  198. case kHASHCRYPT_Aes256:
  199. keySize = 32;
  200. break;
  201. default:
  202. break;
  203. }
  204. if (keySize == 0)
  205. {
  206. return;
  207. }
  208. hashcrypt_load_data(base, &handle->keyWord[0], keySize);
  209. }
  210. /*!
  211. * @brief Performs AES encryption/decryption of one data block.
  212. *
  213. * This function encrypts/decrypts one block of data with specified size.
  214. *
  215. * @param base Hashcrypt peripheral base address.
  216. * @param input input data
  217. * @param output output data
  218. * @param size size of data block to process in bytes (must be 16bytes multiple).
  219. */
  220. static status_t hashcrypt_aes_one_block(HASHCRYPT_Type *base, const uint8_t *input, uint8_t *output, size_t size)
  221. {
  222. status_t status = kStatus_Fail;
  223. int idx = 0;
  224. /* we use AHB master mode as much as possible */
  225. /* however, it can work only with aligned input data */
  226. /* so, if unaligned, we do memcpy to temp buffer on stack, which is aligned, and use AHB mode to read data in */
  227. /* then we read data back to it and do memcpy to the output buffer */
  228. if (((uint32_t)input & 0x3u) || ((uint32_t)output & 0x3u))
  229. {
  230. uint32_t temp[256 / sizeof(uint32_t)];
  231. int cnt = 0;
  232. while (size)
  233. {
  234. size_t actSz = size >= 256u ? 256u : size;
  235. size_t actSzOrig = actSz;
  236. memcpy(temp, input + 256 * cnt, actSz);
  237. size -= actSz;
  238. base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(temp);
  239. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(actSz / 16);
  240. int outidx = 0;
  241. while (actSz)
  242. {
  243. while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
  244. {
  245. }
  246. for (int i = 0; i < 4; i++)
  247. {
  248. (temp + outidx)[i] = swap_bytes(base->OUTDATA0[i]);
  249. }
  250. outidx += HASHCRYPT_AES_BLOCK_SIZE / 4;
  251. actSz -= HASHCRYPT_AES_BLOCK_SIZE;
  252. }
  253. memcpy(output + 256 * cnt, temp, actSzOrig);
  254. cnt++;
  255. }
  256. }
  257. else
  258. {
  259. base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(input);
  260. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(size / 16);
  261. while (size >= HASHCRYPT_AES_BLOCK_SIZE)
  262. {
  263. /* Get result */
  264. while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
  265. {
  266. }
  267. for (int i = 0; i < 4; i++)
  268. {
  269. ((uint32_t *)output + idx)[i] = swap_bytes(base->OUTDATA0[i]);
  270. }
  271. idx += HASHCRYPT_AES_BLOCK_SIZE / 4;
  272. size -= HASHCRYPT_AES_BLOCK_SIZE;
  273. }
  274. }
  275. if (0 == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
  276. {
  277. status = kStatus_Success;
  278. }
  279. return status;
  280. }
  281. /*!
  282. * @brief Check validity of algoritm.
  283. *
  284. * This function checks the validity of input argument.
  285. *
  286. * @param algo Tested algorithm value.
  287. * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
  288. */
  289. static status_t hashcrypt_sha_check_input_alg(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
  290. {
  291. if ((algo == kHASHCRYPT_Sha1) || (algo == kHASHCRYPT_Sha256))
  292. {
  293. return kStatus_Success;
  294. }
  295. if ((algo == kHASHCRYPT_Sha512) && (base->CONFIG & HASHCRYPT_CONFIG_SHA512_MASK))
  296. {
  297. return kStatus_Success;
  298. }
  299. return kStatus_InvalidArgument;
  300. }
  301. /*!
  302. * @brief Check validity of input arguments.
  303. *
  304. * This function checks the validity of input arguments.
  305. *
  306. * @param base SHA peripheral base address.
  307. * @param ctx Memory buffer given by user application where the SHA_Init/SHA_Update/SHA_Finish store context.
  308. * @param algo Tested algorithm value.
  309. * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
  310. */
  311. static status_t hashcrypt_sha_check_input_args(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
  312. {
  313. /* Check validity of input algorithm */
  314. if (kStatus_Success != hashcrypt_sha_check_input_alg(base, algo))
  315. {
  316. return kStatus_InvalidArgument;
  317. }
  318. if ((NULL == ctx) || (NULL == base))
  319. {
  320. return kStatus_InvalidArgument;
  321. }
  322. return kStatus_Success;
  323. }
  324. /*!
  325. * @brief Check validity of internal software context.
  326. *
  327. * This function checks if the internal context structure looks correct.
  328. *
  329. * @param ctxInternal Internal context.
  330. * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
  331. */
  332. static status_t hashcrypt_sha_check_context(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
  333. {
  334. if ((NULL == ctxInternal) || (kStatus_Success != hashcrypt_sha_check_input_alg(base, ctxInternal->algo)))
  335. {
  336. return kStatus_InvalidArgument;
  337. }
  338. return kStatus_Success;
  339. }
  340. /*!
  341. * @brief Load 512-bit block (16 words) into SHA engine.
  342. *
  343. * This function aligns the input block and moves it into SHA engine INDATA.
  344. * CPU polls the WAITING bit and then moves data by using LDM and STM instructions.
  345. *
  346. * @param base SHA peripheral base address.
  347. * @param blk 512-bit block
  348. */
  349. static void hashcrypt_sha_one_block(HASHCRYPT_Type *base, const uint8_t *blk)
  350. {
  351. uint32_t temp[SHA_BLOCK_SIZE / sizeof(uint32_t)];
  352. const uint32_t *actBlk;
  353. /* make sure the 512-bit block is word aligned */
  354. if ((uintptr_t)blk & 0x3u)
  355. {
  356. hashcrypt_memcpy(temp, blk, SHA_BLOCK_SIZE);
  357. actBlk = (const uint32_t *)(uintptr_t)temp;
  358. }
  359. else
  360. {
  361. actBlk = (const uint32_t *)(uintptr_t)blk;
  362. }
  363. /* poll waiting. */
  364. while (0 == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
  365. {
  366. }
  367. /* feed INDATA (and ALIASes). use STM instruction. */
  368. hashcrypt_sha_ldm_stm_16_words(base, actBlk);
  369. }
  370. /*!
  371. * @brief Adds message to current hash.
  372. *
  373. * This function merges the message to fill the internal buffer, empties the internal buffer if
  374. * it becomes full, then process all remaining message data.
  375. *
  376. *
  377. * @param base SHA peripheral base address.
  378. * @param ctxInternal Internal context.
  379. * @param message Input message.
  380. * @param messageSize Size of input message in bytes.
  381. * @return kStatus_Success.
  382. */
  383. static status_t hashcrypt_sha_process_message_data(HASHCRYPT_Type *base,
  384. hashcrypt_sha_ctx_internal_t *ctxInternal,
  385. const uint8_t *message,
  386. size_t messageSize)
  387. {
  388. /* first fill the internal buffer to full block */
  389. if (ctxInternal->blksz)
  390. {
  391. size_t toCopy = SHA_BLOCK_SIZE - ctxInternal->blksz;
  392. hashcrypt_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
  393. message += toCopy;
  394. messageSize -= toCopy;
  395. /* process full internal block */
  396. hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
  397. }
  398. /* process all full blocks in message[] */
  399. if (messageSize >= SHA_BLOCK_SIZE)
  400. {
  401. if ((uintptr_t)message & 0x3u)
  402. {
  403. while (messageSize >= SHA_BLOCK_SIZE)
  404. {
  405. hashcrypt_sha_one_block(base, message);
  406. message += SHA_BLOCK_SIZE;
  407. messageSize -= SHA_BLOCK_SIZE;
  408. }
  409. }
  410. else
  411. {
  412. /* poll waiting. */
  413. while (0 == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
  414. {
  415. }
  416. uint32_t blkNum = (messageSize >> 6); /* div by 64 bytes */
  417. uint32_t blkBytes = blkNum * 64u; /* number of bytes in 64 bytes blocks */
  418. base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(message);
  419. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(blkNum);
  420. message += blkBytes;
  421. messageSize -= blkBytes;
  422. while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
  423. {
  424. }
  425. }
  426. }
  427. /* copy last incomplete message bytes into internal block */
  428. hashcrypt_memcpy(&ctxInternal->blk.b[0], message, messageSize);
  429. ctxInternal->blksz = messageSize;
  430. return kStatus_Success;
  431. }
  432. /*!
  433. * @brief Finalize the running hash to make digest.
  434. *
  435. * This function empties the internal buffer, adds padding bits, and generates final digest.
  436. *
  437. * @param base SHA peripheral base address.
  438. * @param ctxInternal Internal context.
  439. * @return kStatus_Success.
  440. */
  441. static status_t hashcrypt_sha_finalize(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
  442. {
  443. hashcrypt_sha_block_t lastBlock;
  444. memset(&lastBlock, 0, sizeof(hashcrypt_sha_block_t));
  445. /* this is last call, so need to flush buffered message bytes along with padding */
  446. if (ctxInternal->blksz <= 55u)
  447. {
  448. /* last data is 440 bits or less. */
  449. hashcrypt_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
  450. lastBlock.b[ctxInternal->blksz] = (uint8_t)0x80U;
  451. lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
  452. hashcrypt_sha_one_block(base, &lastBlock.b[0]);
  453. }
  454. else
  455. {
  456. if (ctxInternal->blksz < SHA_BLOCK_SIZE)
  457. {
  458. ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
  459. for (uint32_t i = ctxInternal->blksz + 1u; i < SHA_BLOCK_SIZE; i++)
  460. {
  461. ctxInternal->blk.b[i] = 0;
  462. }
  463. }
  464. else
  465. {
  466. lastBlock.b[0] = (uint8_t)0x80U;
  467. }
  468. hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
  469. lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
  470. hashcrypt_sha_one_block(base, &lastBlock.b[0]);
  471. }
  472. /* poll wait for final digest */
  473. while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
  474. {
  475. }
  476. return kStatus_Success;
  477. }
  478. /*!
  479. * brief Create HASH on given data
  480. *
  481. * Perform the full SHA in one function call. The function is blocking.
  482. *
  483. * param base HASHCRYPT peripheral base address
  484. * param algo Underlaying algorithm to use for hash computation.
  485. * param input Input data
  486. * param inputSize Size of input data in bytes
  487. * param[out] output Output hash data
  488. * param[out] outputSize Output parameter storing the size of the output hash in bytes
  489. * return Status of the one call hash operation.
  490. */
  491. status_t HASHCRYPT_SHA(HASHCRYPT_Type *base,
  492. hashcrypt_algo_t algo,
  493. const uint8_t *input,
  494. size_t inputSize,
  495. uint8_t *output,
  496. size_t *outputSize)
  497. {
  498. hashcrypt_hash_ctx_t hashCtx;
  499. status_t status;
  500. status = HASHCRYPT_SHA_Init(base, &hashCtx, algo);
  501. if (status != kStatus_Success)
  502. {
  503. return status;
  504. }
  505. status = HASHCRYPT_SHA_Update(base, &hashCtx, input, inputSize);
  506. if (status != kStatus_Success)
  507. {
  508. return status;
  509. }
  510. status = HASHCRYPT_SHA_Finish(base, &hashCtx, output, outputSize);
  511. return status;
  512. }
  513. /*!
  514. * brief Initialize HASH context
  515. *
  516. * This function initializes the HASH.
  517. *
  518. * param base HASHCRYPT peripheral base address
  519. * param[out] ctx Output hash context
  520. * param algo Underlaying algorithm to use for hash computation.
  521. * return Status of initialization
  522. */
  523. status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
  524. {
  525. status_t status;
  526. hashcrypt_sha_ctx_internal_t *ctxInternal;
  527. /* compile time check for the correct structure size */
  528. BUILD_ASSERT(sizeof(hashcrypt_hash_ctx_t) >= sizeof(hashcrypt_sha_ctx_internal_t), hashcrypt_hash_ctx_t_size);
  529. status = hashcrypt_sha_check_input_args(base, ctx, algo);
  530. if (status != kStatus_Success)
  531. {
  532. return status;
  533. }
  534. /* set algorithm in context struct for later use */
  535. ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
  536. ctxInternal->algo = algo;
  537. ctxInternal->blksz = 0u;
  538. #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
  539. for (int i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
  540. {
  541. ctxInternal->blk.w[i] = 0u;
  542. }
  543. #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
  544. ctxInternal->state = kHASHCRYPT_HashInit;
  545. ctxInternal->fullMessageSize = 0;
  546. return kStatus_Success;
  547. }
  548. /*!
  549. * brief Add data to current HASH
  550. *
  551. * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
  552. * hashed. The functions blocks. If it returns kStatus_Success, the running hash
  553. * has been updated (HASHCRYPT has processed the input data), so the memory at \p input pointer
  554. * can be released back to system. The HASHCRYPT context buffer is updated with the running hash
  555. * and with all necessary information to support possible context switch.
  556. *
  557. * param base HASHCRYPT peripheral base address
  558. * param[in,out] ctx HASH context
  559. * param input Input data
  560. * param inputSize Size of input data in bytes
  561. * return Status of the hash update operation
  562. */
  563. status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
  564. {
  565. bool isUpdateState;
  566. status_t status;
  567. hashcrypt_sha_ctx_internal_t *ctxInternal;
  568. size_t blockSize;
  569. if (inputSize == 0)
  570. {
  571. return kStatus_Success;
  572. }
  573. ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
  574. #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
  575. status = hashcrypt_sha_check_context(base, ctxInternal);
  576. if (kStatus_Success != status)
  577. {
  578. return status;
  579. }
  580. #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
  581. ctxInternal->fullMessageSize += inputSize;
  582. blockSize = SHA_BLOCK_SIZE;
  583. /* if we are still less than 64 bytes, keep only in context */
  584. if ((ctxInternal->blksz + inputSize) <= blockSize)
  585. {
  586. hashcrypt_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
  587. ctxInternal->blksz += inputSize;
  588. return kStatus_Success;
  589. }
  590. else
  591. {
  592. isUpdateState = ctxInternal->state == kHASHCRYPT_HashUpdate;
  593. if (!isUpdateState)
  594. {
  595. /* start NEW hash */
  596. hashcrypt_engine_init(base, ctxInternal->algo);
  597. ctxInternal->state = kHASHCRYPT_HashUpdate;
  598. }
  599. }
  600. /* process message data */
  601. status = hashcrypt_sha_process_message_data(base, ctxInternal, input, inputSize);
  602. return status;
  603. }
  604. /*!
  605. * brief Finalize hashing
  606. *
  607. * Outputs the final hash (computed by HASHCRYPT_HASH_Update()) and erases the context.
  608. *
  609. * param base HASHCRYPT peripheral base address
  610. * param[in,out] ctx Input hash context
  611. * param[out] output Output hash data
  612. * param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
  613. * output[] buffer. On function return, it stores the number of updated output bytes.
  614. * return Status of the hash finish operation
  615. */
  616. status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
  617. {
  618. size_t algOutSize = 0;
  619. status_t status;
  620. hashcrypt_sha_ctx_internal_t *ctxInternal;
  621. #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
  622. uint32_t *ctxW;
  623. uint32_t i;
  624. #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
  625. if (output == NULL)
  626. {
  627. return kStatus_InvalidArgument;
  628. }
  629. ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
  630. #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
  631. status = hashcrypt_sha_check_context(base, ctxInternal);
  632. if (kStatus_Success != status)
  633. {
  634. return status;
  635. }
  636. #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
  637. if (ctxInternal->state == kHASHCRYPT_HashInit)
  638. {
  639. hashcrypt_engine_init(base, ctxInternal->algo);
  640. }
  641. size_t outSize = 0u;
  642. /* compute algorithm output length */
  643. switch (ctxInternal->algo)
  644. {
  645. case kHASHCRYPT_Sha1:
  646. outSize = kHASHCRYPT_OutLenSha1;
  647. break;
  648. case kHASHCRYPT_Sha256:
  649. outSize = kHASHCRYPT_OutLenSha256;
  650. break;
  651. default:
  652. break;
  653. }
  654. algOutSize = outSize;
  655. /* flush message last incomplete block, if there is any, and add padding bits */
  656. status = hashcrypt_sha_finalize(base, ctxInternal);
  657. if (outputSize)
  658. {
  659. if (algOutSize < *outputSize)
  660. {
  661. *outputSize = algOutSize;
  662. }
  663. else
  664. {
  665. algOutSize = *outputSize;
  666. }
  667. }
  668. hashcrypt_get_data(base, (uint32_t *)output, algOutSize);
  669. #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
  670. ctxW = (uint32_t *)ctx;
  671. for (i = 0; i < HASHCRYPT_HASH_CTX_SIZE; i++)
  672. {
  673. ctxW[i] = 0u;
  674. }
  675. #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
  676. return status;
  677. }
  678. /*!
  679. * brief Initializes the HASHCRYPT handle for background hashing.
  680. *
  681. * This function initializes the hash context for background hashing
  682. * (Non-blocking) APIs. This is less typical interface to hash function, but can be used
  683. * for parallel processing, when main CPU has something else to do.
  684. * Example is digital signature RSASSA-PKCS1-V1_5-VERIFY((n,e),M,S) algorithm, where
  685. * background hashing of M can be started, then CPU can compute S^e mod n
  686. * (in parallel with background hashing) and once the digest becomes available,
  687. * CPU can proceed to comparison of EM with EM'.
  688. *
  689. * param base HASHCRYPT peripheral base address.
  690. * param[out] ctx Hash context.
  691. * param callback Callback function.
  692. * param userData User data (to be passed as an argument to callback function, once callback is invoked from isr).
  693. */
  694. void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base,
  695. hashcrypt_hash_ctx_t *ctx,
  696. hashcrypt_callback_t callback,
  697. void *userData)
  698. {
  699. hashcrypt_sha_ctx_internal_t *ctxInternal;
  700. s_ctx = ctx;
  701. ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
  702. ctxInternal->hashCallback = callback;
  703. ctxInternal->userData = userData;
  704. EnableIRQ(HASHCRYPT_IRQn);
  705. }
  706. /*!
  707. * brief Create running hash on given data.
  708. *
  709. * Configures the HASHCRYPT to compute new running hash as AHB master
  710. * and returns immediately. HASHCRYPT AHB Master mode supports only aligned \p input
  711. * address and can be called only once per continuous block of data. Every call to this function
  712. * must be preceded with HASHCRYPT_SHA_Init() and finished with HASHCRYPT_SHA_Finish().
  713. * Once callback function is invoked by HASHCRYPT isr, it should set a flag
  714. * for the main application to finalize the hashing (padding) and to read out the final digest
  715. * by calling HASHCRYPT_SHA_Finish().
  716. *
  717. * param base HASHCRYPT peripheral base address
  718. * param ctx Specifies callback. Last incomplete 512-bit block of the input is copied into clear buffer for padding.
  719. * param input 32-bit word aligned pointer to Input data.
  720. * param inputSize Size of input data in bytes (must be word aligned)
  721. * return Status of the hash update operation.
  722. */
  723. status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base,
  724. hashcrypt_hash_ctx_t *ctx,
  725. const uint8_t *input,
  726. size_t inputSize)
  727. {
  728. hashcrypt_sha_ctx_internal_t *ctxInternal;
  729. uint32_t numBlocks;
  730. status_t status;
  731. if (inputSize == 0)
  732. {
  733. return kStatus_Success;
  734. }
  735. if ((uintptr_t)input & 0x3U)
  736. {
  737. return kStatus_Fail;
  738. }
  739. ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
  740. status = hashcrypt_sha_check_context(base, ctxInternal);
  741. if (kStatus_Success != status)
  742. {
  743. return status;
  744. }
  745. ctxInternal->fullMessageSize = inputSize;
  746. ctxInternal->remainingBlcks = inputSize / SHA_BLOCK_SIZE;
  747. ctxInternal->blksz = inputSize % SHA_BLOCK_SIZE;
  748. /* copy last incomplete block to context */
  749. if ((ctxInternal->blksz > 0) && (ctxInternal->blksz <= SHA_BLOCK_SIZE))
  750. {
  751. hashcrypt_memcpy((&ctxInternal->blk.b[0]), input + SHA_BLOCK_SIZE * ctxInternal->remainingBlcks,
  752. ctxInternal->blksz);
  753. }
  754. if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
  755. {
  756. numBlocks = SHA_MASTER_MAX_BLOCKS - 1;
  757. }
  758. else
  759. {
  760. numBlocks = ctxInternal->remainingBlcks;
  761. }
  762. /* update remainingBlks so that ISR can run another hash if necessary */
  763. ctxInternal->remainingBlcks -= numBlocks;
  764. /* compute hash using AHB Master mode for full blocks */
  765. if (numBlocks > 0)
  766. {
  767. ctxInternal->state = kHASHCRYPT_HashUpdate;
  768. hashcrypt_engine_init(base, ctxInternal->algo);
  769. /* Enable digest and error interrupts and start hash */
  770. base->INTENSET = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
  771. base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(input);
  772. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
  773. }
  774. /* no full blocks, invoke callback directly */
  775. else
  776. {
  777. ctxInternal->hashCallback(HASHCRYPT, ctx, status, ctxInternal->userData);
  778. }
  779. return status;
  780. }
  781. /*!
  782. * brief Set AES key to hashcrypt_handle_t struct and optionally to HASHCRYPT.
  783. *
  784. * Sets the AES key for encryption/decryption with the hashcrypt_handle_t structure.
  785. * The hashcrypt_handle_t input argument specifies key source.
  786. *
  787. * param base HASHCRYPT peripheral base address.
  788. * param handle Handle used for the request.
  789. * param key 0-mod-4 aligned pointer to AES key.
  790. * param keySize AES key size in bytes. Shall equal 16, 24 or 32.
  791. * return status from set key operation
  792. */
  793. status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t aesKeySize)
  794. {
  795. switch (aesKeySize)
  796. {
  797. case 16:
  798. handle->keySize = kHASHCRYPT_Aes128;
  799. break;
  800. case 24:
  801. handle->keySize = kHASHCRYPT_Aes192;
  802. break;
  803. case 32:
  804. handle->keySize = kHASHCRYPT_Aes256;
  805. break;
  806. default:
  807. handle->keySize = kHASHCRYPT_InvalidKey;
  808. break;
  809. }
  810. if (handle->keySize == kHASHCRYPT_InvalidKey)
  811. {
  812. return kStatus_InvalidArgument;
  813. }
  814. if (handle->keyType == kHASHCRYPT_SecretKey)
  815. {
  816. /* for kHASHCRYPT_SecretKey just return Success */
  817. return kStatus_Success;
  818. }
  819. else if (handle->keyType == kHASHCRYPT_UserKey)
  820. {
  821. /* only work with aligned key[] */
  822. if (0x3U & (uintptr_t)key)
  823. {
  824. return kStatus_InvalidArgument;
  825. }
  826. /* move the key by 32-bit words */
  827. int i = 0;
  828. while (aesKeySize)
  829. {
  830. aesKeySize -= sizeof(uint32_t);
  831. handle->keyWord[i] = ((uint32_t *)(uintptr_t)key)[i];
  832. i++;
  833. }
  834. }
  835. else
  836. {
  837. return kStatus_InvalidArgument;
  838. }
  839. return kStatus_Success;
  840. }
  841. /*!
  842. * brief Encrypts AES on one or multiple 128-bit block(s).
  843. *
  844. * Encrypts AES.
  845. * The source plaintext and destination ciphertext can overlap in system memory.
  846. *
  847. * param base HASHCRYPT peripheral base address
  848. * param handle Handle used for this request.
  849. * param plaintext Input plain text to encrypt
  850. * param[out] ciphertext Output cipher text
  851. * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  852. * return Status from encrypt operation
  853. */
  854. status_t HASHCRYPT_AES_EncryptEcb(
  855. HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
  856. {
  857. status_t status = kStatus_Fail;
  858. if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
  859. {
  860. return kStatus_InvalidArgument;
  861. }
  862. uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
  863. base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
  864. HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
  865. HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
  866. HASHCRYPT_CRYPTCFG_MSW1ST(1);
  867. hashcrypt_engine_init(base, kHASHCRYPT_Aes);
  868. /* load key if kHASHCRYPT_UserKey is selected */
  869. if (handle->keyType == kHASHCRYPT_UserKey)
  870. {
  871. hashcrypt_aes_load_userKey(base, handle);
  872. }
  873. /* load message and get result */
  874. status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
  875. return status;
  876. }
  877. /*!
  878. * brief Decrypts AES on one or multiple 128-bit block(s).
  879. *
  880. * Decrypts AES.
  881. * The source ciphertext and destination plaintext can overlap in system memory.
  882. *
  883. * param base HASHCRYPT peripheral base address
  884. * param handle Handle used for this request.
  885. * param ciphertext Input plain text to encrypt
  886. * param[out] plaintext Output cipher text
  887. * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  888. * return Status from decrypt operation
  889. */
  890. status_t HASHCRYPT_AES_DecryptEcb(
  891. HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
  892. {
  893. status_t status = kStatus_Fail;
  894. if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
  895. {
  896. return kStatus_InvalidArgument;
  897. }
  898. uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
  899. base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
  900. HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
  901. HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
  902. HASHCRYPT_CRYPTCFG_MSW1ST(1);
  903. hashcrypt_engine_init(base, kHASHCRYPT_Aes);
  904. /* load key if kHASHCRYPT_UserKey is selected */
  905. if (handle->keyType == kHASHCRYPT_UserKey)
  906. {
  907. hashcrypt_aes_load_userKey(base, handle);
  908. }
  909. /* load message and get result */
  910. status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
  911. return status;
  912. }
  913. /*!
  914. * brief Encrypts AES using CBC block mode.
  915. *
  916. * param base HASHCRYPT peripheral base address
  917. * param handle Handle used for this request.
  918. * param plaintext Input plain text to encrypt
  919. * param[out] ciphertext Output cipher text
  920. * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  921. * param iv Input initial vector to combine with the first input block.
  922. * return Status from encrypt operation
  923. */
  924. status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base,
  925. hashcrypt_handle_t *handle,
  926. const uint8_t *plaintext,
  927. uint8_t *ciphertext,
  928. size_t size,
  929. const uint8_t iv[16])
  930. {
  931. status_t status = kStatus_Fail;
  932. if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
  933. {
  934. return kStatus_InvalidArgument;
  935. }
  936. uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
  937. base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
  938. HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
  939. HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
  940. HASHCRYPT_CRYPTCFG_MSW1ST(1);
  941. hashcrypt_engine_init(base, kHASHCRYPT_Aes);
  942. /* load key if kHASHCRYPT_UserKey is selected */
  943. if (handle->keyType == kHASHCRYPT_UserKey)
  944. {
  945. hashcrypt_aes_load_userKey(base, handle);
  946. }
  947. /* load 16b iv */
  948. hashcrypt_load_data(base, (uint32_t *)iv, 16);
  949. /* load message and get result */
  950. status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
  951. return status;
  952. }
  953. /*!
  954. * brief Decrypts AES using CBC block mode.
  955. *
  956. * param base HASHCRYPT peripheral base address
  957. * param handle Handle used for this request.
  958. * param ciphertext Input cipher text to decrypt
  959. * param[out] plaintext Output plain text
  960. * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
  961. * param iv Input initial vector to combine with the first input block.
  962. * return Status from decrypt operation
  963. */
  964. status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base,
  965. hashcrypt_handle_t *handle,
  966. const uint8_t *ciphertext,
  967. uint8_t *plaintext,
  968. size_t size,
  969. const uint8_t iv[16])
  970. {
  971. status_t status = kStatus_Fail;
  972. if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
  973. {
  974. return kStatus_InvalidArgument;
  975. }
  976. uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
  977. base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
  978. HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
  979. HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
  980. HASHCRYPT_CRYPTCFG_MSW1ST(1);
  981. hashcrypt_engine_init(base, kHASHCRYPT_Aes);
  982. /* load key if kHASHCRYPT_UserKey is selected */
  983. if (handle->keyType == kHASHCRYPT_UserKey)
  984. {
  985. hashcrypt_aes_load_userKey(base, handle);
  986. }
  987. /* load iv */
  988. hashcrypt_load_data(base, (uint32_t *)iv, 16);
  989. /* load message and get result */
  990. status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
  991. return status;
  992. }
  993. /*!
  994. * brief Encrypts or decrypts AES using CTR block mode.
  995. *
  996. * Encrypts or decrypts AES using CTR block mode.
  997. * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
  998. * The only difference between encryption and decryption is that, for encryption, the input argument
  999. * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
  1000. * and the output argument is plain text.
  1001. *
  1002. * param base HASHCRYPT peripheral base address
  1003. * param handle Handle used for this request.
  1004. * param input Input data for CTR block mode
  1005. * param[out] output Output data for CTR block mode
  1006. * param size Size of input and output data in bytes
  1007. * param[in,out] counter Input counter (updates on return)
  1008. * param[out] counterlast Output cipher of last counter, for chained CTR calls (statefull encryption). NULL can be
  1009. * passed if chained calls are
  1010. * not used.
  1011. * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
  1012. * are not used.
  1013. * return Status from encrypt operation
  1014. */
  1015. status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base,
  1016. hashcrypt_handle_t *handle,
  1017. const uint8_t *input,
  1018. uint8_t *output,
  1019. size_t size,
  1020. uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],
  1021. uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],
  1022. size_t *szLeft)
  1023. {
  1024. uint32_t lastSize;
  1025. uint8_t lastBlock[HASHCRYPT_AES_BLOCK_SIZE] = {0};
  1026. uint8_t *lastEncryptedCounter;
  1027. status_t status = kStatus_Fail;
  1028. if (handle->keySize == kHASHCRYPT_InvalidKey)
  1029. {
  1030. return kStatus_InvalidArgument;
  1031. }
  1032. uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
  1033. base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCtr) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
  1034. HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
  1035. HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
  1036. HASHCRYPT_CRYPTCFG_MSW1ST(1);
  1037. hashcrypt_engine_init(base, kHASHCRYPT_Aes);
  1038. /* load key if kHASHCRYPT_UserKey is selected */
  1039. if (handle->keyType == kHASHCRYPT_UserKey)
  1040. {
  1041. hashcrypt_aes_load_userKey(base, handle);
  1042. }
  1043. /* load nonce */
  1044. hashcrypt_load_data(base, (uint32_t *)counter, 16);
  1045. lastSize = size % HASHCRYPT_AES_BLOCK_SIZE;
  1046. size -= lastSize;
  1047. /* encrypt full 16byte blocks */
  1048. hashcrypt_aes_one_block(base, input, output, size);
  1049. while (size)
  1050. {
  1051. ctrIncrement(counter);
  1052. size -= 16u;
  1053. input += 16;
  1054. output += 16;
  1055. }
  1056. if (lastSize)
  1057. {
  1058. if (counterlast)
  1059. {
  1060. lastEncryptedCounter = counterlast;
  1061. }
  1062. else
  1063. {
  1064. lastEncryptedCounter = lastBlock;
  1065. }
  1066. /* Perform encryption with all zeros to get last counter. XOR with zeros doesn't change. */
  1067. status = hashcrypt_aes_one_block(base, lastBlock, lastEncryptedCounter, HASHCRYPT_AES_BLOCK_SIZE);
  1068. if (status != kStatus_Success)
  1069. {
  1070. return status;
  1071. }
  1072. /* remain output = input XOR counterlast */
  1073. for (uint32_t i = 0; i < lastSize; i++)
  1074. {
  1075. output[i] = input[i] ^ lastEncryptedCounter[i];
  1076. }
  1077. /* Increment counter parameter */
  1078. ctrIncrement(counter);
  1079. }
  1080. else
  1081. {
  1082. lastSize = HASHCRYPT_AES_BLOCK_SIZE;
  1083. /* no remaining bytes in couterlast so clearing it */
  1084. if (counterlast)
  1085. {
  1086. memset(counterlast, 0, HASHCRYPT_AES_BLOCK_SIZE);
  1087. }
  1088. }
  1089. if (szLeft)
  1090. {
  1091. *szLeft = HASHCRYPT_AES_BLOCK_SIZE - lastSize;
  1092. }
  1093. return kStatus_Success;
  1094. }
  1095. void HASH_IRQHandler(void)
  1096. {
  1097. hashcrypt_sha_ctx_internal_t *ctxInternal;
  1098. HASHCRYPT_Type *base = HASHCRYPT;
  1099. uint32_t numBlocks;
  1100. status_t status;
  1101. ctxInternal = (hashcrypt_sha_ctx_internal_t *)s_ctx;
  1102. if (0 == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
  1103. {
  1104. if (ctxInternal->remainingBlcks > 0)
  1105. {
  1106. if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
  1107. {
  1108. numBlocks = SHA_MASTER_MAX_BLOCKS - 1;
  1109. }
  1110. else
  1111. {
  1112. numBlocks = ctxInternal->remainingBlcks;
  1113. }
  1114. /* some blocks still remaining, update remainingBlcks for next ISR and start another hash */
  1115. ctxInternal->remainingBlcks -= numBlocks;
  1116. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
  1117. return;
  1118. }
  1119. /* no full blocks left, disable interrupts and AHB master mode */
  1120. base->INTENCLR = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
  1121. base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(0);
  1122. status = kStatus_Success;
  1123. }
  1124. else
  1125. {
  1126. status = kStatus_Fail;
  1127. }
  1128. /* Invoke callback if there is one */
  1129. if (NULL != ctxInternal->hashCallback)
  1130. {
  1131. ctxInternal->hashCallback(HASHCRYPT, s_ctx, status, ctxInternal->userData);
  1132. }
  1133. }
  1134. /*!
  1135. * brief Enables clock and disables reset for HASHCRYPT peripheral.
  1136. *
  1137. * Enable clock and disable reset for HASHCRYPT.
  1138. *
  1139. * param base HASHCRYPT base address
  1140. */
  1141. void HASHCRYPT_Init(HASHCRYPT_Type *base)
  1142. {
  1143. RESET_PeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
  1144. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  1145. CLOCK_EnableClock(kCLOCK_HashCrypt);
  1146. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  1147. }
  1148. /*!
  1149. * brief Disables clock for HASHCRYPT peripheral.
  1150. *
  1151. * Disable clock and enable reset.
  1152. *
  1153. * param base HASHCRYPT base address
  1154. */
  1155. void HASHCRYPT_Deinit(HASHCRYPT_Type *base)
  1156. {
  1157. RESET_SetPeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
  1158. #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
  1159. CLOCK_DisableClock(kCLOCK_HashCrypt);
  1160. #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
  1161. }