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