1 /******************************************************************************
2 * Filename: sha2.h
3 *
4 * Description: SHA-2 header file.
5 *
6 * Copyright (c) 2015 - 2022, Texas Instruments Incorporated
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1) Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2) Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3) Neither the name of the ORGANIZATION nor the names of its contributors may
20 * be used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
24 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
25 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
27 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33 * POSSIBILITY OF SUCH DAMAGE.
34 *
35 ******************************************************************************/
36
37 //*****************************************************************************
38 //
39 //! \addtogroup peripheral_group
40 //! @{
41 //! \addtogroup sha2_api
42 //! @{
43 //
44 //*****************************************************************************
45
46 #ifndef __SHA2_H__
47 #define __SHA2_H__
48
49 //*****************************************************************************
50 //
51 // If building with a C++ compiler, make all of the definitions in this header
52 // have a C binding.
53 //
54 //*****************************************************************************
55 #ifdef __cplusplus
56 extern "C"
57 {
58 #endif
59
60 #include <stdbool.h>
61 #include <stdint.h>
62 #include <stddef.h>
63 #include "../inc/hw_types.h"
64 #include "../inc/hw_memmap.h"
65 #include "../inc/hw_ints.h"
66 #include "../inc/hw_crypto.h"
67 #include "../inc/hw_ccfg.h"
68 #include "debug.h"
69 #include "interrupt.h"
70 #include "cpu.h"
71
72 //*****************************************************************************
73 //
74 // Support for DriverLib in ROM:
75 // This section renames all functions that are not "static inline", so that
76 // calling these functions will default to implementation in flash. At the end
77 // of this file a second renaming will change the defaults to implementation in
78 // ROM for available functions.
79 //
80 // To force use of the implementation in flash, e.g. for debugging:
81 // - Globally: Define DRIVERLIB_NOROM at project level
82 // - Per function: Use prefix "NOROM_" when calling the function
83 //
84 //*****************************************************************************
85 #if !defined(DOXYGEN)
86 #define SHA2StartDMAOperation NOROM_SHA2StartDMAOperation
87 #define SHA2WaitForIRQFlags NOROM_SHA2WaitForIRQFlags
88 #define SHA2ComputeInitialHash NOROM_SHA2ComputeInitialHash
89 #define SHA2ComputeIntermediateHash NOROM_SHA2ComputeIntermediateHash
90 #define SHA2ComputeFinalHash NOROM_SHA2ComputeFinalHash
91 #define SHA2ComputeHash NOROM_SHA2ComputeHash
92 #endif
93
94 //*****************************************************************************
95 //
96 // Values that can be passed to SHA2IntEnable, SHA2IntDisable, and SHA2IntClear
97 // as the intFlags parameter, and returned from SHA2IntStatus.
98 // Only SHA2_DMA_IN_DONE and SHA2_RESULT_RDY are routed to the NVIC. Check each
99 // function to see if it supports other interrupt status flags.
100 //
101 //*****************************************************************************
102 #define SHA2_DMA_IN_DONE (CRYPTO_IRQEN_DMA_IN_DONE_M)
103 #define SHA2_RESULT_RDY (CRYPTO_IRQEN_RESULT_AVAIL_M)
104 #define SHA2_DMA_BUS_ERR (CRYPTO_IRQCLR_DMA_BUS_ERR_M)
105
106
107 //*****************************************************************************
108 //
109 // General constants
110 //
111 //*****************************************************************************
112
113 // SHA-2 module return codes
114 #define SHA2_SUCCESS 0
115 #define SHA2_INVALID_ALGORITHM 1
116 #define SHA2_DMA_BUSY 3
117 #define SHA2_DMA_ERROR 4
118 #define SHA2_DIGEST_NOT_READY 5
119 #define SHA2_OLD_DIGEST_NOT_READ 6
120
121 // SHA-2 output digest lengths in bytes.
122 #define SHA2_SHA224_DIGEST_LENGTH_BYTES (224 / 8)
123 #define SHA2_SHA256_DIGEST_LENGTH_BYTES (256 / 8)
124 #define SHA2_SHA384_DIGEST_LENGTH_BYTES (384 / 8)
125 #define SHA2_SHA512_DIGEST_LENGTH_BYTES (512 / 8)
126
127 //Selectable SHA-2 modes. They determine the algorithm used and if initial
128 //values will be set to the default constants or not
129 #define SHA2_MODE_SELECT_SHA224 (CRYPTO_HASHMODE_SHA224_MODE_M)
130 #define SHA2_MODE_SELECT_SHA256 (CRYPTO_HASHMODE_SHA256_MODE_M)
131 #define SHA2_MODE_SELECT_SHA384 (CRYPTO_HASHMODE_SHA384_MODE_M)
132 #define SHA2_MODE_SELECT_SHA512 (CRYPTO_HASHMODE_SHA512_MODE_M)
133 #define SHA2_MODE_SELECT_NEW_HASH (CRYPTO_HASHMODE_NEW_HASH_M)
134
135 // SHA-2 block lengths. When hashing block-wise, they define the size of each
136 // block provided to the new and intermediate hash functions.
137 #define SHA2_SHA224_BLOCK_SIZE_BYTES (512 / 8)
138 #define SHA2_SHA256_BLOCK_SIZE_BYTES (512 / 8)
139 #define SHA2_SHA384_BLOCK_SIZE_BYTES (1024 / 8)
140 #define SHA2_SHA512_BLOCK_SIZE_BYTES (1024 / 8)
141
142 // DMA status codes
143 #define SHA2_DMA_CHANNEL0_ACTIVE (CRYPTO_DMASTAT_CH0_ACT_M)
144 #define SHA2_DMA_CHANNEL1_ACTIVE (CRYPTO_DMASTAT_CH1_ACT_M)
145 #define SHA2_DMA_PORT_ERROR (CRYPTO_DMASTAT_PORT_ERR_M)
146
147 // Crypto module DMA operation types
148 #define SHA2_ALGSEL_SHA256 0x04
149 #define SHA2_ALGSEL_SHA512 0x08
150 #define SHA2_ALGSEL_TAG (CRYPTO_ALGSEL_TAG_M)
151
152
153
154 //*****************************************************************************
155 //
156 // API Functions and prototypes
157 //
158 //*****************************************************************************
159
160 //*****************************************************************************
161 //
162 //! \brief Start a crypto DMA operation
163 //!
164 //! Enable the crypto DMA channels, configure the channel addresses,
165 //! and set the length of the data transfer.
166 //! Setting the length of the data transfer automatically starts the
167 //! transfer. It is also used by the hardware module as a signal to
168 //! begin the encryption, decryption, or MAC operation.
169 //!
170 //! \param [in] channel0Addr
171 //! A pointer to the address channel 0 shall use.
172 //!
173 //! \param [in] channel0Length
174 //! Length of the data in bytes to be read from or written to at
175 //! \c channel0Addr. Set to 0 to not set up this channel.
176 //!
177 //! \param [out] channel1Addr
178 //! A pointer to the address channel 1 shall use.
179 //!
180 //! \param [in] channel1Length
181 //! Length of the data in bytes to be read from or written to at
182 //! \c channel1Addr. Set to 0 to not set up this channel.
183 //!
184 //! \return None
185 //
186 //*****************************************************************************
187 extern void SHA2StartDMAOperation(uint8_t *channel0Addr, uint32_t channel0Length, uint8_t *channel1Addr, uint32_t channel1Length);
188
189 //*****************************************************************************
190 //
191 //! \brief Poll the interrupt status register and clear when done.
192 //!
193 //! This function polls until one of the bits in the \c irqFlags is
194 //! asserted. Only \ref SHA2_DMA_IN_DONE and \ref SHA2_RESULT_RDY can actually
195 //! trigger the interrupt line. That means that one of those should
196 //! always be included in \c irqFlags and will always be returned together
197 //! with any error codes.
198 //!
199 //! \param [in] irqFlags
200 //! IRQ flags to poll and mask that the status register will be
201 //! masked with. Consists of any bitwise OR of the flags
202 //! below that includes at least one of
203 //! \ref SHA2_DMA_IN_DONE or \ref SHA2_RESULT_RDY :
204 //! - \ref SHA2_DMA_IN_DONE
205 //! - \ref SHA2_RESULT_RDY
206 //! - \ref SHA2_DMA_BUS_ERR
207 //!
208 //! \return Returns the IRQ status register masked with \c irqFlags. May be any
209 //! bitwise OR of the following masks:
210 //! - \ref SHA2_DMA_IN_DONE
211 //! - \ref SHA2_RESULT_RDY
212 //! - \ref SHA2_DMA_BUS_ERR
213 //
214 //*****************************************************************************
215 extern uint32_t SHA2WaitForIRQFlags(uint32_t irqFlags);
216
217 //*****************************************************************************
218 //
219 //! \brief Start a new SHA-2 hash operation.
220 //!
221 //! This function begins a new piecewise hash operation.
222 //!
223 //! Call this function when starting a new hash operation and the
224 //! entire message is not yet available.
225 //!
226 //! Call SHA2ComputeIntermediateHash() or SHA2ComputeFinalHash()
227 //! after this call.
228 //!
229 //! If the device shall go into standby in between calls to this
230 //! function and either SHA2ComputeIntermediateHash() or
231 //! SHA2ComputeFinalHash(), the intermediate digest must be saved in
232 //! system RAM.
233 //!
234 //! \param [in] message
235 //! Byte array containing the start of the message to hash.
236 //! Must be exactly as long as the block length of the selected
237 //! algorithm.
238 //! - \ref SHA2_SHA224_BLOCK_SIZE_BYTES
239 //! - \ref SHA2_SHA256_BLOCK_SIZE_BYTES
240 //! - \ref SHA2_SHA384_BLOCK_SIZE_BYTES
241 //! - \ref SHA2_SHA512_BLOCK_SIZE_BYTES
242 //!
243 //! \param [out] intermediateDigest
244 //! Pointer to intermediate digest.
245 //! - NULL The intermediate digest will be stored in the internal
246 //! registers of the SHA module.
247 //! - Not NULL Specifies the location the intermediate digest will
248 //! be written to.
249 //!
250 //! Must be of a length equal to the digest length of the selected
251 //! hash algorithm.
252 //! Must be 32-bit aligned. \c intermediateDigest is copied into the
253 //! registers through the AHB slave interface in
254 //! SHA2ComputeIntermediateHash() and SHA2ComputeFinalHash().
255 //! This can only be done word-by-word.
256 //!
257 //! \param [in] hashAlgorithm Selects the hash algorithm to use. One of:
258 //! - \ref SHA2_MODE_SELECT_SHA224
259 //! - \ref SHA2_MODE_SELECT_SHA256
260 //! - \ref SHA2_MODE_SELECT_SHA384
261 //! - \ref SHA2_MODE_SELECT_SHA512
262 //!
263 //! \param [in] initialMessageLength The length in bytes of the first
264 //! section of the message to process. Must be a multiple of the
265 //! block size.
266 //!
267 //! \return Returns a SHA-2 return code.
268 //! - \ref SHA2_SUCCESS
269 //! - \ref SHA2_INVALID_ALGORITHM
270 //!
271 //! \sa SHA2ComputeIntermediateHash()
272 //! \sa SHA2ComputeFinalHash()
273 //
274 //*****************************************************************************
275 extern uint32_t SHA2ComputeInitialHash(const uint8_t *message, uint32_t *intermediateDigest, uint32_t hashAlgorithm, uint32_t initialMessageLength);
276
277 //*****************************************************************************
278 //
279 //! \brief Resume a SHA-2 hash operation but do not finalize it.
280 //!
281 //! This function resumes a previous hash operation.
282 //!
283 //! Call this function when continuing a hash operation and the
284 //! message is not yet complete.
285 //!
286 //! Call this function again or SHA2ComputeFinalHash()
287 //! after this call.
288 //!
289 //! If the device shall go into standby in between calls to this
290 //! function and SHA2ComputeFinalHash(), the intermediate
291 //! digest must be saved in system RAM.
292 //!
293 //! \param [in] message
294 //! Byte array containing the start of the current block of the
295 //! message to hash.
296 //! Must be exactly as long as the block length of the selected
297 //! algorithm.
298 //! - \ref SHA2_SHA224_BLOCK_SIZE_BYTES
299 //! - \ref SHA2_SHA256_BLOCK_SIZE_BYTES
300 //! - \ref SHA2_SHA384_BLOCK_SIZE_BYTES
301 //! - \ref SHA2_SHA512_BLOCK_SIZE_BYTES
302 //!
303 //! \param [in, out] intermediateDigest
304 //! Pointer to intermediate digest.
305 //! - NULL The intermediate digest will be sourced from the internal
306 //! registers of the SHA module and stored there after the
307 //! operation completes.
308 //! - Not NULL Specifies the location the intermediate digest will
309 //! be read from and written to.
310 //!
311 //! Must be of a length equal to the digest length of the selected
312 //! hash algorithm.
313 //! Must be 32-bit aligned. \c intermediateDigest is copied from and
314 //! to the registers through the AHB slave interface.
315 //! This can only be done word-by-word.
316 //!
317 //! \param [in] hashAlgorithm Selects the hash algorithm to use. One of:
318 //! - \ref SHA2_MODE_SELECT_SHA224
319 //! - \ref SHA2_MODE_SELECT_SHA256
320 //! - \ref SHA2_MODE_SELECT_SHA384
321 //! - \ref SHA2_MODE_SELECT_SHA512
322 //!
323 //! \param [in] intermediateMessageLength The length in bytes of this
324 //! section of the message to process. Must be a multiple of the
325 //! block size.
326 //!
327 //! \return Returns a SHA-2 return code.
328 //! - \ref SHA2_SUCCESS
329 //! - \ref SHA2_INVALID_ALGORITHM
330 //!
331 //! \sa SHA2ComputeInitialHash()
332 //! \sa SHA2ComputeFinalHash()
333 //
334 //*****************************************************************************
335 extern uint32_t SHA2ComputeIntermediateHash(const uint8_t *message, uint32_t *intermediateDigest, uint32_t hashAlgorithm, uint32_t intermediateMessageLength);
336
337 //*****************************************************************************
338 //
339 //! \brief Resume a SHA-2 hash operation and finalize it.
340 //!
341 //! This function resumes a previous hash session.
342 //!
343 //! Call this function when continuing a hash operation and the
344 //! message is complete.
345 //!
346 //! \param [in] message
347 //! Byte array containing the final block of the message to hash.
348 //! Any length <= the block size is acceptable.
349 //! The DMA finalize the message as necessary.
350 //! - \ref SHA2_SHA224_BLOCK_SIZE_BYTES
351 //! - \ref SHA2_SHA256_BLOCK_SIZE_BYTES
352 //! - \ref SHA2_SHA384_BLOCK_SIZE_BYTES
353 //! - \ref SHA2_SHA512_BLOCK_SIZE_BYTES
354 //!
355 //! \param [out] resultDigest
356 //! Byte array that the final digest will be written to. Must be of
357 //! a length equal to the digest length of the selected hash algorithm.
358 //!
359 //! \param [in] intermediateDigest
360 //! Pointer to intermediate digest.
361 //! - NULL The intermediate digest will be sourced from the internal
362 //! registers of the SHA module.
363 //! - Not NULL Specifies the location the intermediate digest will
364 //! be read from.
365 //! Must be of a length equal to the digest length of the selected
366 //! hash algorithm.
367 //! Must be 32-bit aligned. \c intermediateDigest is copied from and
368 //! to the registers through the AHB slave interface.
369 //! This can only be done word-by-word.
370 //!
371 //! \param [in] totalMsgLength
372 //! The length in bytes of the entire \c message including the sections
373 //! passed to previous calls to SHA2ComputeInitialHash() and
374 //! SHA2ComputeIntermediateHash().
375 //!
376 //! \param [in] messageLength The length in bytes of the last
377 //! section of the message to process. Does not need to be
378 //! a multiple of the block size.
379 //!
380 //! \param [in] hashAlgorithm Selects the hash algorithm to use. One of:
381 //! - \ref SHA2_MODE_SELECT_SHA224
382 //! - \ref SHA2_MODE_SELECT_SHA256
383 //! - \ref SHA2_MODE_SELECT_SHA384
384 //! - \ref SHA2_MODE_SELECT_SHA512
385 //!
386 //! \return Returns a SHA-2 return code.
387 //! - \ref SHA2_SUCCESS
388 //! - \ref SHA2_INVALID_ALGORITHM
389 //!
390 //! \sa SHA2ComputeInitialHash()
391 //! \sa SHA2ComputeIntermediateHash()
392 //
393 //*****************************************************************************
394 extern uint32_t SHA2ComputeFinalHash(const uint8_t *message, uint8_t *resultDigest, uint32_t *intermediateDigest, uint32_t totalMsgLength, uint32_t messageLength, uint32_t hashAlgorithm);
395
396 //*****************************************************************************
397 //
398 //! \brief Start a SHA-2 hash operation and return the finalized digest.
399 //!
400 //! This function starts a hash operation and returns the finalized
401 //! digest.
402 //!
403 //! Use this function if the entire message is available when starting
404 //! the hash.
405 //!
406 //! \param [in] message
407 //! Byte array containing the message that will be hashed.
408 //! Any length <= the block size is acceptable.
409 //! The DMA will finalize the message as necessary.
410 //! - \ref SHA2_SHA224_BLOCK_SIZE_BYTES
411 //! - \ref SHA2_SHA256_BLOCK_SIZE_BYTES
412 //! - \ref SHA2_SHA384_BLOCK_SIZE_BYTES
413 //! - \ref SHA2_SHA512_BLOCK_SIZE_BYTES
414 //!
415 //! \param [out] resultDigest
416 //! Byte array that the final digest will be written to. Must be of a
417 //! length equal to the digest length of the selected hash algorithm.
418 //!
419 //! \param [in] totalMsgLength
420 //! The length in bytes of the entire \c message.
421 //!
422 //! \param [in] hashAlgorithm Selects the hash algorithm to use. One of:
423 //! - \ref SHA2_MODE_SELECT_SHA224
424 //! - \ref SHA2_MODE_SELECT_SHA256
425 //! - \ref SHA2_MODE_SELECT_SHA384
426 //! - \ref SHA2_MODE_SELECT_SHA512
427 //!
428 //! \return Returns a SHA-2 return code.
429 //! - \ref SHA2_SUCCESS
430 //! - \ref SHA2_INVALID_ALGORITHM
431 //!
432 //
433 //*****************************************************************************
434 extern uint32_t SHA2ComputeHash(const uint8_t *message, uint8_t *resultDigest, uint32_t totalMsgLength, uint32_t hashAlgorithm);
435
436 //*****************************************************************************
437 //
438 //! \brief Configure the crypto DMA for a particular operation.
439 //!
440 //! \param algorithm
441 //! Configures the crypto DMA for a particular operation.
442 //! It also powers on the respective part of the system.
443 //! \ref SHA2_ALGSEL_TAG may be combined with another flag. All other
444 //! flags are mutually exclusive.
445 //! - 0 : Reset the module and turn off all sub-modules.
446 //! - \ref SHA2_ALGSEL_SHA256 Configure for a SHA224 or SHA256 operation.
447 //! - \ref SHA2_ALGSEL_SHA512 Configure for a SHA384 or SHA512 operation.
448 //! - \ref SHA2_ALGSEL_TAG Read out hash via DMA rather than the slave interface
449 //!
450 //! \return None
451 //
452 //*****************************************************************************
SHA2SelectAlgorithm(uint32_t algorithm)453 __STATIC_INLINE void SHA2SelectAlgorithm(uint32_t algorithm)
454 {
455 ASSERT((algorithm == SHA2_ALGSEL_SHA256) ||
456 (algorithm == SHA2_ALGSEL_SHA512) ||
457 (algorithm == SHA2_ALGSEL_SHA256 | SHA2_ALGSEL_TAG) ||
458 (algorithm == SHA2_ALGSEL_SHA512 | SHA2_ALGSEL_TAG));
459
460 HWREG(CRYPTO_BASE + CRYPTO_O_ALGSEL) = algorithm;
461 }
462
463
464
465 //*****************************************************************************
466 //
467 //! \brief Specify the total length of the message.
468 //!
469 //! Despite specifying it here, the crypto DMA must still be
470 //! set up with the correct data length.
471 //!
472 //! Call this function only when setting up the final hash operation to
473 //! enable finalization.
474 //!
475 //! \param length Total message length in bits.
476 //!
477 //! \return None
478 //!
479 //! \sa SHA2StartDMAOperation()
480 //
481 //*****************************************************************************
SHA2SetMessageLength(uint32_t length)482 __STATIC_INLINE void SHA2SetMessageLength(uint32_t length)
483 {
484 HWREG(CRYPTO_BASE + CRYPTO_O_HASHINLENL) = length;
485 // CRYPTO_O_HASHINLENH is automatically set to 0. No need for the extra write.
486 }
487
488 //*****************************************************************************
489 //
490 //! \brief Load an intermediate digest.
491 //!
492 //! \param [in] digestLength
493 //! Length of the digest in bytes. Must be one of:
494 //! - \ref SHA2_SHA224_DIGEST_LENGTH_BYTES
495 //! - \ref SHA2_SHA256_DIGEST_LENGTH_BYTES
496 //! - \ref SHA2_SHA384_DIGEST_LENGTH_BYTES
497 //! - \ref SHA2_SHA512_DIGEST_LENGTH_BYTES
498 //!
499 //! \param [in] digest
500 //! Pointer to an intermediate digest. Must be 32-bit aligned.
501 //!
502 //
503 //*****************************************************************************
SHA2SetDigest(uint32_t * digest,uint8_t digestLength)504 __STATIC_INLINE void SHA2SetDigest(uint32_t *digest, uint8_t digestLength)
505 {
506 // Check the arguments.
507 ASSERT(!(digest == NULL) && !((uint32_t)digest & 0x03));
508 ASSERT((digestLength == SHA2_SHA224_DIGEST_LENGTH_BYTES) ||
509 (digestLength == SHA2_SHA256_DIGEST_LENGTH_BYTES) ||
510 (digestLength == SHA2_SHA384_DIGEST_LENGTH_BYTES) ||
511 (digestLength == SHA2_SHA512_DIGEST_LENGTH_BYTES));
512
513 // Write digest
514 uint32_t i = 0;
515 for (i = 0; i < (digestLength / sizeof(uint32_t)); i++) {
516 HWREG(CRYPTO_BASE + CRYPTO_O_HASHDIGESTA + (i * sizeof(uint32_t))) = digest[i];
517 }
518
519 }
520
521 //*****************************************************************************
522 //
523 //! \brief Read the intermediate or final digest.
524 //!
525 //! \param [in] digestLength Length of the digest in bytes. Must be one of:
526 //! - ref SHA2_SHA224_DIGEST_LENGTH_BYTES
527 //! - ref SHA2_SHA256_DIGEST_LENGTH_BYTES
528 //! - ref SHA2_SHA384_DIGEST_LENGTH_BYTES
529 //! - ref SHA2_SHA512_DIGEST_LENGTH_BYTES
530 //!
531 //! \param [out] digest
532 //! Pointer to an intermediate digest. Must be 32-bit aligned.
533 //!
534 //! \return Returns a status code.
535 //! - \ref SHA2_OLD_DIGEST_NOT_READ
536 //! - \ref SHA2_SUCCESS
537 //
538 //*****************************************************************************
SHA2GetDigest(uint32_t * digest,uint8_t digestLength)539 __STATIC_INLINE uint32_t SHA2GetDigest(uint32_t *digest, uint8_t digestLength)
540 {
541 // Check the arguments.
542 ASSERT(!(digest == NULL) && !((uint32_t)digest & 0x03));
543 ASSERT((digestLength == SHA2_SHA224_DIGEST_LENGTH_BYTES) ||
544 (digestLength == SHA2_SHA256_DIGEST_LENGTH_BYTES) ||
545 (digestLength == SHA2_SHA384_DIGEST_LENGTH_BYTES) ||
546 (digestLength == SHA2_SHA512_DIGEST_LENGTH_BYTES));
547
548 if (HWREG(CRYPTO_BASE + CRYPTO_O_HASHIOBUFCTRL) & CRYPTO_HASHIOBUFCTRL_OUTPUT_FULL_M) {
549 return SHA2_OLD_DIGEST_NOT_READ;
550 }
551 else {
552 // Read digest
553 uint32_t i = 0;
554 for (i = 0; i < (digestLength / sizeof(uint32_t)); i++) {
555 digest[i] = HWREG(CRYPTO_BASE + CRYPTO_O_HASHDIGESTA + (i * sizeof(uint32_t)));
556 }
557 return SHA2_SUCCESS;
558 }
559 }
560
561 //*****************************************************************************
562 //
563 //! \brief Confirm digest was read.
564 //
565 //*****************************************************************************
SHA2ClearDigestAvailableFlag(void)566 __STATIC_INLINE void SHA2ClearDigestAvailableFlag(void)
567 {
568 HWREG(CRYPTO_BASE + CRYPTO_O_HASHIOBUFCTRL) = HWREG(CRYPTO_BASE + CRYPTO_O_HASHIOBUFCTRL);
569 }
570
571 //*****************************************************************************
572 //
573 //! \brief Enable individual crypto interrupt sources.
574 //!
575 //! This function enables the indicated crypto interrupt sources. Only the
576 //! sources that are enabled can be reflected to the processor interrupt.
577 //! Disabled sources have no effect on the processor.
578 //!
579 //! \param intFlags is the bitwise OR of the interrupt sources to be enabled.
580 //! - \ref SHA2_DMA_IN_DONE
581 //! - \ref SHA2_RESULT_RDY
582 //!
583 //! \return None
584 //
585 //*****************************************************************************
SHA2IntEnable(uint32_t intFlags)586 __STATIC_INLINE void SHA2IntEnable(uint32_t intFlags)
587 {
588 // Check the arguments.
589 ASSERT((intFlags & SHA2_DMA_IN_DONE) ||
590 (intFlags & SHA2_RESULT_RDY));
591
592 // Using level interrupt.
593 HWREG(CRYPTO_BASE + CRYPTO_O_IRQTYPE) = CRYPTO_IRQTYPE_LEVEL_M;
594
595 // Enable the specified interrupts.
596 HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) |= intFlags;
597 }
598
599 //*****************************************************************************
600 //
601 //! \brief Disable individual crypto interrupt sources.
602 //!
603 //! This function disables the indicated crypto interrupt sources. Only the
604 //! sources that are enabled can be reflected to the processor interrupt.
605 //! Disabled sources have no effect on the processor.
606 //!
607 //! \param intFlags is the bitwise OR of the interrupt sources to be enabled.
608 //! - \ref SHA2_DMA_IN_DONE
609 //! - \ref SHA2_RESULT_RDY
610 //!
611 //! \return None
612 //
613 //*****************************************************************************
SHA2IntDisable(uint32_t intFlags)614 __STATIC_INLINE void SHA2IntDisable(uint32_t intFlags)
615 {
616 // Check the arguments.
617 ASSERT((intFlags & SHA2_DMA_IN_DONE) ||
618 (intFlags & SHA2_RESULT_RDY));
619
620 // Disable the specified interrupts.
621 HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN) &= ~intFlags;
622 }
623
624 //*****************************************************************************
625 //
626 //! \brief Get the current masked interrupt status.
627 //!
628 //! This function returns the masked interrupt status of the crypto module.
629 //!
630 //! \return Returns the status of the masked lines when enabled:
631 //! - \ref SHA2_DMA_IN_DONE
632 //! - \ref SHA2_RESULT_RDY
633 //
634 //*****************************************************************************
SHA2IntStatusMasked(void)635 __STATIC_INLINE uint32_t SHA2IntStatusMasked(void)
636 {
637 uint32_t mask;
638
639 // Return the masked interrupt status
640 mask = HWREG(CRYPTO_BASE + CRYPTO_O_IRQEN);
641 return(mask & HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT));
642 }
643
644 //*****************************************************************************
645 //
646 //! \brief Get the current raw interrupt status.
647 //!
648 //! This function returns the raw interrupt status of the crypto module.
649 //! It returns both the status of the lines routed to the NVIC as well as the
650 //! error flags.
651 //!
652 //! \return Returns the raw interrupt status:
653 //! - \ref SHA2_DMA_IN_DONE
654 //! - \ref SHA2_RESULT_RDY
655 //! - \ref SHA2_DMA_BUS_ERR
656 //
657 //*****************************************************************************
SHA2IntStatusRaw(void)658 __STATIC_INLINE uint32_t SHA2IntStatusRaw(void)
659 {
660 // Return either the raw interrupt status
661 return(HWREG(CRYPTO_BASE + CRYPTO_O_IRQSTAT));
662 }
663
664 //*****************************************************************************
665 //
666 //! \brief Clear crypto interrupt sources.
667 //!
668 //! The specified crypto interrupt sources are cleared, so that they no longer
669 //! assert. This function must be called in the interrupt handler to keep the
670 //! interrupt from being recognized again immediately upon exit.
671 //!
672 //! \note Due to write buffers and synchronizers in the system it may take several
673 //! clock cycles from a register write clearing an event in the module until the
674 //! event is actually cleared in the NVIC of the system CPU. It is recommended to
675 //! clear the event source early in the interrupt service routine (ISR) to allow
676 //! the event clear to propagate to the NVIC before returning from the ISR.
677 //!
678 //! \param intFlags is a bit mask of the interrupt sources to be cleared.
679 //! - \ref SHA2_DMA_IN_DONE
680 //! - \ref SHA2_RESULT_RDY
681 //!
682 //! \return None
683 //
684 //*****************************************************************************
SHA2IntClear(uint32_t intFlags)685 __STATIC_INLINE void SHA2IntClear(uint32_t intFlags)
686 {
687 // Check the arguments.
688 ASSERT((intFlags & SHA2_DMA_IN_DONE) ||
689 (intFlags & SHA2_RESULT_RDY));
690
691 // Clear the requested interrupt sources,
692 HWREG(CRYPTO_BASE + CRYPTO_O_IRQCLR) = intFlags;
693 }
694
695 //*****************************************************************************
696 //
697 //! \brief Register an interrupt handler for a crypto interrupt in the dynamic interrupt table.
698 //!
699 //! \note Only use this function if you want to use the dynamic vector table (in SRAM)!
700 //!
701 //! This function registers a function as the interrupt handler for a specific
702 //! interrupt and enables the corresponding interrupt in the interrupt controller.
703 //!
704 //! Specific crypto interrupts must be enabled via \ref SHA2IntEnable(). It is the
705 //! interrupt handler's responsibility to clear the interrupt source.
706 //!
707 //! \param handlerFxn is a pointer to the function to be called when the
708 //! crypto interrupt occurs.
709 //!
710 //! \return None
711 //!
712 //! \sa \ref IntRegister() for important information about registering interrupt
713 //! handlers.
714 //
715 //*****************************************************************************
SHA2IntRegister(void (* handlerFxn)(void))716 __STATIC_INLINE void SHA2IntRegister(void (*handlerFxn)(void))
717 {
718 // Register the interrupt handler.
719 IntRegister(INT_CRYPTO_RESULT_AVAIL_IRQ, handlerFxn);
720
721 // Enable the crypto interrupt.
722 IntEnable(INT_CRYPTO_RESULT_AVAIL_IRQ);
723 }
724
725 //*****************************************************************************
726 //
727 //! \brief Unregister an interrupt handler for a crypto interrupt in the dynamic interrupt table.
728 //!
729 //! This function does the actual unregistering of the interrupt handler. It
730 //! clears the handler called when a crypto interrupt occurs. This
731 //! function also masks off the interrupt in the interrupt controller so that
732 //! the interrupt handler no longer is called.
733 //!
734 //! \return None
735 //!
736 //! \sa \ref IntRegister() for important information about registering interrupt
737 //! handlers.
738 //
739 //*****************************************************************************
SHA2IntUnregister(void)740 __STATIC_INLINE void SHA2IntUnregister(void)
741 {
742 // Disable the interrupt.
743 IntDisable(INT_CRYPTO_RESULT_AVAIL_IRQ);
744
745 // Unregister the interrupt handler.
746 IntUnregister(INT_CRYPTO_RESULT_AVAIL_IRQ);
747 }
748
749 //*****************************************************************************
750 //
751 // Support for DriverLib in ROM:
752 // Redirect to implementation in ROM when available.
753 //
754 //*****************************************************************************
755 #if !defined(DRIVERLIB_NOROM) && !defined(DOXYGEN)
756 #include "../driverlib/rom.h"
757 #ifdef ROM_SHA2StartDMAOperation
758 #undef SHA2StartDMAOperation
759 #define SHA2StartDMAOperation ROM_SHA2StartDMAOperation
760 #endif
761 #ifdef ROM_SHA2WaitForIRQFlags
762 #undef SHA2WaitForIRQFlags
763 #define SHA2WaitForIRQFlags ROM_SHA2WaitForIRQFlags
764 #endif
765 #ifdef ROM_SHA2ComputeInitialHash
766 #undef SHA2ComputeInitialHash
767 #define SHA2ComputeInitialHash ROM_SHA2ComputeInitialHash
768 #endif
769 #ifdef ROM_SHA2ComputeIntermediateHash
770 #undef SHA2ComputeIntermediateHash
771 #define SHA2ComputeIntermediateHash ROM_SHA2ComputeIntermediateHash
772 #endif
773 #ifdef ROM_SHA2ComputeFinalHash
774 #undef SHA2ComputeFinalHash
775 #define SHA2ComputeFinalHash ROM_SHA2ComputeFinalHash
776 #endif
777 #ifdef ROM_SHA2ComputeHash
778 #undef SHA2ComputeHash
779 #define SHA2ComputeHash ROM_SHA2ComputeHash
780 #endif
781 #endif
782
783 //*****************************************************************************
784 //
785 // Mark the end of the C bindings section for C++ compilers.
786 //
787 //*****************************************************************************
788 #ifdef __cplusplus
789 }
790 #endif
791
792 #endif // __SHA2_H__
793
794 //*****************************************************************************
795 //
796 //! Close the Doxygen group.
797 //! @}
798 //! @}
799 //
800 //*****************************************************************************
801