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().

204 {
205  uint8_t digestLength = 0;
206  uint32_t dmaAlgorithmSelect = 0;
207 
209 
210  switch (hashAlgorithm) {
212  digestLength = SHA2_SHA224_DIGEST_LENGTH_BYTES;
213  dmaAlgorithmSelect = SHA2_ALGSEL_SHA256;
214  break;
216  digestLength = SHA2_SHA256_DIGEST_LENGTH_BYTES;
217  dmaAlgorithmSelect = SHA2_ALGSEL_SHA256;
218  break;
220  digestLength = SHA2_SHA384_DIGEST_LENGTH_BYTES;
221  dmaAlgorithmSelect = SHA2_ALGSEL_SHA512;
222  break;
224  digestLength = SHA2_SHA512_DIGEST_LENGTH_BYTES;
225  dmaAlgorithmSelect = SHA2_ALGSEL_SHA512;
226  break;
227  default:
228  return SHA2_INVALID_ALGORITHM;
229  }
230 
231  if (initialHash && finalHash) {
232  // The empty string is a perfectly valid message. It obviously has a length of 0. The DMA cannot
233  // handle running with a transfer length of 0. This workaround depends on the hash engine adding the
234  // trailing 1 bit and 0-padding bits after the DMAtransfer is complete and not in the DMA itself.
235  // totalMsgLength is purposefully not altered as it is appended to the end of the message during finalization
236  // and determines how many padding-bytes are added.
237  // Altering totalMsgLength would alter the final hash digest.
238  // Because totalMsgLength specifies that the message is of length 0, the content of the byte loaded
239  // through the DMA is irrelevant. It is overwritten internally in the hash engine.
240  messageLength = messageLength ? messageLength : 1;
241  }
242 
243  // Setting the incorrect number of bits here leads to the calculation of the correct result
244  // but a failure to read them out.
245  // The tag bit is set to read out the digest via DMA rather than through the slave interface.
246  SHA2SelectAlgorithm(dmaAlgorithmSelect | (resultDigest ? SHA2_ALGSEL_TAG : 0));
249 
250  HWREG(CRYPTO_BASE + CRYPTO_O_HASHMODE) = hashAlgorithm | (initialHash ? CRYPTO_HASHMODE_NEW_HASH_M : 0);
251 
252  // Only load the intermediate digest if requested.
253  if (intermediateDigest && !initialHash) {
254  SHA2SetDigest(intermediateDigest, digestLength);
255  }
256 
257  // If this is the final hash, finalization is required. This means appending a 1 bit, padding the message until this section
258  // is 448 bytes long, and adding the 64 bit total length of the message in bits. Thankfully, this is all done in hardware.
259  if (finalHash) {
260  // This specific length must be specified in bits not bytes.
261  SHA2SetMessageLength(totalMsgLength * 8);
262  HWREG(CRYPTO_BASE + CRYPTO_O_HASHIOBUFCTRL) = CRYPTO_HASHIOBUFCTRL_PAD_DMA_MESSAGE_M;
263 
264  }
265 
266  // The cast is fine in this case. SHA2StartDMAOperation channel one serves as input and no one does
267  // hash operations in-place.
268  SHA2StartDMAOperation((uint8_t *)message, messageLength, resultDigest, digestLength);
269 
270  return SHA2_SUCCESS;
271 }
#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: