123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302 |
- /*
- * Copyright 2017-2018 NXP
- * All rights reserved.
- *
- * SPDX-License-Identifier: BSD-3-Clause
- */
- #include "fsl_hashcrypt.h"
- /*******************************************************************************
- * Definitions
- *******************************************************************************/
- /*!< SHA-1 and SHA-256 block size */
- #define SHA_BLOCK_SIZE 64
- /*!< max number of blocks that can be proccessed in one run (master mode) */
- #define SHA_MASTER_MAX_BLOCKS 2048
- /*!< Use standard C library memcpy */
- #define hashcrypt_memcpy memcpy
- /*! Internal states of the HASH creation process */
- typedef enum _hashcrypt_sha_algo_state
- {
- kHASHCRYPT_HashInit = 1u, /*!< Init state, the NEW bit in SHA Control register has not been written yet. */
- kHASHCRYPT_HashUpdate, /*!< Update state, DIGEST registers contain running hash, NEW bit in SHA control register has
- been written. */
- } hashcrypt_sha_algo_state_t;
- /*! 64-byte block represented as byte array of 16 32-bit words */
- typedef union _sha_hash_block
- {
- uint32_t w[SHA_BLOCK_SIZE / 4]; /*!< array of 32-bit words */
- uint8_t b[SHA_BLOCK_SIZE]; /*!< byte array */
- } hashcrypt_sha_block_t;
- /*! internal sha context structure */
- typedef struct _hashcrypt_sha_ctx_internal
- {
- hashcrypt_sha_block_t blk; /*!< memory buffer. only full 64-byte blocks are written to SHA during hash updates */
- size_t blksz; /*!< number of valid bytes in memory buffer */
- hashcrypt_algo_t algo; /*!< selected algorithm from the set of supported algorithms */
- hashcrypt_sha_algo_state_t state; /*!< finite machine state of the hash software process */
- size_t fullMessageSize; /*!< track message size during SHA_Update(). The value is used for padding. */
- uint32_t remainingBlcks; /*!< number of remaining blocks to process in AHB master mode */
- hashcrypt_callback_t hashCallback; /*!< pointer to HASH callback function */
- void
- *userData; /*!< user data to be passed as an argument to callback function, once callback is invoked from isr */
- } hashcrypt_sha_ctx_internal_t;
- /*!< SHA-1 and SHA-256 digest length in bytes */
- enum _hashcrypt_sha_digest_len
- {
- kHASHCRYPT_OutLenSha1 = 20u,
- kHASHCRYPT_OutLenSha256 = 32u,
- };
- /*!< pointer to hash context structure used by isr */
- static hashcrypt_hash_ctx_t *s_ctx;
- /*!< macro for checking build time condition. It is used to assure the hashcrypt_sha_ctx_internal_t can fit into
- * hashcrypt_hash_ctx_t */
- #define BUILD_ASSERT(condition, msg) extern int msg[1 - 2 * (!(condition))] __attribute__((unused))
- /*******************************************************************************
- * Code
- ******************************************************************************/
- /*!
- * @brief Swap bytes withing 32-bit word.
- *
- * This function changes endianess of a 32-bit word.
- *
- * @param in 32-bit unsigned integer
- * @return 32-bit unsigned integer with different endianess (big endian to little endian and vice versa).
- */
- #define swap_bytes(in) __REV(in)
- /*!
- * @brief Increment a 16 byte integer.
- *
- * This function increments by one a 16 byte integer.
- *
- * @param input Pointer to a 16 byte integer to be incremented by one.
- */
- static void ctrIncrement(uint8_t *input)
- {
- int i = 15;
- while (input[i] == (uint8_t)0xFFu)
- {
- input[i] = (uint8_t)0x00u;
- i--;
- if (i < 0)
- {
- return;
- }
- }
- if (i >= 0)
- {
- input[i] += (uint8_t)1u;
- }
- }
- /*!
- * @brief LDM to SHA engine INDATA and ALIAS registers.
- *
- * This function writes 16 words starting from the src address (must be word aligned)
- * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
- * Src address increments to load 16 consecutive words.
- *
- * @param dst peripheral register address (word aligned)
- * @param src address of the input 512-bit block (16 words) (word aligned)
- *
- */
- __STATIC_FORCEINLINE void hashcrypt_sha_ldm_stm_16_words(HASHCRYPT_Type *base, const uint32_t *src)
- {
- /*
- typedef struct _one_block
- {
- uint32_t a[8];
- } one_block_t;
- volatile one_block_t *ldst = (void *)(uintptr_t)(&base->INDATA);
- one_block_t *lsrc = (void *)(uintptr_t)src;
- *ldst = lsrc[0];
- *ldst = lsrc[1];
- */
- base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(src);
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(1);
- }
- /*!
- * @brief Loads data to Hashcrypt engine INDATA register.
- *
- * This function writes desired number of bytes starting from the src address (must be word aligned)
- * to the dst address. Dst address does not increment (destination is peripheral module register INDATA).
- * Src address increments to load consecutive words.
- *
- * @param dst peripheral register address (word aligned)
- * @param src address of the input block (word aligned)
- * @param size number of bytes to write (word aligned)
- *
- */
- __STATIC_INLINE void hashcrypt_load_data(HASHCRYPT_Type *base, const uint32_t *src, size_t size)
- {
- if (size >= sizeof(uint32_t))
- {
- base->INDATA = src[0];
- size -= sizeof(uint32_t);
- }
- for (int i = 0; i < size / 4; i++)
- {
- base->ALIAS[i] = src[i + 1];
- }
- }
- /*!
- * @brief Read OUTDATA registers.
- *
- * This function copies OUTDATA to output buffer.
- *
- * @param base Hachcrypt peripheral base address.
- * @param[out] output Output buffer.
- * @param Number of bytes to copy.
- */
- static void hashcrypt_get_data(HASHCRYPT_Type *base, uint32_t *output, size_t outputSize)
- {
- uint32_t digest[8];
- while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
- {
- }
- for (int i = 0; i < 8; i++)
- {
- digest[i] = swap_bytes(base->OUTDATA0[i]);
- }
- if (outputSize > sizeof(digest))
- {
- outputSize = sizeof(digest);
- }
- hashcrypt_memcpy(output, digest, outputSize);
- }
- /*!
- * @brief Initialize the Hashcrypt engine for new operation.
- *
- * This function sets NEW and MODE fields in Hashcrypt Control register to start new operation.
- *
- * @param base Hashcrypt peripheral base address.
- * @param hashcrypt_algo_t Internal context.
- */
- static void hashcrypt_engine_init(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
- {
- /* NEW bit must be set before we switch from previous mode otherwise new mode will not work correctly */
- base->CTRL = HASHCRYPT_CTRL_NEW_HASH(1);
- base->CTRL = HASHCRYPT_CTRL_MODE(algo) | HASHCRYPT_CTRL_NEW_HASH(1);
- }
- /*!
- * @brief Loads user key to INDATA register.
- *
- * This function writes user key stored in handle into HashCrypt INDATA register.
- *
- * @param base Hashcrypt peripheral base address.
- * @param handle Handle used for this request.
- */
- static void hashcrypt_aes_load_userKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle)
- {
- size_t keySize = 0;
- switch (handle->keySize)
- {
- case kHASHCRYPT_Aes128:
- keySize = 16;
- break;
- case kHASHCRYPT_Aes192:
- keySize = 24;
- break;
- case kHASHCRYPT_Aes256:
- keySize = 32;
- break;
- default:
- break;
- }
- if (keySize == 0)
- {
- return;
- }
- hashcrypt_load_data(base, &handle->keyWord[0], keySize);
- }
- /*!
- * @brief Performs AES encryption/decryption of one data block.
- *
- * This function encrypts/decrypts one block of data with specified size.
- *
- * @param base Hashcrypt peripheral base address.
- * @param input input data
- * @param output output data
- * @param size size of data block to process in bytes (must be 16bytes multiple).
- */
- static status_t hashcrypt_aes_one_block(HASHCRYPT_Type *base, const uint8_t *input, uint8_t *output, size_t size)
- {
- status_t status = kStatus_Fail;
- int idx = 0;
- /* we use AHB master mode as much as possible */
- /* however, it can work only with aligned input data */
- /* so, if unaligned, we do memcpy to temp buffer on stack, which is aligned, and use AHB mode to read data in */
- /* then we read data back to it and do memcpy to the output buffer */
- if (((uint32_t)input & 0x3u) || ((uint32_t)output & 0x3u))
- {
- uint32_t temp[256 / sizeof(uint32_t)];
- int cnt = 0;
- while (size)
- {
- size_t actSz = size >= 256u ? 256u : size;
- size_t actSzOrig = actSz;
- memcpy(temp, input + 256 * cnt, actSz);
- size -= actSz;
- base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(temp);
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(actSz / 16);
- int outidx = 0;
- while (actSz)
- {
- while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
- {
- }
- for (int i = 0; i < 4; i++)
- {
- (temp + outidx)[i] = swap_bytes(base->OUTDATA0[i]);
- }
- outidx += HASHCRYPT_AES_BLOCK_SIZE / 4;
- actSz -= HASHCRYPT_AES_BLOCK_SIZE;
- }
- memcpy(output + 256 * cnt, temp, actSzOrig);
- cnt++;
- }
- }
- else
- {
- base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(input);
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(size / 16);
- while (size >= HASHCRYPT_AES_BLOCK_SIZE)
- {
- /* Get result */
- while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
- {
- }
- for (int i = 0; i < 4; i++)
- {
- ((uint32_t *)output + idx)[i] = swap_bytes(base->OUTDATA0[i]);
- }
- idx += HASHCRYPT_AES_BLOCK_SIZE / 4;
- size -= HASHCRYPT_AES_BLOCK_SIZE;
- }
- }
- if (0 == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
- {
- status = kStatus_Success;
- }
- return status;
- }
- /*!
- * @brief Check validity of algoritm.
- *
- * This function checks the validity of input argument.
- *
- * @param algo Tested algorithm value.
- * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
- */
- static status_t hashcrypt_sha_check_input_alg(HASHCRYPT_Type *base, hashcrypt_algo_t algo)
- {
- if ((algo == kHASHCRYPT_Sha1) || (algo == kHASHCRYPT_Sha256))
- {
- return kStatus_Success;
- }
- if ((algo == kHASHCRYPT_Sha512) && (base->CONFIG & HASHCRYPT_CONFIG_SHA512_MASK))
- {
- return kStatus_Success;
- }
- return kStatus_InvalidArgument;
- }
- /*!
- * @brief Check validity of input arguments.
- *
- * This function checks the validity of input arguments.
- *
- * @param base SHA peripheral base address.
- * @param ctx Memory buffer given by user application where the SHA_Init/SHA_Update/SHA_Finish store context.
- * @param algo Tested algorithm value.
- * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
- */
- static status_t hashcrypt_sha_check_input_args(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
- {
- /* Check validity of input algorithm */
- if (kStatus_Success != hashcrypt_sha_check_input_alg(base, algo))
- {
- return kStatus_InvalidArgument;
- }
- if ((NULL == ctx) || (NULL == base))
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- /*!
- * @brief Check validity of internal software context.
- *
- * This function checks if the internal context structure looks correct.
- *
- * @param ctxInternal Internal context.
- * @return kStatus_Success if valid, kStatus_InvalidArgument otherwise.
- */
- static status_t hashcrypt_sha_check_context(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
- {
- if ((NULL == ctxInternal) || (kStatus_Success != hashcrypt_sha_check_input_alg(base, ctxInternal->algo)))
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- /*!
- * @brief Load 512-bit block (16 words) into SHA engine.
- *
- * This function aligns the input block and moves it into SHA engine INDATA.
- * CPU polls the WAITING bit and then moves data by using LDM and STM instructions.
- *
- * @param base SHA peripheral base address.
- * @param blk 512-bit block
- */
- static void hashcrypt_sha_one_block(HASHCRYPT_Type *base, const uint8_t *blk)
- {
- uint32_t temp[SHA_BLOCK_SIZE / sizeof(uint32_t)];
- const uint32_t *actBlk;
- /* make sure the 512-bit block is word aligned */
- if ((uintptr_t)blk & 0x3u)
- {
- hashcrypt_memcpy(temp, blk, SHA_BLOCK_SIZE);
- actBlk = (const uint32_t *)(uintptr_t)temp;
- }
- else
- {
- actBlk = (const uint32_t *)(uintptr_t)blk;
- }
- /* poll waiting. */
- while (0 == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
- {
- }
- /* feed INDATA (and ALIASes). use STM instruction. */
- hashcrypt_sha_ldm_stm_16_words(base, actBlk);
- }
- /*!
- * @brief Adds message to current hash.
- *
- * This function merges the message to fill the internal buffer, empties the internal buffer if
- * it becomes full, then process all remaining message data.
- *
- *
- * @param base SHA peripheral base address.
- * @param ctxInternal Internal context.
- * @param message Input message.
- * @param messageSize Size of input message in bytes.
- * @return kStatus_Success.
- */
- static status_t hashcrypt_sha_process_message_data(HASHCRYPT_Type *base,
- hashcrypt_sha_ctx_internal_t *ctxInternal,
- const uint8_t *message,
- size_t messageSize)
- {
- /* first fill the internal buffer to full block */
- if (ctxInternal->blksz)
- {
- size_t toCopy = SHA_BLOCK_SIZE - ctxInternal->blksz;
- hashcrypt_memcpy(&ctxInternal->blk.b[ctxInternal->blksz], message, toCopy);
- message += toCopy;
- messageSize -= toCopy;
- /* process full internal block */
- hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
- }
- /* process all full blocks in message[] */
- if (messageSize >= SHA_BLOCK_SIZE)
- {
- if ((uintptr_t)message & 0x3u)
- {
- while (messageSize >= SHA_BLOCK_SIZE)
- {
- hashcrypt_sha_one_block(base, message);
- message += SHA_BLOCK_SIZE;
- messageSize -= SHA_BLOCK_SIZE;
- }
- }
- else
- {
- /* poll waiting. */
- while (0 == (base->STATUS & HASHCRYPT_STATUS_WAITING_MASK))
- {
- }
- uint32_t blkNum = (messageSize >> 6); /* div by 64 bytes */
- uint32_t blkBytes = blkNum * 64u; /* number of bytes in 64 bytes blocks */
- base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(message);
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(blkNum);
- message += blkBytes;
- messageSize -= blkBytes;
- while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
- {
- }
- }
- }
- /* copy last incomplete message bytes into internal block */
- hashcrypt_memcpy(&ctxInternal->blk.b[0], message, messageSize);
- ctxInternal->blksz = messageSize;
- return kStatus_Success;
- }
- /*!
- * @brief Finalize the running hash to make digest.
- *
- * This function empties the internal buffer, adds padding bits, and generates final digest.
- *
- * @param base SHA peripheral base address.
- * @param ctxInternal Internal context.
- * @return kStatus_Success.
- */
- static status_t hashcrypt_sha_finalize(HASHCRYPT_Type *base, hashcrypt_sha_ctx_internal_t *ctxInternal)
- {
- hashcrypt_sha_block_t lastBlock;
- memset(&lastBlock, 0, sizeof(hashcrypt_sha_block_t));
- /* this is last call, so need to flush buffered message bytes along with padding */
- if (ctxInternal->blksz <= 55u)
- {
- /* last data is 440 bits or less. */
- hashcrypt_memcpy(&lastBlock.b[0], &ctxInternal->blk.b[0], ctxInternal->blksz);
- lastBlock.b[ctxInternal->blksz] = (uint8_t)0x80U;
- lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
- hashcrypt_sha_one_block(base, &lastBlock.b[0]);
- }
- else
- {
- if (ctxInternal->blksz < SHA_BLOCK_SIZE)
- {
- ctxInternal->blk.b[ctxInternal->blksz] = (uint8_t)0x80U;
- for (uint32_t i = ctxInternal->blksz + 1u; i < SHA_BLOCK_SIZE; i++)
- {
- ctxInternal->blk.b[i] = 0;
- }
- }
- else
- {
- lastBlock.b[0] = (uint8_t)0x80U;
- }
- hashcrypt_sha_one_block(base, &ctxInternal->blk.b[0]);
- lastBlock.w[SHA_BLOCK_SIZE / 4 - 1] = swap_bytes(8u * ctxInternal->fullMessageSize);
- hashcrypt_sha_one_block(base, &lastBlock.b[0]);
- }
- /* poll wait for final digest */
- while (0 == (base->STATUS & HASHCRYPT_STATUS_DIGEST_AKA_OUTDATA_MASK))
- {
- }
- return kStatus_Success;
- }
- /*!
- * brief Create HASH on given data
- *
- * Perform the full SHA in one function call. The function is blocking.
- *
- * param base HASHCRYPT peripheral base address
- * param algo Underlaying algorithm to use for hash computation.
- * param input Input data
- * param inputSize Size of input data in bytes
- * param[out] output Output hash data
- * param[out] outputSize Output parameter storing the size of the output hash in bytes
- * return Status of the one call hash operation.
- */
- status_t HASHCRYPT_SHA(HASHCRYPT_Type *base,
- hashcrypt_algo_t algo,
- const uint8_t *input,
- size_t inputSize,
- uint8_t *output,
- size_t *outputSize)
- {
- hashcrypt_hash_ctx_t hashCtx;
- status_t status;
- status = HASHCRYPT_SHA_Init(base, &hashCtx, algo);
- if (status != kStatus_Success)
- {
- return status;
- }
- status = HASHCRYPT_SHA_Update(base, &hashCtx, input, inputSize);
- if (status != kStatus_Success)
- {
- return status;
- }
- status = HASHCRYPT_SHA_Finish(base, &hashCtx, output, outputSize);
- return status;
- }
- /*!
- * brief Initialize HASH context
- *
- * This function initializes the HASH.
- *
- * param base HASHCRYPT peripheral base address
- * param[out] ctx Output hash context
- * param algo Underlaying algorithm to use for hash computation.
- * return Status of initialization
- */
- status_t HASHCRYPT_SHA_Init(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, hashcrypt_algo_t algo)
- {
- status_t status;
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- /* compile time check for the correct structure size */
- BUILD_ASSERT(sizeof(hashcrypt_hash_ctx_t) >= sizeof(hashcrypt_sha_ctx_internal_t), hashcrypt_hash_ctx_t_size);
- status = hashcrypt_sha_check_input_args(base, ctx, algo);
- if (status != kStatus_Success)
- {
- return status;
- }
- /* set algorithm in context struct for later use */
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
- ctxInternal->algo = algo;
- ctxInternal->blksz = 0u;
- #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
- for (int i = 0; i < sizeof(ctxInternal->blk.w) / sizeof(ctxInternal->blk.w[0]); i++)
- {
- ctxInternal->blk.w[i] = 0u;
- }
- #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
- ctxInternal->state = kHASHCRYPT_HashInit;
- ctxInternal->fullMessageSize = 0;
- return kStatus_Success;
- }
- /*!
- * brief Add data to current HASH
- *
- * Add data to current HASH. This can be called repeatedly with an arbitrary amount of data to be
- * hashed. The functions blocks. If it returns kStatus_Success, the running hash
- * has been updated (HASHCRYPT has processed the input data), so the memory at \p input pointer
- * can be released back to system. The HASHCRYPT context buffer is updated with the running hash
- * and with all necessary information to support possible context switch.
- *
- * param base HASHCRYPT peripheral base address
- * param[in,out] ctx HASH context
- * param input Input data
- * param inputSize Size of input data in bytes
- * return Status of the hash update operation
- */
- status_t HASHCRYPT_SHA_Update(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, const uint8_t *input, size_t inputSize)
- {
- bool isUpdateState;
- status_t status;
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- size_t blockSize;
- if (inputSize == 0)
- {
- return kStatus_Success;
- }
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
- #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
- status = hashcrypt_sha_check_context(base, ctxInternal);
- if (kStatus_Success != status)
- {
- return status;
- }
- #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
- ctxInternal->fullMessageSize += inputSize;
- blockSize = SHA_BLOCK_SIZE;
- /* if we are still less than 64 bytes, keep only in context */
- if ((ctxInternal->blksz + inputSize) <= blockSize)
- {
- hashcrypt_memcpy((&ctxInternal->blk.b[0]) + ctxInternal->blksz, input, inputSize);
- ctxInternal->blksz += inputSize;
- return kStatus_Success;
- }
- else
- {
- isUpdateState = ctxInternal->state == kHASHCRYPT_HashUpdate;
- if (!isUpdateState)
- {
- /* start NEW hash */
- hashcrypt_engine_init(base, ctxInternal->algo);
- ctxInternal->state = kHASHCRYPT_HashUpdate;
- }
- }
- /* process message data */
- status = hashcrypt_sha_process_message_data(base, ctxInternal, input, inputSize);
- return status;
- }
- /*!
- * brief Finalize hashing
- *
- * Outputs the final hash (computed by HASHCRYPT_HASH_Update()) and erases the context.
- *
- * param base HASHCRYPT peripheral base address
- * param[in,out] ctx Input hash context
- * param[out] output Output hash data
- * param[in,out] outputSize Optional parameter (can be passed as NULL). On function entry, it specifies the size of
- * output[] buffer. On function return, it stores the number of updated output bytes.
- * return Status of the hash finish operation
- */
- status_t HASHCRYPT_SHA_Finish(HASHCRYPT_Type *base, hashcrypt_hash_ctx_t *ctx, uint8_t *output, size_t *outputSize)
- {
- size_t algOutSize = 0;
- status_t status;
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
- uint32_t *ctxW;
- uint32_t i;
- #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
- if (output == NULL)
- {
- return kStatus_InvalidArgument;
- }
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
- #ifdef HASHCRYPT_SHA_DO_CHECK_CONTEXT
- status = hashcrypt_sha_check_context(base, ctxInternal);
- if (kStatus_Success != status)
- {
- return status;
- }
- #endif /* HASHCRYPT_SHA_DO_CHECK_CONTEXT */
- if (ctxInternal->state == kHASHCRYPT_HashInit)
- {
- hashcrypt_engine_init(base, ctxInternal->algo);
- }
- size_t outSize = 0u;
- /* compute algorithm output length */
- switch (ctxInternal->algo)
- {
- case kHASHCRYPT_Sha1:
- outSize = kHASHCRYPT_OutLenSha1;
- break;
- case kHASHCRYPT_Sha256:
- outSize = kHASHCRYPT_OutLenSha256;
- break;
- default:
- break;
- }
- algOutSize = outSize;
- /* flush message last incomplete block, if there is any, and add padding bits */
- status = hashcrypt_sha_finalize(base, ctxInternal);
- if (outputSize)
- {
- if (algOutSize < *outputSize)
- {
- *outputSize = algOutSize;
- }
- else
- {
- algOutSize = *outputSize;
- }
- }
- hashcrypt_get_data(base, (uint32_t *)output, algOutSize);
- #ifdef HASHCRYPT_SHA_DO_WIPE_CONTEXT
- ctxW = (uint32_t *)ctx;
- for (i = 0; i < HASHCRYPT_HASH_CTX_SIZE; i++)
- {
- ctxW[i] = 0u;
- }
- #endif /* HASHCRYPT_SHA_DO_WIPE_CONTEXT */
- return status;
- }
- /*!
- * brief Initializes the HASHCRYPT handle for background hashing.
- *
- * This function initializes the hash context for background hashing
- * (Non-blocking) APIs. This is less typical interface to hash function, but can be used
- * for parallel processing, when main CPU has something else to do.
- * Example is digital signature RSASSA-PKCS1-V1_5-VERIFY((n,e),M,S) algorithm, where
- * background hashing of M can be started, then CPU can compute S^e mod n
- * (in parallel with background hashing) and once the digest becomes available,
- * CPU can proceed to comparison of EM with EM'.
- *
- * param base HASHCRYPT peripheral base address.
- * param[out] ctx Hash context.
- * param callback Callback function.
- * param userData User data (to be passed as an argument to callback function, once callback is invoked from isr).
- */
- void HASHCRYPT_SHA_SetCallback(HASHCRYPT_Type *base,
- hashcrypt_hash_ctx_t *ctx,
- hashcrypt_callback_t callback,
- void *userData)
- {
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- s_ctx = ctx;
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
- ctxInternal->hashCallback = callback;
- ctxInternal->userData = userData;
- EnableIRQ(HASHCRYPT_IRQn);
- }
- /*!
- * brief Create running hash on given data.
- *
- * Configures the HASHCRYPT to compute new running hash as AHB master
- * and returns immediately. HASHCRYPT AHB Master mode supports only aligned \p input
- * address and can be called only once per continuous block of data. Every call to this function
- * must be preceded with HASHCRYPT_SHA_Init() and finished with HASHCRYPT_SHA_Finish().
- * Once callback function is invoked by HASHCRYPT isr, it should set a flag
- * for the main application to finalize the hashing (padding) and to read out the final digest
- * by calling HASHCRYPT_SHA_Finish().
- *
- * param base HASHCRYPT peripheral base address
- * param ctx Specifies callback. Last incomplete 512-bit block of the input is copied into clear buffer for padding.
- * param input 32-bit word aligned pointer to Input data.
- * param inputSize Size of input data in bytes (must be word aligned)
- * return Status of the hash update operation.
- */
- status_t HASHCRYPT_SHA_UpdateNonBlocking(HASHCRYPT_Type *base,
- hashcrypt_hash_ctx_t *ctx,
- const uint8_t *input,
- size_t inputSize)
- {
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- uint32_t numBlocks;
- status_t status;
- if (inputSize == 0)
- {
- return kStatus_Success;
- }
- if ((uintptr_t)input & 0x3U)
- {
- return kStatus_Fail;
- }
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)ctx;
- status = hashcrypt_sha_check_context(base, ctxInternal);
- if (kStatus_Success != status)
- {
- return status;
- }
- ctxInternal->fullMessageSize = inputSize;
- ctxInternal->remainingBlcks = inputSize / SHA_BLOCK_SIZE;
- ctxInternal->blksz = inputSize % SHA_BLOCK_SIZE;
- /* copy last incomplete block to context */
- if ((ctxInternal->blksz > 0) && (ctxInternal->blksz <= SHA_BLOCK_SIZE))
- {
- hashcrypt_memcpy((&ctxInternal->blk.b[0]), input + SHA_BLOCK_SIZE * ctxInternal->remainingBlcks,
- ctxInternal->blksz);
- }
- if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
- {
- numBlocks = SHA_MASTER_MAX_BLOCKS - 1;
- }
- else
- {
- numBlocks = ctxInternal->remainingBlcks;
- }
- /* update remainingBlks so that ISR can run another hash if necessary */
- ctxInternal->remainingBlcks -= numBlocks;
- /* compute hash using AHB Master mode for full blocks */
- if (numBlocks > 0)
- {
- ctxInternal->state = kHASHCRYPT_HashUpdate;
- hashcrypt_engine_init(base, ctxInternal->algo);
- /* Enable digest and error interrupts and start hash */
- base->INTENSET = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
- base->MEMADDR = FSL_FEATURE_HASHCRYPT_ALIAS_OFFSET | HASHCRYPT_MEMADDR_BASE(input);
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
- }
- /* no full blocks, invoke callback directly */
- else
- {
- ctxInternal->hashCallback(HASHCRYPT, ctx, status, ctxInternal->userData);
- }
- return status;
- }
- /*!
- * brief Set AES key to hashcrypt_handle_t struct and optionally to HASHCRYPT.
- *
- * Sets the AES key for encryption/decryption with the hashcrypt_handle_t structure.
- * The hashcrypt_handle_t input argument specifies key source.
- *
- * param base HASHCRYPT peripheral base address.
- * param handle Handle used for the request.
- * param key 0-mod-4 aligned pointer to AES key.
- * param keySize AES key size in bytes. Shall equal 16, 24 or 32.
- * return status from set key operation
- */
- status_t HASHCRYPT_AES_SetKey(HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *key, size_t aesKeySize)
- {
- switch (aesKeySize)
- {
- case 16:
- handle->keySize = kHASHCRYPT_Aes128;
- break;
- case 24:
- handle->keySize = kHASHCRYPT_Aes192;
- break;
- case 32:
- handle->keySize = kHASHCRYPT_Aes256;
- break;
- default:
- handle->keySize = kHASHCRYPT_InvalidKey;
- break;
- }
- if (handle->keySize == kHASHCRYPT_InvalidKey)
- {
- return kStatus_InvalidArgument;
- }
- if (handle->keyType == kHASHCRYPT_SecretKey)
- {
- /* for kHASHCRYPT_SecretKey just return Success */
- return kStatus_Success;
- }
- else if (handle->keyType == kHASHCRYPT_UserKey)
- {
- /* only work with aligned key[] */
- if (0x3U & (uintptr_t)key)
- {
- return kStatus_InvalidArgument;
- }
- /* move the key by 32-bit words */
- int i = 0;
- while (aesKeySize)
- {
- aesKeySize -= sizeof(uint32_t);
- handle->keyWord[i] = ((uint32_t *)(uintptr_t)key)[i];
- i++;
- }
- }
- else
- {
- return kStatus_InvalidArgument;
- }
- return kStatus_Success;
- }
- /*!
- * brief Encrypts AES on one or multiple 128-bit block(s).
- *
- * Encrypts AES.
- * The source plaintext and destination ciphertext can overlap in system memory.
- *
- * param base HASHCRYPT peripheral base address
- * param handle Handle used for this request.
- * param plaintext Input plain text to encrypt
- * param[out] ciphertext Output cipher text
- * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
- * return Status from encrypt operation
- */
- status_t HASHCRYPT_AES_EncryptEcb(
- HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *plaintext, uint8_t *ciphertext, size_t size)
- {
- status_t status = kStatus_Fail;
- if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
- {
- return kStatus_InvalidArgument;
- }
- uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
- base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
- HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
- HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
- HASHCRYPT_CRYPTCFG_MSW1ST(1);
- hashcrypt_engine_init(base, kHASHCRYPT_Aes);
- /* load key if kHASHCRYPT_UserKey is selected */
- if (handle->keyType == kHASHCRYPT_UserKey)
- {
- hashcrypt_aes_load_userKey(base, handle);
- }
- /* load message and get result */
- status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
- return status;
- }
- /*!
- * brief Decrypts AES on one or multiple 128-bit block(s).
- *
- * Decrypts AES.
- * The source ciphertext and destination plaintext can overlap in system memory.
- *
- * param base HASHCRYPT peripheral base address
- * param handle Handle used for this request.
- * param ciphertext Input plain text to encrypt
- * param[out] plaintext Output cipher text
- * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
- * return Status from decrypt operation
- */
- status_t HASHCRYPT_AES_DecryptEcb(
- HASHCRYPT_Type *base, hashcrypt_handle_t *handle, const uint8_t *ciphertext, uint8_t *plaintext, size_t size)
- {
- status_t status = kStatus_Fail;
- if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
- {
- return kStatus_InvalidArgument;
- }
- uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
- base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesEcb) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
- HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
- HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
- HASHCRYPT_CRYPTCFG_MSW1ST(1);
- hashcrypt_engine_init(base, kHASHCRYPT_Aes);
- /* load key if kHASHCRYPT_UserKey is selected */
- if (handle->keyType == kHASHCRYPT_UserKey)
- {
- hashcrypt_aes_load_userKey(base, handle);
- }
- /* load message and get result */
- status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
- return status;
- }
- /*!
- * brief Encrypts AES using CBC block mode.
- *
- * param base HASHCRYPT peripheral base address
- * param handle Handle used for this request.
- * param plaintext Input plain text to encrypt
- * param[out] ciphertext Output cipher text
- * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
- * param iv Input initial vector to combine with the first input block.
- * return Status from encrypt operation
- */
- status_t HASHCRYPT_AES_EncryptCbc(HASHCRYPT_Type *base,
- hashcrypt_handle_t *handle,
- const uint8_t *plaintext,
- uint8_t *ciphertext,
- size_t size,
- const uint8_t iv[16])
- {
- status_t status = kStatus_Fail;
- if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
- {
- return kStatus_InvalidArgument;
- }
- uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
- base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
- HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
- HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
- HASHCRYPT_CRYPTCFG_MSW1ST(1);
- hashcrypt_engine_init(base, kHASHCRYPT_Aes);
- /* load key if kHASHCRYPT_UserKey is selected */
- if (handle->keyType == kHASHCRYPT_UserKey)
- {
- hashcrypt_aes_load_userKey(base, handle);
- }
- /* load 16b iv */
- hashcrypt_load_data(base, (uint32_t *)iv, 16);
- /* load message and get result */
- status = hashcrypt_aes_one_block(base, plaintext, ciphertext, size);
- return status;
- }
- /*!
- * brief Decrypts AES using CBC block mode.
- *
- * param base HASHCRYPT peripheral base address
- * param handle Handle used for this request.
- * param ciphertext Input cipher text to decrypt
- * param[out] plaintext Output plain text
- * param size Size of input and output data in bytes. Must be multiple of 16 bytes.
- * param iv Input initial vector to combine with the first input block.
- * return Status from decrypt operation
- */
- status_t HASHCRYPT_AES_DecryptCbc(HASHCRYPT_Type *base,
- hashcrypt_handle_t *handle,
- const uint8_t *ciphertext,
- uint8_t *plaintext,
- size_t size,
- const uint8_t iv[16])
- {
- status_t status = kStatus_Fail;
- if ((size % 16u) || (handle->keySize == kHASHCRYPT_InvalidKey))
- {
- return kStatus_InvalidArgument;
- }
- uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
- base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCbc) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_DECRYPT) |
- HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
- HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
- HASHCRYPT_CRYPTCFG_MSW1ST(1);
- hashcrypt_engine_init(base, kHASHCRYPT_Aes);
- /* load key if kHASHCRYPT_UserKey is selected */
- if (handle->keyType == kHASHCRYPT_UserKey)
- {
- hashcrypt_aes_load_userKey(base, handle);
- }
- /* load iv */
- hashcrypt_load_data(base, (uint32_t *)iv, 16);
- /* load message and get result */
- status = hashcrypt_aes_one_block(base, ciphertext, plaintext, size);
- return status;
- }
- /*!
- * brief Encrypts or decrypts AES using CTR block mode.
- *
- * Encrypts or decrypts AES using CTR block mode.
- * AES CTR mode uses only forward AES cipher and same algorithm for encryption and decryption.
- * The only difference between encryption and decryption is that, for encryption, the input argument
- * is plain text and the output argument is cipher text. For decryption, the input argument is cipher text
- * and the output argument is plain text.
- *
- * param base HASHCRYPT peripheral base address
- * param handle Handle used for this request.
- * param input Input data for CTR block mode
- * param[out] output Output data for CTR block mode
- * param size Size of input and output data in bytes
- * param[in,out] counter Input counter (updates on return)
- * param[out] counterlast Output cipher of last counter, for chained CTR calls (statefull encryption). NULL can be
- * passed if chained calls are
- * not used.
- * param[out] szLeft Output number of bytes in left unused in counterlast block. NULL can be passed if chained calls
- * are not used.
- * return Status from encrypt operation
- */
- status_t HASHCRYPT_AES_CryptCtr(HASHCRYPT_Type *base,
- hashcrypt_handle_t *handle,
- const uint8_t *input,
- uint8_t *output,
- size_t size,
- uint8_t counter[HASHCRYPT_AES_BLOCK_SIZE],
- uint8_t counterlast[HASHCRYPT_AES_BLOCK_SIZE],
- size_t *szLeft)
- {
- uint32_t lastSize;
- uint8_t lastBlock[HASHCRYPT_AES_BLOCK_SIZE] = {0};
- uint8_t *lastEncryptedCounter;
- status_t status = kStatus_Fail;
- if (handle->keySize == kHASHCRYPT_InvalidKey)
- {
- return kStatus_InvalidArgument;
- }
- uint32_t keyType = (handle->keyType == kHASHCRYPT_UserKey) ? 0 : 1u;
- base->CRYPTCFG = HASHCRYPT_CRYPTCFG_AESMODE(kHASHCRYPT_AesCtr) | HASHCRYPT_CRYPTCFG_AESDECRYPT(AES_ENCRYPT) |
- HASHCRYPT_CRYPTCFG_AESSECRET(keyType) | HASHCRYPT_CRYPTCFG_AESKEYSZ(handle->keySize) |
- HASHCRYPT_CRYPTCFG_MSW1ST_OUT(1) | HASHCRYPT_CRYPTCFG_SWAPKEY(1) | HASHCRYPT_CRYPTCFG_SWAPDAT(1) |
- HASHCRYPT_CRYPTCFG_MSW1ST(1);
- hashcrypt_engine_init(base, kHASHCRYPT_Aes);
- /* load key if kHASHCRYPT_UserKey is selected */
- if (handle->keyType == kHASHCRYPT_UserKey)
- {
- hashcrypt_aes_load_userKey(base, handle);
- }
- /* load nonce */
- hashcrypt_load_data(base, (uint32_t *)counter, 16);
- lastSize = size % HASHCRYPT_AES_BLOCK_SIZE;
- size -= lastSize;
- /* encrypt full 16byte blocks */
- hashcrypt_aes_one_block(base, input, output, size);
- while (size)
- {
- ctrIncrement(counter);
- size -= 16u;
- input += 16;
- output += 16;
- }
- if (lastSize)
- {
- if (counterlast)
- {
- lastEncryptedCounter = counterlast;
- }
- else
- {
- lastEncryptedCounter = lastBlock;
- }
- /* Perform encryption with all zeros to get last counter. XOR with zeros doesn't change. */
- status = hashcrypt_aes_one_block(base, lastBlock, lastEncryptedCounter, HASHCRYPT_AES_BLOCK_SIZE);
- if (status != kStatus_Success)
- {
- return status;
- }
- /* remain output = input XOR counterlast */
- for (uint32_t i = 0; i < lastSize; i++)
- {
- output[i] = input[i] ^ lastEncryptedCounter[i];
- }
- /* Increment counter parameter */
- ctrIncrement(counter);
- }
- else
- {
- lastSize = HASHCRYPT_AES_BLOCK_SIZE;
- /* no remaining bytes in couterlast so clearing it */
- if (counterlast)
- {
- memset(counterlast, 0, HASHCRYPT_AES_BLOCK_SIZE);
- }
- }
- if (szLeft)
- {
- *szLeft = HASHCRYPT_AES_BLOCK_SIZE - lastSize;
- }
- return kStatus_Success;
- }
- void HASH_IRQHandler(void)
- {
- hashcrypt_sha_ctx_internal_t *ctxInternal;
- HASHCRYPT_Type *base = HASHCRYPT;
- uint32_t numBlocks;
- status_t status;
- ctxInternal = (hashcrypt_sha_ctx_internal_t *)s_ctx;
- if (0 == (base->STATUS & HASHCRYPT_STATUS_ERROR_MASK))
- {
- if (ctxInternal->remainingBlcks > 0)
- {
- if (ctxInternal->remainingBlcks >= SHA_MASTER_MAX_BLOCKS)
- {
- numBlocks = SHA_MASTER_MAX_BLOCKS - 1;
- }
- else
- {
- numBlocks = ctxInternal->remainingBlcks;
- }
- /* some blocks still remaining, update remainingBlcks for next ISR and start another hash */
- ctxInternal->remainingBlcks -= numBlocks;
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(1) | HASHCRYPT_MEMCTRL_COUNT(numBlocks);
- return;
- }
- /* no full blocks left, disable interrupts and AHB master mode */
- base->INTENCLR = HASHCRYPT_INTENCLR_DIGEST_MASK | HASHCRYPT_INTENCLR_ERROR_MASK;
- base->MEMCTRL = HASHCRYPT_MEMCTRL_MASTER(0);
- status = kStatus_Success;
- }
- else
- {
- status = kStatus_Fail;
- }
- /* Invoke callback if there is one */
- if (NULL != ctxInternal->hashCallback)
- {
- ctxInternal->hashCallback(HASHCRYPT, s_ctx, status, ctxInternal->userData);
- }
- }
- /*!
- * brief Enables clock and disables reset for HASHCRYPT peripheral.
- *
- * Enable clock and disable reset for HASHCRYPT.
- *
- * param base HASHCRYPT base address
- */
- void HASHCRYPT_Init(HASHCRYPT_Type *base)
- {
- RESET_PeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- CLOCK_EnableClock(kCLOCK_HashCrypt);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- }
- /*!
- * brief Disables clock for HASHCRYPT peripheral.
- *
- * Disable clock and enable reset.
- *
- * param base HASHCRYPT base address
- */
- void HASHCRYPT_Deinit(HASHCRYPT_Type *base)
- {
- RESET_SetPeripheralReset(kHASHCRYPT_RST_SHIFT_RSTn);
- #if !(defined(FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL) && FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL)
- CLOCK_DisableClock(kCLOCK_HashCrypt);
- #endif /* FSL_SDK_DISABLE_DRIVER_CLOCK_CONTROL */
- }
|