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