CC26xx Driver Library
sha2.c File Reference
#include "sha2.h"

Functions

static uint32_t SHA2ExecuteHash (const uint8_t *message, uint8_t *resultDigest, uint32_t *intermediateDigest, uint32_t totalMsgLength, uint32_t messageLength, uint32_t hashAlgorithm, bool initialHash, bool finalHash)
 
void SHA2StartDMAOperation (uint8_t *channel0Addr, uint32_t channel0Length, uint8_t *channel1Addr, uint32_t channel1Length)
 Start a crypto DMA operation. More...
 
uint32_t SHA2WaitForIRQFlags (uint32_t irqFlags)
 Poll the interrupt status register and clear when done. More...
 
uint32_t SHA2ComputeInitialHash (const uint8_t *message, uint32_t *intermediateDigest, uint32_t hashAlgorithm, uint32_t initialMessageLength)
 Start a new SHA-2 hash operation. More...
 
uint32_t SHA2ComputeIntermediateHash (const uint8_t *message, uint32_t *intermediateDigest, uint32_t hashAlgorithm, uint32_t intermediateMessageLength)
 Resume a SHA-2 hash operation but do not finalize it. More...
 
uint32_t SHA2ComputeFinalHash (const uint8_t *message, uint8_t *resultDigest, uint32_t *intermediateDigest, uint32_t totalMsgLength, uint32_t messageLength, uint32_t hashAlgorithm)
 Resume a SHA-2 hash operation and finalize it. More...
 
uint32_t SHA2ComputeHash (const uint8_t *message, uint8_t *resultDigest, uint32_t totalMsgLength, uint32_t hashAlgorithm)
 Start a SHA-2 hash operation and return the finalized digest. More...
 

Function Documentation

static uint32_t SHA2ExecuteHash ( const uint8_t *  message,
uint8_t *  resultDigest,
uint32_t *  intermediateDigest,
uint32_t  totalMsgLength,
uint32_t  messageLength,
uint32_t  hashAlgorithm,
bool  initialHash,
bool  finalHash 
)
static

Referenced by SHA2ComputeFinalHash(), SHA2ComputeHash(), SHA2ComputeInitialHash(), and SHA2ComputeIntermediateHash().

205 {
206  uint8_t digestLength = 0;
207  uint32_t dmaAlgorithmSelect = 0;
208 
210 
211  switch (hashAlgorithm) {
213  digestLength = SHA2_SHA224_DIGEST_LENGTH_BYTES;
214  dmaAlgorithmSelect = SHA2_ALGSEL_SHA256;
215  break;
217  digestLength = SHA2_SHA256_DIGEST_LENGTH_BYTES;
218  dmaAlgorithmSelect = SHA2_ALGSEL_SHA256;
219  break;
221  digestLength = SHA2_SHA384_DIGEST_LENGTH_BYTES;
222  dmaAlgorithmSelect = SHA2_ALGSEL_SHA512;
223  break;
225  digestLength = SHA2_SHA512_DIGEST_LENGTH_BYTES;
226  dmaAlgorithmSelect = SHA2_ALGSEL_SHA512;
227  break;
228  default:
229  return SHA2_INVALID_ALGORITHM;
230  }
231 
232  if (initialHash && finalHash) {
233  // The empty string is a perfectly valid message. It obviously has a length of 0. The DMA cannot
234  // handle running with a transfer length of 0. This workaround depends on the hash engine adding the
235  // trailing 1 bit and 0-padding bits after the DMAtransfer is complete and not in the DMA itself.
236  // totalMsgLength is purposefully not altered as it is appended to the end of the message during finalization
237  // and determines how many padding-bytes are added.
238  // Altering totalMsgLength would alter the final hash digest.
239  // Because totalMsgLength specifies that the message is of length 0, the content of the byte loaded
240  // through the DMA is irrelevant. It is overwritten internally in the hash engine.
241  messageLength = messageLength ? messageLength : 1;
242  }
243 
244  // Setting the incorrect number of bits here leads to the calculation of the correct result
245  // but a failure to read them out.
246  // The tag bit is set to read out the digest via DMA rather than through the slave interface.
247  SHA2SelectAlgorithm(dmaAlgorithmSelect | (resultDigest ? SHA2_ALGSEL_TAG : 0));
250 
251  HWREG(CRYPTO_BASE + CRYPTO_O_HASHMODE) = hashAlgorithm | (initialHash ? CRYPTO_HASHMODE_NEW_HASH_M : 0);
252 
253  // Only load the intermediate digest if requested.
254  if (intermediateDigest && !initialHash) {
255  SHA2SetDigest(intermediateDigest, digestLength);
256  }
257 
258  // If this is the final hash, finalization is required. This means appending a 1 bit, padding the message until this section
259  // is 448 bytes long, and adding the 64 bit total length of the message in bits. Thankfully, this is all done in hardware.
260  if (finalHash) {
261  // This specific length must be specified in bits not bytes.
262  SHA2SetMessageLength(totalMsgLength * 8);
263  HWREG(CRYPTO_BASE + CRYPTO_O_HASHIOBUFCTRL) = CRYPTO_HASHIOBUFCTRL_PAD_DMA_MESSAGE_M;
264 
265  }
266 
267  // The cast is fine in this case. SHA2StartDMAOperation channel one serves as input and no one does
268  // hash operations in-place.
269  SHA2StartDMAOperation((uint8_t *)message, messageLength, resultDigest, digestLength);
270 
271  return SHA2_SUCCESS;
272 }
#define SHA2_ALGSEL_SHA512
Definition: sha2.h:151
static void SHA2SetMessageLength(uint32_t length)
Specify the total length of the message.
Definition: sha2.h:484
#define SHA2_RESULT_RDY
Definition: sha2.h:105
#define SHA2_SHA512_DIGEST_LENGTH_BYTES
Definition: sha2.h:127
static void SHA2IntEnable(uint32_t intFlags)
Enable individual crypto interrupt sources.
Definition: sha2.h:588
#define SHA2_MODE_SELECT_SHA224
Definition: sha2.h:131
static void SHA2SetDigest(uint32_t *digest, uint8_t digestLength)
Load an intermediate digest.
Definition: sha2.h:506
#define SHA2_SHA384_DIGEST_LENGTH_BYTES
Definition: sha2.h:126
#define SHA2_MODE_SELECT_SHA512
Definition: sha2.h:134
static void SHA2ClearDigestAvailableFlag(void)
Confirm digest was read.
Definition: sha2.h:568
#define SHA2_ALGSEL_TAG
Definition: sha2.h:152
#define SHA2_SHA224_DIGEST_LENGTH_BYTES
Definition: sha2.h:124
#define SHA2_SHA256_DIGEST_LENGTH_BYTES
Definition: sha2.h:125
void SHA2StartDMAOperation(uint8_t *channel0Addr, uint32_t channel0Length, uint8_t *channel1Addr, uint32_t channel1Length)
Start a crypto DMA operation.
Definition: sha2.c:71
static void SHA2IntClear(uint32_t intFlags)
Clear crypto interrupt sources.
Definition: sha2.h:687
static void SHA2SelectAlgorithm(uint32_t algorithm)
Configure the crypto DMA for a particular operation.
Definition: sha2.h:455
#define SHA2_DMA_IN_DONE
Definition: sha2.h:104
#define SHA2_MODE_SELECT_SHA256
Definition: sha2.h:132
#define SHA2_ALGSEL_SHA256
Definition: sha2.h:150
#define SHA2_INVALID_ALGORITHM
Definition: sha2.h:117
#define SHA2_SUCCESS
Definition: sha2.h:116
#define SHA2_MODE_SELECT_SHA384
Definition: sha2.h:133

Here is the call graph for this function: