| < draft-eastlake-sha2b-03.txt | draft-eastlake-sha2b-04.txt > | |||
|---|---|---|---|---|
| Network Working Group Donald Eastlake 3rd | Network Working Group Donald Eastlake 3rd | |||
| INTERNET-DRAFT Stellar Switches | INTERNET-DRAFT Stellar Switches | |||
| Obsoletes: 4634 Tony Hansen | Obsoletes: 4634 Tony Hansen | |||
| Updates: 3174 AT&T Labs | Updates: 3174 AT&T Labs | |||
| Intended Status: Informational | Intended Status: Informational | |||
| Expires: January 29, 2011 July 30, 2010 | Expires: March 21, 2011 September 22, 2010 | |||
| US Secure Hash Algorithms | US Secure Hash Algorithms | |||
| (SHA and SHA based HMAC and HKDF) | (SHA and SHA based HMAC and HKDF) | |||
| <draft-eastlake-sha2b-03.txt> | <draft-eastlake-sha2b-04.txt> | |||
| Abstract | Abstract | |||
| This document is an update of RFC 4634 to fix errata and to add code | This document replaces RFC 4634, fixing errata and adding code for an | |||
| for an HMAC-based extract-and-expand key derivation function. | HMAC-based extract-and-expand key derivation function. | |||
| The United States of America has adopted a suite of secure hash | The United States of America has adopted a suite of secure hash | |||
| algorithms (SHAs), including four beyond SHA-1, as part of a Federal | algorithms (SHAs), including four beyond SHA-1, as part of a Federal | |||
| Information Processing Standard (FIPS), specifically SHA-224, | Information Processing Standard (FIPS), specifically SHA-224, | |||
| SHA-256, SHA-384, and SHA-512. The purpose of this document is to | SHA-256, SHA-384, and SHA-512. This document makes open source code | |||
| make open source code performing the SHA hash functions conveniently | performing the SHA hash functions conveniently available to the | |||
| available to the Internet community. The sample code supports input | Internet community. The sample code supports input strings of | |||
| strings of arbitrary bit length. Much of the text herein was adapted | arbitrary bit length. Much of the text herein was adapted by the | |||
| by the authors from FIPS 180-2. | authors from FIPS 180-2. | |||
| As with RFC 4634, code to perform SHA based HMACs is included and, | As with RFC 4634, code to perform SHA based HMACs is included and, | |||
| new in this version, code for HKDF (RFC 5869) is included. | new in this version, code for HKDF (RFC 5869) is included. | |||
| Status of This Memo | Status of This Memo | |||
| This Internet-Draft is submitted to IETF in full conformance with the | This Internet-Draft is submitted to IETF in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| Distribution of this document is unlimited. Comments should be sent | Distribution of this document is unlimited. Comments should be sent | |||
| skipping to change at page 2, line 39 ¶ | skipping to change at page 2, line 39 ¶ | |||
| 7.2 HKDF..................................................17 | 7.2 HKDF..................................................17 | |||
| 8. C Code for SHAs, HMAC, and HKDF........................18 | 8. C Code for SHAs, HMAC, and HKDF........................18 | |||
| 8.1 The Header Files......................................21 | 8.1 The Header Files......................................21 | |||
| 8.1.1 The .h file.........................................21 | 8.1.1 The .h file.........................................21 | |||
| 8.1.2 sha-private.h.......................................29 | 8.1.2 sha-private.h.......................................29 | |||
| 8.2 The SHA Code..........................................29 | 8.2 The SHA Code..........................................29 | |||
| 8.2.1 sha1.c..............................................29 | 8.2.1 sha1.c..............................................29 | |||
| 8.2.2 sha224-256.c........................................38 | 8.2.2 sha224-256.c........................................38 | |||
| 8.2.3 sha384-512.c........................................50 | 8.2.3 sha384-512.c........................................50 | |||
| 8.2.4 usha.c..............................................71 | 8.2.4 usha.c..............................................70 | |||
| 8.3 The HMAC Code.........................................77 | 8.3 The HMAC Code.........................................76 | |||
| 8.4 The HKDF Code.........................................82 | 8.4 The HKDF Code.........................................81 | |||
| 8.5 The Test Driver.......................................89 | 8.5 The Test Driver.......................................88 | |||
| 9. IANA Considerations...................................120 | ||||
| 10. Security Considerations..............................120 | ||||
| 11. Acknowledgements.....................................120 | ||||
| 12. References...........................................121 | 9. IANA Considerations...................................119 | |||
| 12.1 Normative References................................121 | 10. Security Considerations..............................119 | |||
| 12.2 Informative References..............................121 | 11. Acknowledgements.....................................119 | |||
| 12. References...........................................120 | ||||
| 12.1 Normative References................................120 | ||||
| 12.2 Informative References..............................120 | ||||
| Appendix: Changes from RFC 4634..........................123 | Appendix: Changes from RFC 4634..........................121 | |||
| Appendix Z: Edit History.................................124 | Appendix Z: Edit History.................................122 | |||
| Z.1 Changes from -00 to -01..............................124 | Z.1 Changes from -00 to -01..............................122 | |||
| Z.2 Changes from -01 to -02..............................124 | Z.2 Changes from -01 to -02..............................122 | |||
| Z.3 Changes from -02 to -03..............................124 | Z.3 Changes from -02 to -03..............................122 | |||
| Z.4 Changes from -03 to -04..............................122 | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| 1. Overview of Contents | 1. Overview of Contents | |||
| This document obsoletes [RFC4634]; and the changes from that RFC are | This document obsoletes [RFC4634]; and the changes from that RFC are | |||
| summarized in the Appendix. | summarized in the Appendix. | |||
| This document includes specifications for the United States of | This document includes specifications for the United States of | |||
| America (USA) Federal Information Processing Standard (FIPS) Secure | America (USA) Federal Information Processing Standard (FIPS) Secure | |||
| skipping to change at page 22, line 39 ¶ | skipping to change at page 22, line 39 ¶ | |||
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN | |||
| ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
| POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
| */ | */ | |||
| #ifndef _SHA_H_ | #ifndef _SHA_H_ | |||
| #define _SHA_H_ | #define _SHA_H_ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the Secure Hash Algorithms | * This file implements the Secure Hash Algorithms | |||
| * as defined in the National Institute of Standards | * as defined in the U.S. National Institute of Standards | |||
| * and Technology Federal Information Processing Standards | * and Technology Federal Information Processing Standards | |||
| * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2 | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * published on August 1, 2002, and the FIPS PUB 180-2 Change | * and formerly defined in its predecessors, FIPS PUB 180-1 | |||
| * Notice published on February 28, 2004. | * and FIP PUB 180-2. | |||
| * | * | |||
| * A combined document showing all algorithms is available at | * A combined document showing all algorithms is available at | |||
| * http://csrc.nist.gov/publications/fips/ | * http://csrc.nist.gov/publications/fips/ | |||
| * fips180-2/fips180-2withchangenotice.pdf | * fips180-3/fips180-3_final.pdf | |||
| * | * | |||
| * The five hashes are defined in these sizes: | * The five hashes are defined in these sizes: | |||
| * SHA-1 20 byte / 160 bit | * SHA-1 20 byte / 160 bit | |||
| * SHA-224 28 byte / 224 bit | * SHA-224 28 byte / 224 bit | |||
| * SHA-256 32 byte / 256 bit | * SHA-256 32 byte / 256 bit | |||
| * SHA-384 48 byte / 384 bit | * SHA-384 48 byte / 384 bit | |||
| * SHA-512 64 byte / 512 bit | * SHA-512 64 byte / 512 bit | |||
| * | * | |||
| * Compilation Note: | * Compilation Note: | |||
| skipping to change at page 24, line 26 ¶ | skipping to change at page 24, line 26 ¶ | |||
| SHA1, SHA224, SHA256, SHA384, SHA512 | SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| } SHAversion; | } SHAversion; | |||
| /* | /* | |||
| * This structure will hold context information for the SHA-1 | * This structure will hold context information for the SHA-1 | |||
| * hashing operation. | * hashing operation. | |||
| */ | */ | |||
| typedef struct SHA1Context { | typedef struct SHA1Context { | |||
| uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ | uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */ | |||
| uint32_t Length_Low; /* Message length in bits */ | ||||
| uint32_t Length_High; /* Message length in bits */ | uint32_t Length_High; /* Message length in bits */ | |||
| uint32_t Length_Low; /* Message length in bits */ | ||||
| int_least16_t Message_Block_Index; /* Message_Block array index */ | int_least16_t Message_Block_Index; /* Message_Block array index */ | |||
| /* 512-bit message blocks */ | /* 512-bit message blocks */ | |||
| uint8_t Message_Block[SHA1_Message_Block_Size]; | uint8_t Message_Block[SHA1_Message_Block_Size]; | |||
| int Computed; /* Is the digest computed? */ | int Computed; /* Is the hash computed? */ | |||
| int Corrupted; /* Is the digest corrupted? */ | int Corrupted; /* Cumulative corruption code */ | |||
| } SHA1Context; | } SHA1Context; | |||
| /* | /* | |||
| * This structure will hold context information for the SHA-256 | * This structure will hold context information for the SHA-256 | |||
| * hashing operation. | * hashing operation. | |||
| */ | */ | |||
| typedef struct SHA256Context { | typedef struct SHA256Context { | |||
| uint32_t Intermediate_Hash[SHA256HashSize/4]; /* Message Digest */ | uint32_t Intermediate_Hash[SHA256HashSize/4]; /* Message Digest */ | |||
| uint32_t Length_Low; /* Message length in bits */ | ||||
| uint32_t Length_High; /* Message length in bits */ | uint32_t Length_High; /* Message length in bits */ | |||
| uint32_t Length_Low; /* Message length in bits */ | ||||
| int_least16_t Message_Block_Index; /* Message_Block array index */ | int_least16_t Message_Block_Index; /* Message_Block array index */ | |||
| /* 512-bit message blocks */ | /* 512-bit message blocks */ | |||
| uint8_t Message_Block[SHA256_Message_Block_Size]; | uint8_t Message_Block[SHA256_Message_Block_Size]; | |||
| int Computed; /* Is the digest computed? */ | int Computed; /* Is the hash computed? */ | |||
| int Corrupted; /* Is the digest corrupted? */ | int Corrupted; /* Cumulative corruption code */ | |||
| } SHA256Context; | } SHA256Context; | |||
| /* | /* | |||
| * This structure will hold context information for the SHA-512 | * This structure will hold context information for the SHA-512 | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| * hashing operation. | * hashing operation. | |||
| */ | */ | |||
| typedef struct SHA512Context { | typedef struct SHA512Context { | |||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| uint32_t Intermediate_Hash[SHA512HashSize/4]; /* Message Digest */ | uint32_t Intermediate_Hash[SHA512HashSize/4]; /* Message Digest */ | |||
| uint32_t Length[4]; /* Message length in bits */ | uint32_t Length[4]; /* Message length in bits */ | |||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| uint64_t Intermediate_Hash[SHA512HashSize/8]; /* Message Digest */ | uint64_t Intermediate_Hash[SHA512HashSize/8]; /* Message Digest */ | |||
| uint64_t Length_Low, Length_High; /* Message length in bits */ | uint64_t Length_High, Length_Low; /* Message length in bits */ | |||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| int_least16_t Message_Block_Index; /* Message_Block array index */ | int_least16_t Message_Block_Index; /* Message_Block array index */ | |||
| /* 1024-bit message blocks */ | /* 1024-bit message blocks */ | |||
| uint8_t Message_Block[SHA512_Message_Block_Size]; | uint8_t Message_Block[SHA512_Message_Block_Size]; | |||
| int Computed; /* Is the digest computed?*/ | int Computed; /* Is the hash computed?*/ | |||
| int Corrupted; /* Is the digest corrupted? */ | int Corrupted; /* Cumulative corruption code */ | |||
| } SHA512Context; | } SHA512Context; | |||
| /* | /* | |||
| * This structure will hold context information for the SHA-224 | * This structure will hold context information for the SHA-224 | |||
| * hashing operation. It uses the SHA-256 structure for computation. | * hashing operation. It uses the SHA-256 structure for computation. | |||
| */ | */ | |||
| typedef struct SHA256Context SHA224Context; | typedef struct SHA256Context SHA224Context; | |||
| /* | /* | |||
| * This structure will hold context information for the SHA-384 | * This structure will hold context information for the SHA-384 | |||
| skipping to change at page 26, line 12 ¶ | skipping to change at page 26, line 12 ¶ | |||
| typedef struct HMACContext { | typedef struct HMACContext { | |||
| int whichSha; /* which SHA is being used */ | int whichSha; /* which SHA is being used */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| int hashSize; /* hash size of SHA being used */ | int hashSize; /* hash size of SHA being used */ | |||
| int blockSize; /* block size of SHA being used */ | int blockSize; /* block size of SHA being used */ | |||
| USHAContext shaContext; /* SHA context */ | USHAContext shaContext; /* SHA context */ | |||
| unsigned char k_opad[USHA_Max_Message_Block_Size]; | unsigned char k_opad[USHA_Max_Message_Block_Size]; | |||
| /* outer padding - key XORd with opad */ | /* outer padding - key XORd with opad */ | |||
| int Computed; /* Is the digest computed? */ | int Computed; /* Is the MAC computed? */ | |||
| int Corrupted; /* Is the digest corrupted? */ | int Corrupted; /* Cumulative corruption code */ | |||
| } HMACContext; | } HMACContext; | |||
| /* | /* | |||
| * This structure will hold context information for the HKDF | * This structure will hold context information for the HKDF | |||
| * Extract-and-Expand Key Derivation functions. | * Extract-and-Expand Key Derivation functions. | |||
| */ | */ | |||
| typedef struct HKDFContext { | typedef struct HKDFContext { | |||
| int whichSha; /* which SHA is being used */ | int whichSha; /* which SHA is being used */ | |||
| HMACContext hmacContext; | HMACContext hmacContext; | |||
| int hashSize; /* hash size of SHA being used */ | int hashSize; /* hash size of SHA being used */ | |||
| unsigned char prk[USHAMaxHashSize]; | unsigned char prk[USHAMaxHashSize]; | |||
| /* Pseudo Random Key - output of hkdfInput */ | /* Pseudo Random Key - output of hkdfInput */ | |||
| int Computed; /* Is the digest computed? */ | int Computed; /* Is the key material computed? */ | |||
| int Corrupted; /* Is the digest corrupted? */ | int Corrupted; /* Cumulative corruption code */ | |||
| } HKDFContext; | } HKDFContext; | |||
| /* | /* | |||
| * Function Prototypes | * Function Prototypes | |||
| */ | */ | |||
| /* SHA-1 */ | /* SHA-1 */ | |||
| extern int SHA1Reset(SHA1Context *); | extern int SHA1Reset(SHA1Context *); | |||
| extern int SHA1Input(SHA1Context *, const uint8_t *bytes, | extern int SHA1Input(SHA1Context *, const uint8_t *bytes, | |||
| unsigned int bytecount); | unsigned int bytecount); | |||
| skipping to change at page 26, line 54 ¶ | skipping to change at page 27, line 4 ¶ | |||
| extern int SHA224Reset(SHA224Context *); | extern int SHA224Reset(SHA224Context *); | |||
| extern int SHA224Input(SHA224Context *, const uint8_t *bytes, | extern int SHA224Input(SHA224Context *, const uint8_t *bytes, | |||
| unsigned int bytecount); | unsigned int bytecount); | |||
| extern int SHA224FinalBits(SHA224Context *, uint8_t bits, | extern int SHA224FinalBits(SHA224Context *, uint8_t bits, | |||
| unsigned int bit_count); | unsigned int bit_count); | |||
| extern int SHA224Result(SHA224Context *, | extern int SHA224Result(SHA224Context *, | |||
| uint8_t Message_Digest[SHA224HashSize]); | uint8_t Message_Digest[SHA224HashSize]); | |||
| /* SHA-256 */ | /* SHA-256 */ | |||
| extern int SHA256Reset(SHA256Context *); | extern int SHA256Reset(SHA256Context *); | |||
| extern int SHA256Input(SHA256Context *, const uint8_t *bytes, | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| extern int SHA256Input(SHA256Context *, const uint8_t *bytes, | ||||
| unsigned int bytecount); | unsigned int bytecount); | |||
| extern int SHA256FinalBits(SHA256Context *, uint8_t bits, | extern int SHA256FinalBits(SHA256Context *, uint8_t bits, | |||
| unsigned int bit_count); | unsigned int bit_count); | |||
| extern int SHA256Result(SHA256Context *, | extern int SHA256Result(SHA256Context *, | |||
| uint8_t Message_Digest[SHA256HashSize]); | uint8_t Message_Digest[SHA256HashSize]); | |||
| /* SHA-384 */ | /* SHA-384 */ | |||
| extern int SHA384Reset(SHA384Context *); | extern int SHA384Reset(SHA384Context *); | |||
| extern int SHA384Input(SHA384Context *, const uint8_t *bytes, | extern int SHA384Input(SHA384Context *, const uint8_t *bytes, | |||
| unsigned int bytecount); | unsigned int bytecount); | |||
| skipping to change at page 27, line 55 ¶ | skipping to change at page 28, line 5 ¶ | |||
| * for all SHAs. | * for all SHAs. | |||
| * This interface allows a fixed-length text input to be used. | * This interface allows a fixed-length text input to be used. | |||
| */ | */ | |||
| extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */ | extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */ | |||
| const unsigned char *text, /* pointer to data stream */ | const unsigned char *text, /* pointer to data stream */ | |||
| int text_len, /* length of data stream */ | int text_len, /* length of data stream */ | |||
| const unsigned char *key, /* pointer to authentication key */ | const unsigned char *key, /* pointer to authentication key */ | |||
| int key_len, /* length of authentication key */ | int key_len, /* length of authentication key */ | |||
| uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */ | uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */ | |||
| /* | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| /* | ||||
| * HMAC Keyed-Hashing for Message Authentication, RFC 2104, | * HMAC Keyed-Hashing for Message Authentication, RFC 2104, | |||
| * for all SHAs. | * for all SHAs. | |||
| * This interface allows any length of text input to be used. | * This interface allows any length of text input to be used. | |||
| */ | */ | |||
| extern int hmacReset(HMACContext *context, enum SHAversion whichSha, | extern int hmacReset(HMACContext *context, enum SHAversion whichSha, | |||
| const unsigned char *key, int key_len); | const unsigned char *key, int key_len); | |||
| extern int hmacInput(HMACContext *context, const unsigned char *text, | extern int hmacInput(HMACContext *context, const unsigned char *text, | |||
| int text_len); | int text_len); | |||
| extern int hmacFinalBits(HMACContext *context, uint8_t bits, | extern int hmacFinalBits(HMACContext *context, uint8_t bits, | |||
| unsigned int bit_count); | unsigned int bit_count); | |||
| skipping to change at page 29, line 13 ¶ | skipping to change at page 29, line 13 ¶ | |||
| #endif /* _SHA_H_ */ | #endif /* _SHA_H_ */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| 8.1.2 sha-private.h | 8.1.2 sha-private.h | |||
| /************************ sha-private.h ************************/ | /************************ sha-private.h ************************/ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| #ifndef _SHA_PRIVATE__H | #ifndef _SHA_PRIVATE__H | |||
| #define _SHA_PRIVATE__H | #define _SHA_PRIVATE__H | |||
| /* | /* | |||
| * These definitions are defined in FIPS-180-2, section 4.1. | * These definitions are defined in FIPS 180-3, section 4.1. | |||
| * Ch() and Maj() are defined identically in sections 4.1.1, | * Ch() and Maj() are defined identically in sections 4.1.1, | |||
| * 4.1.2 and 4.1.3. | * 4.1.2 and 4.1.3. | |||
| * | * | |||
| * The definitions used in FIPS-180-2 are as follows: | * The definitions used in FIPS 180-3 are as follows: | |||
| */ | */ | |||
| #ifndef USE_MODIFIED_MACROS | #ifndef USE_MODIFIED_MACROS | |||
| #define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | #define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z))) | |||
| #define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | #define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z))) | |||
| #else /* USE_MODIFIED_MACROS */ | #else /* USE_MODIFIED_MACROS */ | |||
| /* | /* | |||
| * The following definitions are equivalent and potentially faster. | * The following definitions are equivalent and potentially faster. | |||
| */ | */ | |||
| skipping to change at page 30, line 13 ¶ | skipping to change at page 30, line 13 ¶ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| /* Copyright (c) 2010 IETF Trust and the persons identified as */ | /* Copyright (c) 2010 IETF Trust and the persons identified as */ | |||
| /* authors of the code. All rights reserved. */ | /* authors of the code. All rights reserved. */ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the Secure Hash Algorithm SHA-1 | * This file implements the Secure Hash Algorithm SHA-1 | |||
| * as defined in the National Institute of Standards | * as defined in the U.S. National Institute of Standards | |||
| * and Technology Federal Information Processing Standards | * and Technology Federal Information Processing Standards | |||
| * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2 | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * published on August 1, 2002, and the FIPS PUB 180-2 Change | * and formerly defined in its predecessors, FIPS PUB 180-1 | |||
| * Notice published on February 28, 2004. | * and FIP PUB 180-2. | |||
| * | * | |||
| * A combined document showing all algorithms is available at | * A combined document showing all algorithms is available at | |||
| * http://csrc.nist.gov/publications/fips/ | * http://csrc.nist.gov/publications/fips/ | |||
| * fips180-2/fips180-2withchangenotice.pdf | * fips180-3/fips180-3_final.pdf | |||
| * | * | |||
| * The SHA-1 algorithm produces a 160-bit message digest for a | * The SHA-1 algorithm produces a 160-bit message digest for a | |||
| * given data stream. It should take about 2**n steps to find a | * given data stream. It should take about 2**n steps to find a | |||
| * message with the same digest as a given message and | * message with the same digest as a given message and | |||
| * 2**(n/2) to find any two messages with the same digest, | * 2**(n/2) to find any two messages with the same digest, | |||
| * when n is the digest size in bits. Therefore, this | * when n is the digest size in bits. Therefore, this | |||
| * algorithm can serve as a means of providing a | * algorithm can serve as a means of providing a | |||
| * "fingerprint" for a message. | * "fingerprint" for a message. | |||
| * | * | |||
| * Portability Issues: | * Portability Issues: | |||
| skipping to change at page 31, line 15 ¶ | skipping to change at page 31, line 15 ¶ | |||
| * Add "length" to the length. | * Add "length" to the length. | |||
| * Set Corrupted when overflow has occurred. | * Set Corrupted when overflow has occurred. | |||
| */ | */ | |||
| static uint32_t addTemp; | static uint32_t addTemp; | |||
| #define SHA1AddLength(context, length) \ | #define SHA1AddLength(context, length) \ | |||
| (addTemp = (context)->Length_Low, \ | (addTemp = (context)->Length_Low, \ | |||
| (context)->Corrupted = \ | (context)->Corrupted = \ | |||
| (((context)->Length_Low += (length)) < addTemp) && \ | (((context)->Length_Low += (length)) < addTemp) && \ | |||
| (++(context)->Length_High == 0) ? shaInputTooLong \ | (++(context)->Length_High == 0) ? shaInputTooLong \ | |||
| : shaSuccess ) | : (context)->Corrupted ) | |||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static void SHA1ProcessMessageBlock(SHA1Context *context); | ||||
| static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte); | static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte); | |||
| static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte); | static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte); | |||
| static void SHA1ProcessMessageBlock(SHA1Context *context); | ||||
| /* | /* | |||
| * SHA1Reset | * SHA1Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the SHA1Context in preparation | * This function will initialize the SHA1Context in preparation | |||
| * for computing a new SHA1 message digest. | * for computing a new SHA1 message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA1Reset(SHA1Context *context) | int SHA1Reset(SHA1Context *context) | |||
| { | { | |||
| if (!context) | if (!context) return shaNull; | |||
| return shaNull; | ||||
| context->Length_Low = 0; | context->Length_High = context->Length_Low = 0; | |||
| context->Length_High = 0; | context->Message_Block_Index = 0; | |||
| context->Message_Block_Index = 0; | ||||
| /* Initial Hash Values: FIPS-180-2 section 5.3.1 */ | /* Initial Hash Values: FIPS 180-3 section 5.3.1 */ | |||
| context->Intermediate_Hash[0] = 0x67452301; | context->Intermediate_Hash[0] = 0x67452301; | |||
| context->Intermediate_Hash[1] = 0xEFCDAB89; | context->Intermediate_Hash[1] = 0xEFCDAB89; | |||
| context->Intermediate_Hash[2] = 0x98BADCFE; | context->Intermediate_Hash[2] = 0x98BADCFE; | |||
| context->Intermediate_Hash[3] = 0x10325476; | context->Intermediate_Hash[3] = 0x10325476; | |||
| context->Intermediate_Hash[4] = 0xC3D2E1F0; | context->Intermediate_Hash[4] = 0xC3D2E1F0; | |||
| context->Computed = 0; | context->Computed = 0; | |||
| context->Corrupted = 0; | context->Corrupted = shaSuccess; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return shaSuccess; | return shaSuccess; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * SHA1Input | * SHA1Input | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA1Input(SHA1Context *context, | int SHA1Input(SHA1Context *context, | |||
| const uint8_t *message_array, unsigned length) | const uint8_t *message_array, unsigned length) | |||
| { | { | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (!message_array) return shaNull; | ||||
| if (!context || !message_array) | ||||
| return shaNull; | ||||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| while (length-- && !context->Corrupted) { | while (length--) { | |||
| context->Message_Block[context->Message_Block_Index++] = | context->Message_Block[context->Message_Block_Index++] = | |||
| (*message_array & 0xFF); | *message_array; | |||
| if ((SHA1AddLength(context, 8) == shaSuccess) && | if ((SHA1AddLength(context, 8) == shaSuccess) && | |||
| (context->Message_Block_Index == SHA1_Message_Block_Size)) | (context->Message_Block_Index == SHA1_Message_Block_Size)) | |||
| SHA1ProcessMessageBlock(context); | SHA1ProcessMessageBlock(context); | |||
| message_array++; | message_array++; | |||
| } | } | |||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * SHA1FinalBits | * SHA1FinalBits | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will add in any final bits of the message. | * This function will add in any final bits of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA1FinalBits(SHA1Context *context, uint8_t message_bits, | int SHA1FinalBits(SHA1Context *context, uint8_t message_bits, | |||
| unsigned int length) | unsigned int length) | |||
| { | { | |||
| uint8_t masks[8] = { | static uint8_t masks[8] = { | |||
| /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | |||
| /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | |||
| /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | |||
| /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | |||
| }; | }; | |||
| uint8_t markbit[8] = { | static uint8_t markbit[8] = { | |||
| /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | |||
| /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | |||
| /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | |||
| /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | |||
| }; | }; | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (!context) | ||||
| return shaNull; | ||||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| if (length >= 8) return context->Corrupted = shaBadParam; | ||||
| if ((length >= 8) || (length == 0)) | ||||
| return context->Corrupted = shaBadParam; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| SHA1AddLength(context, length); | SHA1AddLength(context, length); | |||
| SHA1Finalize(context, | SHA1Finalize(context, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| (uint8_t) ((message_bits & masks[length]) | markbit[length])); | (uint8_t) ((message_bits & masks[length]) | markbit[length])); | |||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| * SHA1Result | * SHA1Result | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the 160-bit message digest | * This function will return the 160-bit message digest | |||
| * into the Message_Digest array provided by the caller. | * into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 19. | * the last octet of hash in the element with index 19. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA-1 hash. | * The context to use to calculate the SHA-1 hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA1Result(SHA1Context *context, | int SHA1Result(SHA1Context *context, | |||
| uint8_t Message_Digest[SHA1HashSize]) | uint8_t Message_Digest[SHA1HashSize]) | |||
| { | { | |||
| int i; | int i; | |||
| if (!context || !Message_Digest) | if (!context) return shaNull; | |||
| return shaNull; | if (!Message_Digest) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| if (!context->Computed) | if (!context->Computed) | |||
| SHA1Finalize(context, 0x80); | SHA1Finalize(context, 0x80); | |||
| for (i = 0; i < SHA1HashSize; ++i) | for (i = 0; i < SHA1HashSize; ++i) | |||
| Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2] | Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2] | |||
| >> 8 * ( 3 - ( i & 0x03 ) )); | >> (8 * ( 3 - ( i & 0x03 ) ))); | |||
| return shaSuccess; | return shaSuccess; | |||
| } | } | |||
| /* | /* | |||
| * SHA1Finalize | ||||
| * | ||||
| * Description: | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * This helper function finishes off the digest calculations. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The SHA context to update | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the digest before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * sha Error Code. | ||||
| * | ||||
| */ | ||||
| static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) | ||||
| { | ||||
| int i; | ||||
| SHA1PadMessage(context, Pad_Byte); | ||||
| /* message may be sensitive, clear it out */ | ||||
| for (i = 0; i < SHA1_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| context->Length_Low = 0; /* and clear length */ | ||||
| context->Length_High = 0; | ||||
| context->Computed = 1; | ||||
| } | ||||
| /* | ||||
| * SHA1PadMessage | ||||
| * | ||||
| * Description: | ||||
| * According to the standard, the message must be padded to the next | ||||
| * even multiple of 512 bits. The first padding bit must be a '1'. | ||||
| * The last 64 bits represent the length of the original message. | ||||
| * All bits in between should be 0. This helper function will pad | ||||
| * the message according to those rules by filling the Message_Block | ||||
| * array accordingly. When it returns, it can be assumed that the | ||||
| * message digest has been computed. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The context to pad | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the digest before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * Nothing. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | ||||
| static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) | ||||
| { | ||||
| /* | ||||
| * Check to see if the current message block is too small to hold | ||||
| * the initial padding bits and length. If so, we will pad the | ||||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA1_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| SHA1ProcessMessageBlock(context); | ||||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8)) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| /* | ||||
| * Store the message length as the last 8 octets | ||||
| */ | ||||
| context->Message_Block[56] = (uint8_t) (context->Length_High >> 24); | ||||
| context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); | ||||
| context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); | ||||
| context->Message_Block[59] = (uint8_t) (context->Length_High); | ||||
| context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); | ||||
| context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); | ||||
| context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); | ||||
| context->Message_Block[63] = (uint8_t) (context->Length_Low); | ||||
| SHA1ProcessMessageBlock(context); | ||||
| } | ||||
| /* | ||||
| * SHA1ProcessMessageBlock | * SHA1ProcessMessageBlock | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will process the next 512 bits of the | * This helper function will process the next 512 bits of the | |||
| * message stored in the Message_Block array. | * message stored in the Message_Block array. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Comments: | * Comments: | |||
| * Many of the variable names in this code, especially the | * Many of the variable names in this code, especially the | |||
| * single character names, were used because those were the | * single character names, were used because those were the | |||
| * names used in the publication. | * names used in the Secure Hash Standard. | |||
| */ | */ | |||
| static void SHA1ProcessMessageBlock(SHA1Context *context) | static void SHA1ProcessMessageBlock(SHA1Context *context) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { | { | |||
| /* Constants defined in FIPS-180-2, section 4.2.1 */ | /* Constants defined in FIPS 180-3, section 4.2.1 */ | |||
| const uint32_t K[4] = { | const uint32_t K[4] = { | |||
| 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 | 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6 | |||
| }; | }; | |||
| int t; /* Loop counter */ | int t; /* Loop counter */ | |||
| uint32_t temp; /* Temporary word value */ | uint32_t temp; /* Temporary word value */ | |||
| uint32_t W[80]; /* Word sequence */ | uint32_t W[80]; /* Word sequence */ | |||
| uint32_t A, B, C, D, E; /* Word buffers */ | uint32_t A, B, C, D, E; /* Word buffers */ | |||
| /* | /* | |||
| * Initialize the first 16 words in the array W | * Initialize the first 16 words in the array W | |||
| skipping to change at page 38, line 4 ¶ | skipping to change at page 35, line 50 ¶ | |||
| B = A; | B = A; | |||
| A = temp; | A = temp; | |||
| } | } | |||
| for (t = 20; t < 40; t++) { | for (t = 20; t < 40; t++) { | |||
| temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1]; | temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1]; | |||
| E = D; | E = D; | |||
| D = C; | D = C; | |||
| C = SHA1_ROTL(30,B); | C = SHA1_ROTL(30,B); | |||
| B = A; | B = A; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| A = temp; | A = temp; | |||
| } | } | |||
| for (t = 40; t < 60; t++) { | for (t = 40; t < 60; t++) { | |||
| temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2]; | temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2]; | |||
| E = D; | E = D; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| D = C; | D = C; | |||
| C = SHA1_ROTL(30,B); | C = SHA1_ROTL(30,B); | |||
| B = A; | B = A; | |||
| A = temp; | A = temp; | |||
| } | } | |||
| for (t = 60; t < 80; t++) { | for (t = 60; t < 80; t++) { | |||
| temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3]; | temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3]; | |||
| E = D; | E = D; | |||
| D = C; | D = C; | |||
| skipping to change at page 38, line 37 ¶ | skipping to change at page 36, line 31 ¶ | |||
| context->Intermediate_Hash[0] += A; | context->Intermediate_Hash[0] += A; | |||
| context->Intermediate_Hash[1] += B; | context->Intermediate_Hash[1] += B; | |||
| context->Intermediate_Hash[2] += C; | context->Intermediate_Hash[2] += C; | |||
| context->Intermediate_Hash[3] += D; | context->Intermediate_Hash[3] += D; | |||
| context->Intermediate_Hash[4] += E; | context->Intermediate_Hash[4] += E; | |||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| } | } | |||
| /* | ||||
| * SHA1Finalize | ||||
| * | ||||
| * Description: | ||||
| * This helper function finishes off the digest calculations. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The SHA context to update | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the message block before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * sha Error Code. | ||||
| * | ||||
| */ | ||||
| static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte) | ||||
| { | ||||
| int i; | ||||
| SHA1PadMessage(context, Pad_Byte); | ||||
| /* message may be sensitive, clear it out */ | ||||
| for (i = 0; i < SHA1_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Length_High = 0; /* and clear length */ | ||||
| context->Length_Low = 0; | ||||
| context->Computed = 1; | ||||
| } | ||||
| /* | ||||
| * SHA1PadMessage | ||||
| * | ||||
| * Description: | ||||
| * According to the standard, the message must be padded to the next | ||||
| * even multiple of 512 bits. The first padding bit must be a '1'. | ||||
| * The last 64 bits represent the length of the original message. | ||||
| * All bits in between should be 0. This helper function will pad | ||||
| * the message according to those rules by filling the Message_Block | ||||
| * array accordingly. When it returns, it can be assumed that the | ||||
| * message digest has been computed. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The context to pad | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the message block before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * Nothing. | ||||
| */ | ||||
| static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) | ||||
| { | ||||
| /* | ||||
| * Check to see if the current message block is too small to hold | ||||
| * the initial padding bits and length. If so, we will pad the | ||||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA1_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| SHA1ProcessMessageBlock(context); | ||||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8)) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| /* | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Store the message length as the last 8 octets | ||||
| */ | ||||
| context->Message_Block[56] = (uint8_t) (context->Length_High >> 24); | ||||
| context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); | ||||
| context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); | ||||
| context->Message_Block[59] = (uint8_t) (context->Length_High); | ||||
| context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); | ||||
| context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); | ||||
| context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); | ||||
| context->Message_Block[63] = (uint8_t) (context->Length_Low); | ||||
| SHA1ProcessMessageBlock(context); | ||||
| } | ||||
| 8.2.2 sha224-256.c | 8.2.2 sha224-256.c | |||
| /************************* sha224-256.c ************************/ | /************************* sha224-256.c ************************/ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| /* Copyright (c) 2010 IETF Trust and the persons identified as */ | /* Copyright (c) 2010 IETF Trust and the persons identified as */ | |||
| /* authors of the code. All rights reserved. */ | /* authors of the code. All rights reserved. */ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the Secure Hash Algorithms SHA-224 and | * This file implements the Secure Hash Algorithms SHA-224 and | |||
| * SHA-256 as defined in the National Institute of Standards | * SHA-256 as defined in the U.S. National Institute of Standards | |||
| * and Technology Federal Information Processing Standards | * and Technology Federal Information Processing Standards | |||
| * Publication (FIPS PUB) 180-2 published on August 1, 2002, and | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * the FIPS PUB 180-2 Change Notice published on February 28, 2004. | * and formerly defined in its predecessors, FIPS PUB 180-1 | |||
| * and FIP PUB 180-2. | ||||
| * | * | |||
| * A combined document showing all algorithms is available at | * A combined document showing all algorithms is available at | |||
| * http://csrc.nist.gov/publications/fips/ | * http://csrc.nist.gov/publications/fips/ | |||
| * fips180-3/fips180-3_final.pdf | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * fips180-2/fips180-2withchangenotice.pdf | ||||
| * | * | |||
| * The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit | * The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit | |||
| * message digests for a given data stream. It should take about | * message digests for a given data stream. It should take about | |||
| * 2**n steps to find a message with the same digest as a given | * 2**n steps to find a message with the same digest as a given | |||
| * message and 2**(n/2) to find any two messages with the same | * message and 2**(n/2) to find any two messages with the same | |||
| * digest, when n is the digest size in bits. Therefore, this | * digest, when n is the digest size in bits. Therefore, this | |||
| * algorithm can serve as a means of providing a | * algorithm can serve as a means of providing a | |||
| * "fingerprint" for a message. | * "fingerprint" for a message. | |||
| * | * | |||
| * Portability Issues: | * Portability Issues: | |||
| * SHA-224 and SHA-256 are defined in terms of 32-bit "words". | * SHA-224 and SHA-256 are defined in terms of 32-bit "words". | |||
| * This code uses <stdint.h> (included via "sha.h") to define 32 | * This code uses <stdint.h> (included via "sha.h") to define 32 | |||
| * and 8 bit unsigned integer types. If your C compiler does not | * and 8 bit unsigned integer types. If your C compiler does not | |||
| * support 32 bit unsigned integers, this code is not | * support 32 bit unsigned integers, this code is not | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * appropriate. | * appropriate. | |||
| * | * | |||
| * Caveats: | * Caveats: | |||
| * SHA-224 and SHA-256 are designed to work with messages less | * SHA-224 and SHA-256 are designed to work with messages less | |||
| * than 2^64 bits long. This implementation uses SHA224/256Input() | * than 2^64 bits long. This implementation uses SHA224/256Input() | |||
| * to hash the bits that are a multiple of the size of an 8-bit | * to hash the bits that are a multiple of the size of an 8-bit | |||
| * octet, and then optionally uses SHA224/256FinalBits() | * octet, and then optionally uses SHA224/256FinalBits() | |||
| * to hash the final few bits of the input. | * to hash the final few bits of the input. | |||
| */ | */ | |||
| skipping to change at page 40, line 4 ¶ | skipping to change at page 39, line 42 ¶ | |||
| #define SHA256_sigma0(word) \ | #define SHA256_sigma0(word) \ | |||
| (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word)) | (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word)) | |||
| #define SHA256_sigma1(word) \ | #define SHA256_sigma1(word) \ | |||
| (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word)) | (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word)) | |||
| /* | /* | |||
| * Add "length" to the length. | * Add "length" to the length. | |||
| * Set Corrupted when overflow has occurred. | * Set Corrupted when overflow has occurred. | |||
| */ | */ | |||
| static uint32_t addTemp; | static uint32_t addTemp; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define SHA224_256AddLength(context, length) \ | #define SHA224_256AddLength(context, length) \ | |||
| (addTemp = (context)->Length_Low, (context)->Corrupted = \ | (addTemp = (context)->Length_Low, (context)->Corrupted = \ | |||
| (((context)->Length_Low += (length)) < addTemp) && \ | (((context)->Length_Low += (length)) < addTemp) && \ | |||
| (++(context)->Length_High == 0) ? shaInputTooLong : \ | (++(context)->Length_High == 0) ? shaInputTooLong : \ | |||
| shaSuccess ) | (context)->Corrupted ) | |||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static int SHA224_256Reset(SHA256Context *context, uint32_t *H0); | ||||
| static void SHA224_256ProcessMessageBlock(SHA256Context *context); | ||||
| static void SHA224_256Finalize(SHA256Context *context, | static void SHA224_256Finalize(SHA256Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA224_256PadMessage(SHA256Context *context, | static void SHA224_256PadMessage(SHA256Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA224_256ProcessMessageBlock(SHA256Context *context); | ||||
| static int SHA224_256Reset(SHA256Context *context, uint32_t *H0); | ||||
| static int SHA224_256ResultN(SHA256Context *context, | static int SHA224_256ResultN(SHA256Context *context, | |||
| uint8_t Message_Digest[ ], int HashSize); | uint8_t Message_Digest[ ], int HashSize); | |||
| /* Initial Hash Values: FIPS-180-2 Change Notice 1 */ | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| /* Initial Hash Values: FIPS 180-3 section 5.3.2 */ | ||||
| static uint32_t SHA224_H0[SHA256HashSize/4] = { | static uint32_t SHA224_H0[SHA256HashSize/4] = { | |||
| 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, | 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939, | |||
| 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 | 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4 | |||
| }; | }; | |||
| /* Initial Hash Values: FIPS-180-2 section 5.3.2 */ | /* Initial Hash Values: FIPS 180-3 section 5.3.3 */ | |||
| static uint32_t SHA256_H0[SHA256HashSize/4] = { | static uint32_t SHA256_H0[SHA256HashSize/4] = { | |||
| 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, | 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A, | |||
| 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 | 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19 | |||
| }; | }; | |||
| /* | /* | |||
| * SHA224Reset | * SHA224Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the SHA224Context in preparation | * This function will initialize the SHA224Context in preparation | |||
| skipping to change at page 41, line 4 ¶ | skipping to change at page 40, line 41 ¶ | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA224Reset(SHA224Context *context) | int SHA224Reset(SHA224Context *context) | |||
| { | { | |||
| return SHA224_256Reset(context, SHA224_H0); | return SHA224_256Reset(context, SHA224_H0); | |||
| } | } | |||
| /* | /* | |||
| * SHA224Input | * SHA224Input | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | */ | |||
| int SHA224Input(SHA224Context *context, const uint8_t *message_array, | int SHA224Input(SHA224Context *context, const uint8_t *message_array, | |||
| unsigned int length) | unsigned int length) | |||
| { | { | |||
| return SHA256Input(context, message_array, length); | return SHA256Input(context, message_array, length); | |||
| } | } | |||
| /* | /* | |||
| * SHA224FinalBits | * SHA224FinalBits | |||
| * | * | |||
| skipping to change at page 42, line 4 ¶ | skipping to change at page 41, line 41 ¶ | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA224FinalBits(SHA224Context *context, | int SHA224FinalBits(SHA224Context *context, | |||
| uint8_t message_bits, unsigned int length) | uint8_t message_bits, unsigned int length) | |||
| { | { | |||
| return SHA256FinalBits(context, message_bits, length); | return SHA256FinalBits(context, message_bits, length); | |||
| } | } | |||
| /* | /* | |||
| * SHA224Result | * SHA224Result | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the 224-bit message digest | * This function will return the 224-bit message digest | |||
| * into the Message_Digest array provided by the caller. | * into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 27. | * the last octet of hash in the element with index 27. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | */ | |||
| int SHA224Result(SHA224Context *context, | int SHA224Result(SHA224Context *context, | |||
| uint8_t Message_Digest[SHA224HashSize]) | uint8_t Message_Digest[SHA224HashSize]) | |||
| { | { | |||
| return SHA224_256ResultN(context, Message_Digest, SHA224HashSize); | return SHA224_256ResultN(context, Message_Digest, SHA224HashSize); | |||
| } | } | |||
| /* | /* | |||
| * SHA256Reset | * SHA256Reset | |||
| * | * | |||
| skipping to change at page 43, line 4 ¶ | skipping to change at page 42, line 41 ¶ | |||
| } | } | |||
| /* | /* | |||
| * SHA256Input | * SHA256Input | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA256Input(SHA256Context *context, const uint8_t *message_array, | int SHA256Input(SHA256Context *context, const uint8_t *message_array, | |||
| unsigned int length) | unsigned int length) | |||
| { | { | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (!context || !message_array) | ||||
| return shaNull; | ||||
| if (context->Computed) | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| return context->Corrupted = shaStateError; | ||||
| if (context->Corrupted) | if (!message_array) return shaNull; | |||
| return context->Corrupted; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| while (length-- && !context->Corrupted) { | while (length--) { | |||
| context->Message_Block[context->Message_Block_Index++] = | context->Message_Block[context->Message_Block_Index++] = | |||
| (*message_array & 0xFF); | *message_array; | |||
| if ((SHA224_256AddLength(context, 8) == shaSuccess) && | if ((SHA224_256AddLength(context, 8) == shaSuccess) && | |||
| (context->Message_Block_Index == SHA256_Message_Block_Size)) | (context->Message_Block_Index == SHA256_Message_Block_Size)) | |||
| SHA224_256ProcessMessageBlock(context); | SHA224_256ProcessMessageBlock(context); | |||
| message_array++; | message_array++; | |||
| } | } | |||
| return context->Corrupted; | return context->Corrupted; | |||
| skipping to change at page 44, line 4 ¶ | skipping to change at page 43, line 35 ¶ | |||
| /* | /* | |||
| * SHA256FinalBits | * SHA256FinalBits | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will add in any final bits of the message. | * This function will add in any final bits of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA256FinalBits(SHA256Context *context, | int SHA256FinalBits(SHA256Context *context, | |||
| uint8_t message_bits, unsigned int length) | uint8_t message_bits, unsigned int length) | |||
| { | { | |||
| uint8_t masks[8] = { | static uint8_t masks[8] = { | |||
| /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | |||
| /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | |||
| /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | |||
| /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | |||
| }; | }; | |||
| uint8_t markbit[8] = { | static uint8_t markbit[8] = { | |||
| /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | |||
| /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | |||
| /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | |||
| }; | }; | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (!context) | if (context->Computed) return context->Corrupted = shaStateError; | |||
| return shaNull; | if (length >= 8) return context->Corrupted = shaBadParam; | |||
| if (context->Computed) | ||||
| return context->Corrupted = shaStateError; | ||||
| if ((length >= 8) || (length == 0)) | ||||
| return context->Corrupted = shaBadParam; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| SHA224_256AddLength(context, length); | SHA224_256AddLength(context, length); | |||
| SHA224_256Finalize(context, (uint8_t) | SHA224_256Finalize(context, (uint8_t) | |||
| ((message_bits & masks[length]) | markbit[length])); | ((message_bits & masks[length]) | markbit[length])); | |||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| * SHA256Result | * SHA256Result | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the 256-bit message digest | * This function will return the 256-bit message digest | |||
| * into the Message_Digest array provided by the caller. | * into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 31. | * the last octet of hash in the element with index 31. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int SHA256Result(SHA256Context *context, | int SHA256Result(SHA256Context *context, | |||
| uint8_t Message_Digest[SHA256HashSize]) | uint8_t Message_Digest[SHA256HashSize]) | |||
| { | { | |||
| return SHA224_256ResultN(context, Message_Digest, SHA256HashSize); | return SHA224_256ResultN(context, Message_Digest, SHA256HashSize); | |||
| } | } | |||
| /* | /* | |||
| * SHA224_256Finalize | * SHA224_256Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function finishes off the digest calculations. | * This helper function will initialize the SHA256Context in | |||
| * preparation for computing a new SHA-224 or SHA-256 message digest. | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | ||||
| * The SHA context to update | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the digest before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * sha Error Code. | ||||
| */ | ||||
| static void SHA224_256Finalize(SHA256Context *context, | ||||
| uint8_t Pad_Byte) | ||||
| { | ||||
| int i; | ||||
| SHA224_256PadMessage(context, Pad_Byte); | ||||
| /* message may be sensitive, so clear it out */ | ||||
| for (i = 0; i < SHA256_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| context->Length_Low = 0; /* and clear length */ | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| context->Length_High = 0; | ||||
| context->Computed = 1; | ||||
| } | ||||
| /* | ||||
| * SHA224_256PadMessage | ||||
| * | ||||
| * Description: | ||||
| * According to the standard, the message must be padded to the next | ||||
| * even multiple of 512 bits. The first padding bit must be a '1'. | ||||
| * The last 64 bits represent the length of the original message. | ||||
| * All bits in between should be 0. This helper function will pad | ||||
| * the message according to those rules by filling the | ||||
| * Message_Block array accordingly. When it returns, it can be | ||||
| * assumed that the message digest has been computed. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | * context: [in/out] | |||
| * The context to pad | * The context to reset. | |||
| * Pad_Byte: [in] | * H0[ ]: [in] | |||
| * The last byte to add to the digest before the 0-padding | * The initial hash value array to use. | |||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * sha Error Code. | |||
| */ | */ | |||
| static void SHA224_256PadMessage(SHA256Context *context, | static int SHA224_256Reset(SHA256Context *context, uint32_t *H0) | |||
| uint8_t Pad_Byte) | ||||
| { | { | |||
| /* | if (!context) return shaNull; | |||
| * Check to see if the current message block is too small to hold | ||||
| * the initial padding bits and length. If so, we will pad the | ||||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA256_Message_Block_Size-8)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA256_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| SHA224_256ProcessMessageBlock(context); | ||||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < (SHA256_Message_Block_Size-8)) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| /* | context->Length_High = context->Length_Low = 0; | |||
| * Store the message length as the last 8 octets | context->Message_Block_Index = 0; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | context->Intermediate_Hash[0] = H0[0]; | |||
| context->Intermediate_Hash[1] = H0[1]; | ||||
| context->Intermediate_Hash[2] = H0[2]; | ||||
| context->Intermediate_Hash[3] = H0[3]; | ||||
| context->Intermediate_Hash[4] = H0[4]; | ||||
| context->Intermediate_Hash[5] = H0[5]; | ||||
| context->Intermediate_Hash[6] = H0[6]; | ||||
| context->Intermediate_Hash[7] = H0[7]; | ||||
| */ | context->Computed = 0; | |||
| context->Message_Block[56] = (uint8_t)(context->Length_High >> 24); | context->Corrupted = shaSuccess; | |||
| context->Message_Block[57] = (uint8_t)(context->Length_High >> 16); | ||||
| context->Message_Block[58] = (uint8_t)(context->Length_High >> 8); | ||||
| context->Message_Block[59] = (uint8_t)(context->Length_High); | ||||
| context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24); | ||||
| context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16); | ||||
| context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8); | ||||
| context->Message_Block[63] = (uint8_t)(context->Length_Low); | ||||
| SHA224_256ProcessMessageBlock(context); | return shaSuccess; | |||
| } | } | |||
| /* | /* | |||
| * SHA224_256ProcessMessageBlock | * SHA224_256ProcessMessageBlock | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will process the next 512 bits of the | * This helper function will process the next 512 bits of the | |||
| * message stored in the Message_Block array. | * message stored in the Message_Block array. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| * | * | |||
| * Comments: | * Comments: | |||
| * Many of the variable names in this code, especially the | * Many of the variable names in this code, especially the | |||
| * single character names, were used because those were the | * single character names, were used because those were the | |||
| * names used in the publication. | * names used in the Secure Hash Standard. | |||
| */ | */ | |||
| static void SHA224_256ProcessMessageBlock(SHA256Context *context) | static void SHA224_256ProcessMessageBlock(SHA256Context *context) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { | { | |||
| /* Constants defined in FIPS-180-2, section 4.2.2 */ | /* Constants defined in FIPS 180-3, section 4.2.2 */ | |||
| static const uint32_t K[64] = { | static const uint32_t K[64] = { | |||
| 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, | 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, | |||
| 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, | 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01, | |||
| 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, | 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, | |||
| 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, | |||
| 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, | 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152, | |||
| 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, | 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, | |||
| 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, | 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, | |||
| 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, | |||
| 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, | 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, | |||
| 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, | 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08, | |||
| 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, | 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, | |||
| 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, | |||
| 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | |||
| }; | }; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| int t, t4; /* Loop counter */ | int t, t4; /* Loop counter */ | |||
| uint32_t temp1, temp2; /* Temporary word value */ | uint32_t temp1, temp2; /* Temporary word value */ | |||
| uint32_t W[64]; /* Word sequence */ | uint32_t W[64]; /* Word sequence */ | |||
| uint32_t A, B, C, D, E, F, G, H; /* Word buffers */ | uint32_t A, B, C, D, E, F, G, H; /* Word buffers */ | |||
| /* | /* | |||
| * Initialize the first 16 words in the array W | * Initialize the first 16 words in the array W | |||
| */ | */ | |||
| for (t = t4 = 0; t < 16; t++, t4 += 4) | for (t = t4 = 0; t < 16; t++, t4 += 4) | |||
| W[t] = (((uint32_t)context->Message_Block[t4]) << 24) | | W[t] = (((uint32_t)context->Message_Block[t4]) << 24) | | |||
| skipping to change at page 48, line 40 ¶ | skipping to change at page 47, line 4 ¶ | |||
| F = context->Intermediate_Hash[5]; | F = context->Intermediate_Hash[5]; | |||
| G = context->Intermediate_Hash[6]; | G = context->Intermediate_Hash[6]; | |||
| H = context->Intermediate_Hash[7]; | H = context->Intermediate_Hash[7]; | |||
| for (t = 0; t < 64; t++) { | for (t = 0; t < 64; t++) { | |||
| temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | |||
| temp2 = SHA256_SIGMA0(A) + SHA_Maj(A,B,C); | temp2 = SHA256_SIGMA0(A) + SHA_Maj(A,B,C); | |||
| H = G; | H = G; | |||
| G = F; | G = F; | |||
| F = E; | F = E; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| E = D + temp1; | E = D + temp1; | |||
| D = C; | D = C; | |||
| C = B; | C = B; | |||
| B = A; | B = A; | |||
| A = temp1 + temp2; | A = temp1 + temp2; | |||
| } | } | |||
| context->Intermediate_Hash[0] += A; | context->Intermediate_Hash[0] += A; | |||
| context->Intermediate_Hash[1] += B; | context->Intermediate_Hash[1] += B; | |||
| context->Intermediate_Hash[2] += C; | context->Intermediate_Hash[2] += C; | |||
| context->Intermediate_Hash[3] += D; | context->Intermediate_Hash[3] += D; | |||
| context->Intermediate_Hash[4] += E; | context->Intermediate_Hash[4] += E; | |||
| context->Intermediate_Hash[5] += F; | context->Intermediate_Hash[5] += F; | |||
| context->Intermediate_Hash[6] += G; | context->Intermediate_Hash[6] += G; | |||
| context->Intermediate_Hash[7] += H; | context->Intermediate_Hash[7] += H; | |||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| /* | /* | |||
| * SHA224_256Reset | * SHA224_256Finalize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will initialize the SHA256Context in | * This helper function finishes off the digest calculations. | |||
| * preparation for computing a new SHA-224 or SHA-256 message digest. | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The SHA context to update | |||
| * H0 | * Pad_Byte: [in] | |||
| * The initial hash value to use. | * The last byte to add to the message block before the 0-padding | |||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| static int SHA224_256Reset(SHA256Context *context, uint32_t *H0) | static void SHA224_256Finalize(SHA256Context *context, | |||
| uint8_t Pad_Byte) | ||||
| { | { | |||
| if (!context) | int i; | |||
| return shaNull; | SHA224_256PadMessage(context, Pad_Byte); | |||
| /* message may be sensitive, so clear it out */ | ||||
| for (i = 0; i < SHA256_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| context->Length_High = 0; /* and clear length */ | ||||
| context->Length_Low = 0; | ||||
| context->Computed = 1; | ||||
| } | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Length_Low = 0; | /* | |||
| context->Length_High = 0; | * SHA224_256PadMessage | |||
| context->Message_Block_Index = 0; | * | |||
| * Description: | ||||
| * According to the standard, the message must be padded to the next | ||||
| * even multiple of 512 bits. The first padding bit must be a '1'. | ||||
| * The last 64 bits represent the length of the original message. | ||||
| * All bits in between should be 0. This helper function will pad | ||||
| * the message according to those rules by filling the | ||||
| * Message_Block array accordingly. When it returns, it can be | ||||
| * assumed that the message digest has been computed. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The context to pad | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the message block before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * Nothing. | ||||
| */ | ||||
| static void SHA224_256PadMessage(SHA256Context *context, | ||||
| uint8_t Pad_Byte) | ||||
| { | ||||
| /* | ||||
| * Check to see if the current message block is too small to hold | ||||
| * the initial padding bits and length. If so, we will pad the | ||||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA256_Message_Block_Size-8)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA256_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| SHA224_256ProcessMessageBlock(context); | ||||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| context->Intermediate_Hash[0] = H0[0]; | while (context->Message_Block_Index < (SHA256_Message_Block_Size-8)) | |||
| context->Intermediate_Hash[1] = H0[1]; | context->Message_Block[context->Message_Block_Index++] = 0; | |||
| context->Intermediate_Hash[2] = H0[2]; | ||||
| context->Intermediate_Hash[3] = H0[3]; | ||||
| context->Intermediate_Hash[4] = H0[4]; | ||||
| context->Intermediate_Hash[5] = H0[5]; | ||||
| context->Intermediate_Hash[6] = H0[6]; | ||||
| context->Intermediate_Hash[7] = H0[7]; | ||||
| context->Computed = 0; | /* | |||
| context->Corrupted = 0; | * Store the message length as the last 8 octets | |||
| */ | ||||
| context->Message_Block[56] = (uint8_t)(context->Length_High >> 24); | ||||
| context->Message_Block[57] = (uint8_t)(context->Length_High >> 16); | ||||
| context->Message_Block[58] = (uint8_t)(context->Length_High >> 8); | ||||
| return shaSuccess; | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| context->Message_Block[59] = (uint8_t)(context->Length_High); | ||||
| context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24); | ||||
| context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16); | ||||
| context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8); | ||||
| context->Message_Block[63] = (uint8_t)(context->Length_Low); | ||||
| SHA224_256ProcessMessageBlock(context); | ||||
| } | } | |||
| /* | /* | |||
| * SHA224_256ResultN | * SHA224_256ResultN | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will return the 224-bit or 256-bit message | * This helper function will return the 224-bit or 256-bit message | |||
| * digest into the Message_Digest array provided by the caller. | * digest into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * the last octet of hash in the element with index 27/31. | * the last octet of hash in the element with index 27/31. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * HashSize: [in] | * HashSize: [in] | |||
| * The size of the hash, either 28 or 32. | * The size of the hash, either 28 or 32. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| static int SHA224_256ResultN(SHA256Context *context, | static int SHA224_256ResultN(SHA256Context *context, | |||
| uint8_t Message_Digest[ ], int HashSize) | uint8_t Message_Digest[ ], int HashSize) | |||
| { | { | |||
| int i; | int i; | |||
| if (!context || !Message_Digest) | if (!context) return shaNull; | |||
| return shaNull; | if (!Message_Digest) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| if (!context->Computed) | if (!context->Computed) | |||
| SHA224_256Finalize(context, 0x80); | SHA224_256Finalize(context, 0x80); | |||
| for (i = 0; i < HashSize; ++i) | for (i = 0; i < HashSize; ++i) | |||
| Message_Digest[i] = (uint8_t) | Message_Digest[i] = (uint8_t) | |||
| (context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )); | (context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) )); | |||
| return shaSuccess; | return shaSuccess; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 8.2.3 sha384-512.c | 8.2.3 sha384-512.c | |||
| /************************* sha384-512.c ************************/ | /************************* sha384-512.c ************************/ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| /* Copyright (c) 2010 IETF Trust and the persons identified as */ | /* Copyright (c) 2010 IETF Trust and the persons identified as */ | |||
| /* authors of the code. All rights reserved. */ | /* authors of the code. All rights reserved. */ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the Secure Hash Algorithms SHA-384 and | * This file implements the Secure Hash Algorithms SHA-384 and | |||
| * SHA-512 as defined in the National Institute of Standards | * SHA-512 as defined in the U.S. National Institute of Standards | |||
| * and Technology Federal Information Processing Standards | * and Technology Federal Information Processing Standards | |||
| * Publication (FIPS PUB) 180-2 published on August 1, 2002, and | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * and formerly defined in its predecessors, FIPS PUB 180-1 | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | * and FIP PUB 180-2. | |||
| * the FIPS PUB 180-2 Change Notice published on February 28, 2004. | ||||
| * | * | |||
| * A combined document showing all algorithms is available at | * A combined document showing all algorithms is available at | |||
| * http://csrc.nist.gov/publications/fips/ | * http://csrc.nist.gov/publications/fips/ | |||
| * fips180-2/fips180-2withchangenotice.pdf | * fips180-3/fips180-3_final.pdf | |||
| * | * | |||
| * The SHA-384 and SHA-512 algorithms produce 384-bit and 512-bit | * The SHA-384 and SHA-512 algorithms produce 384-bit and 512-bit | |||
| * message digests for a given data stream. It should take about | * message digests for a given data stream. It should take about | |||
| * 2**n steps to find a message with the same digest as a given | * 2**n steps to find a message with the same digest as a given | |||
| * message and 2**(n/2) to find any two messages with the same | * message and 2**(n/2) to find any two messages with the same | |||
| * digest, when n is the digest size in bits. Therefore, this | * digest, when n is the digest size in bits. Therefore, this | |||
| * algorithm can serve as a means of providing a | * algorithm can serve as a means of providing a | |||
| * "fingerprint" for a message. | * "fingerprint" for a message. | |||
| * | * | |||
| * Portability Issues: | * Portability Issues: | |||
| skipping to change at page 51, line 40 ¶ | skipping to change at page 50, line 54 ¶ | |||
| * Caveats: | * Caveats: | |||
| * SHA-384 and SHA-512 are designed to work with messages less | * SHA-384 and SHA-512 are designed to work with messages less | |||
| * than 2^128 bits long. This implementation uses SHA384/512Input() | * than 2^128 bits long. This implementation uses SHA384/512Input() | |||
| * to hash the bits that are a multiple of the size of an 8-bit | * to hash the bits that are a multiple of the size of an 8-bit | |||
| * octet, and then optionally uses SHA384/256FinalBits() | * octet, and then optionally uses SHA384/256FinalBits() | |||
| * to hash the final few bits of the input. | * to hash the final few bits of the input. | |||
| * | * | |||
| */ | */ | |||
| #include "sha.h" | #include "sha.h" | |||
| #include "sha-private.h" | ||||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Define 64-bit arithmetic in terms of 32-bit arithmetic. | * Define 64-bit arithmetic in terms of 32-bit arithmetic. | |||
| * Each 64-bit number is represented in a 2-word array. | * Each 64-bit number is represented in a 2-word array. | |||
| * All macros are defined such that the result is the last parameter. | * All macros are defined such that the result is the last parameter. | |||
| */ | */ | |||
| /* | /* | |||
| * Define shift, rotate left and rotate right functions | * Define shift, rotate left and rotate right functions | |||
| */ | */ | |||
| #define SHA512_SHR(bits, word, ret) ( \ | #define SHA512_SHR(bits, word, ret) ( \ | |||
| /* (((uint64_t)((word))) >> (bits)) */ \ | /* (((uint64_t)((word))) >> (bits)) */ \ | |||
| (ret)[0] = (((bits) < 32) && ((bits) >= 0)) ? \ | (ret)[0] = (((bits) < 32) && ((bits) >= 0)) ? \ | |||
| ((word)[0] >> (bits)) : 0, \ | ((word)[0] >> (bits)) : 0, \ | |||
| (ret)[1] = ((bits) > 32) ? ((word)[0] >> ((bits) - 32)) : \ | (ret)[1] = ((bits) > 32) ? ((word)[0] >> ((bits) - 32)) : \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| ((bits) == 32) ? (word)[0] : \ | ((bits) == 32) ? (word)[0] : \ | |||
| ((bits) >= 0) ? \ | ((bits) >= 0) ? \ | |||
| (((word)[0] << (32 - (bits))) | \ | (((word)[0] << (32 - (bits))) | \ | |||
| ((word)[1] >> (bits))) : 0 ) | ((word)[1] >> (bits))) : 0 ) | |||
| #define SHA512_SHL(bits, word, ret) ( \ | #define SHA512_SHL(bits, word, ret) ( \ | |||
| /* (((uint64_t)(word)) << (bits)) */ \ | /* (((uint64_t)(word)) << (bits)) */ \ | |||
| (ret)[0] = ((bits) > 32) ? ((word)[1] << ((bits) - 32)) : \ | (ret)[0] = ((bits) > 32) ? ((word)[1] << ((bits) - 32)) : \ | |||
| ((bits) == 32) ? (word)[1] : \ | ((bits) == 32) ? (word)[1] : \ | |||
| ((bits) >= 0) ? \ | ((bits) >= 0) ? \ | |||
| skipping to change at page 52, line 44 ¶ | skipping to change at page 52, line 5 ¶ | |||
| (ret)[0] = (word1)[0] ^ (word2)[0], \ | (ret)[0] = (word1)[0] ^ (word2)[0], \ | |||
| (ret)[1] = (word1)[1] ^ (word2)[1] ) | (ret)[1] = (word1)[1] ^ (word2)[1] ) | |||
| /* | /* | |||
| * Define 64-bit AND | * Define 64-bit AND | |||
| */ | */ | |||
| #define SHA512_AND(word1, word2, ret) ( \ | #define SHA512_AND(word1, word2, ret) ( \ | |||
| (ret)[0] = (word1)[0] & (word2)[0], \ | (ret)[0] = (word1)[0] & (word2)[0], \ | |||
| (ret)[1] = (word1)[1] & (word2)[1] ) | (ret)[1] = (word1)[1] & (word2)[1] ) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Define 64-bit TILDA | * Define 64-bit TILDA | |||
| */ | */ | |||
| #define SHA512_TILDA(word, ret) \ | #define SHA512_TILDA(word, ret) \ | |||
| ( (ret)[0] = ~(word)[0], (ret)[1] = ~(word)[1] ) | ( (ret)[0] = ~(word)[0], (ret)[1] = ~(word)[1] ) | |||
| /* | /* | |||
| * Define 64-bit ADD | * Define 64-bit ADD | |||
| */ | */ | |||
| #define SHA512_ADD(word1, word2, ret) ( \ | #define SHA512_ADD(word1, word2, ret) ( \ | |||
| (ret)[1] = (word1)[1], (ret)[1] += (word2)[1], \ | (ret)[1] = (word1)[1], (ret)[1] += (word2)[1], \ | |||
| (ret)[0] = (word1)[0] + (word2)[0] + ((ret)[1] < (word1)[1]) ) | (ret)[0] = (word1)[0] + (word2)[0] + ((ret)[1] < (word1)[1]) ) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Add the 4word value in word2 to word1. | * Add the 4word value in word2 to word1. | |||
| */ | */ | |||
| static uint32_t ADDTO4_temp, ADDTO4_temp2; | static uint32_t ADDTO4_temp, ADDTO4_temp2; | |||
| #define SHA512_ADDTO4(word1, word2) ( \ | #define SHA512_ADDTO4(word1, word2) ( \ | |||
| ADDTO4_temp = (word1)[3], \ | ADDTO4_temp = (word1)[3], \ | |||
| (word1)[3] += (word2)[3], \ | (word1)[3] += (word2)[3], \ | |||
| ADDTO4_temp2 = (word1)[2], \ | ADDTO4_temp2 = (word1)[2], \ | |||
| (word1)[2] += (word2)[2] + ((word1)[3] < ADDTO4_temp), \ | (word1)[2] += (word2)[2] + ((word1)[3] < ADDTO4_temp), \ | |||
| ADDTO4_temp = (word1)[1], \ | ADDTO4_temp = (word1)[1], \ | |||
| skipping to change at page 53, line 40 ¶ | skipping to change at page 52, line 53 ¶ | |||
| * SHA rotate ((word >> bits) | (word << (64-bits))) | * SHA rotate ((word >> bits) | (word << (64-bits))) | |||
| */ | */ | |||
| static uint32_t ROTR_temp1[2], ROTR_temp2[2]; | static uint32_t ROTR_temp1[2], ROTR_temp2[2]; | |||
| #define SHA512_ROTR(bits, word, ret) ( \ | #define SHA512_ROTR(bits, word, ret) ( \ | |||
| SHA512_SHR((bits), (word), ROTR_temp1), \ | SHA512_SHR((bits), (word), ROTR_temp1), \ | |||
| SHA512_SHL(64-(bits), (word), ROTR_temp2), \ | SHA512_SHL(64-(bits), (word), ROTR_temp2), \ | |||
| SHA512_OR(ROTR_temp1, ROTR_temp2, (ret)) ) | SHA512_OR(ROTR_temp1, ROTR_temp2, (ret)) ) | |||
| /* | /* | |||
| * Define the SHA SIGMA and sigma macros | * Define the SHA SIGMA and sigma macros | |||
| * | ||||
| * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word) | * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word) | |||
| */ | */ | |||
| static uint32_t SIGMA0_temp1[2], SIGMA0_temp2[2], | static uint32_t SIGMA0_temp1[2], SIGMA0_temp2[2], | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| SIGMA0_temp3[2], SIGMA0_temp4[2]; | SIGMA0_temp3[2], SIGMA0_temp4[2]; | |||
| #define SHA512_SIGMA0(word, ret) ( \ | #define SHA512_SIGMA0(word, ret) ( \ | |||
| SHA512_ROTR(28, (word), SIGMA0_temp1), \ | SHA512_ROTR(28, (word), SIGMA0_temp1), \ | |||
| SHA512_ROTR(34, (word), SIGMA0_temp2), \ | SHA512_ROTR(34, (word), SIGMA0_temp2), \ | |||
| SHA512_ROTR(39, (word), SIGMA0_temp3), \ | SHA512_ROTR(39, (word), SIGMA0_temp3), \ | |||
| SHA512_XOR(SIGMA0_temp2, SIGMA0_temp3, SIGMA0_temp4), \ | SHA512_XOR(SIGMA0_temp2, SIGMA0_temp3, SIGMA0_temp4), \ | |||
| SHA512_XOR(SIGMA0_temp1, SIGMA0_temp4, (ret)) ) | SHA512_XOR(SIGMA0_temp1, SIGMA0_temp4, (ret)) ) | |||
| /* | /* | |||
| * SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word) | * SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word) | |||
| */ | */ | |||
| static uint32_t SIGMA1_temp1[2], SIGMA1_temp2[2], | static uint32_t SIGMA1_temp1[2], SIGMA1_temp2[2], | |||
| SIGMA1_temp3[2], SIGMA1_temp4[2]; | SIGMA1_temp3[2], SIGMA1_temp4[2]; | |||
| #define SHA512_SIGMA1(word, ret) ( \ | #define SHA512_SIGMA1(word, ret) ( \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| SHA512_ROTR(14, (word), SIGMA1_temp1), \ | SHA512_ROTR(14, (word), SIGMA1_temp1), \ | |||
| SHA512_ROTR(18, (word), SIGMA1_temp2), \ | SHA512_ROTR(18, (word), SIGMA1_temp2), \ | |||
| SHA512_ROTR(41, (word), SIGMA1_temp3), \ | SHA512_ROTR(41, (word), SIGMA1_temp3), \ | |||
| SHA512_XOR(SIGMA1_temp2, SIGMA1_temp3, SIGMA1_temp4), \ | SHA512_XOR(SIGMA1_temp2, SIGMA1_temp3, SIGMA1_temp4), \ | |||
| SHA512_XOR(SIGMA1_temp1, SIGMA1_temp4, (ret)) ) | SHA512_XOR(SIGMA1_temp1, SIGMA1_temp4, (ret)) ) | |||
| /* | /* | |||
| * (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) | * (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) | |||
| */ | */ | |||
| static uint32_t sigma0_temp1[2], sigma0_temp2[2], | static uint32_t sigma0_temp1[2], sigma0_temp2[2], | |||
| skipping to change at page 54, line 36 ¶ | skipping to change at page 53, line 50 ¶ | |||
| */ | */ | |||
| static uint32_t sigma1_temp1[2], sigma1_temp2[2], | static uint32_t sigma1_temp1[2], sigma1_temp2[2], | |||
| sigma1_temp3[2], sigma1_temp4[2]; | sigma1_temp3[2], sigma1_temp4[2]; | |||
| #define SHA512_sigma1(word, ret) ( \ | #define SHA512_sigma1(word, ret) ( \ | |||
| SHA512_ROTR(19, (word), sigma1_temp1), \ | SHA512_ROTR(19, (word), sigma1_temp1), \ | |||
| SHA512_ROTR(61, (word), sigma1_temp2), \ | SHA512_ROTR(61, (word), sigma1_temp2), \ | |||
| SHA512_SHR( 6, (word), sigma1_temp3), \ | SHA512_SHR( 6, (word), sigma1_temp3), \ | |||
| SHA512_XOR(sigma1_temp2, sigma1_temp3, sigma1_temp4), \ | SHA512_XOR(sigma1_temp2, sigma1_temp3, sigma1_temp4), \ | |||
| SHA512_XOR(sigma1_temp1, sigma1_temp4, (ret)) ) | SHA512_XOR(sigma1_temp1, sigma1_temp4, (ret)) ) | |||
| #undef SHA_Ch | ||||
| #undef SHA_Maj | ||||
| #ifndef USE_MODIFIED_MACROS | #ifndef USE_MODIFIED_MACROS | |||
| /* | /* | |||
| * These definitions are the ones used in FIPS-180-2, section 4.1.3 | * These definitions are the ones used in FIPS 180-3, section 4.1.3 | |||
| * Ch(x,y,z) ((x & y) ^ (~x & z)) | * Ch(x,y,z) ((x & y) ^ (~x & z)) | |||
| */ | */ | |||
| static uint32_t Ch_temp1[2], Ch_temp2[2], Ch_temp3[2]; | static uint32_t Ch_temp1[2], Ch_temp2[2], Ch_temp3[2]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define SHA_Ch(x, y, z, ret) ( \ | #define SHA_Ch(x, y, z, ret) ( \ | |||
| SHA512_AND(x, y, Ch_temp1), \ | SHA512_AND(x, y, Ch_temp1), \ | |||
| SHA512_TILDA(x, Ch_temp2), \ | SHA512_TILDA(x, Ch_temp2), \ | |||
| SHA512_AND(Ch_temp2, z, Ch_temp3), \ | SHA512_AND(Ch_temp2, z, Ch_temp3), \ | |||
| SHA512_XOR(Ch_temp1, Ch_temp3, (ret)) ) | SHA512_XOR(Ch_temp1, Ch_temp3, (ret)) ) | |||
| /* | /* | |||
| * Maj(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z))) | * Maj(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z))) | |||
| */ | */ | |||
| static uint32_t Maj_temp1[2], Maj_temp2[2], | static uint32_t Maj_temp1[2], Maj_temp2[2], | |||
| Maj_temp3[2], Maj_temp4[2]; | Maj_temp3[2], Maj_temp4[2]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define SHA_Maj(x, y, z, ret) ( \ | #define SHA_Maj(x, y, z, ret) ( \ | |||
| SHA512_AND(x, y, Maj_temp1), \ | SHA512_AND(x, y, Maj_temp1), \ | |||
| SHA512_AND(x, z, Maj_temp2), \ | SHA512_AND(x, z, Maj_temp2), \ | |||
| SHA512_AND(y, z, Maj_temp3), \ | SHA512_AND(y, z, Maj_temp3), \ | |||
| SHA512_XOR(Maj_temp2, Maj_temp3, Maj_temp4), \ | SHA512_XOR(Maj_temp2, Maj_temp3, Maj_temp4), \ | |||
| SHA512_XOR(Maj_temp1, Maj_temp4, (ret)) ) | SHA512_XOR(Maj_temp1, Maj_temp4, (ret)) ) | |||
| #else /* !USE_MODIFIED_MACROS */ | #else /* !USE_MODIFIED_MACROS */ | |||
| /* | /* | |||
| * These definitions are potentially faster equivalents for the ones | * These definitions are potentially faster equivalents for the ones | |||
| * used in FIPS-180-2, section 4.1.3. | * used in FIPS 180-3, section 4.1.3. | |||
| * ((x & y) ^ (~x & z)) becomes | * ((x & y) ^ (~x & z)) becomes | |||
| * ((x & (y ^ z)) ^ z) | * ((x & (y ^ z)) ^ z) | |||
| */ | */ | |||
| #define SHA_Ch(x, y, z, ret) ( \ | #define SHA_Ch(x, y, z, ret) ( \ | |||
| (ret)[0] = (((x)[0] & ((y)[0] ^ (z)[0])) ^ (z)[0]), \ | (ret)[0] = (((x)[0] & ((y)[0] ^ (z)[0])) ^ (z)[0]), \ | |||
| (ret)[1] = (((x)[1] & ((y)[1] ^ (z)[1])) ^ (z)[1]) ) | (ret)[1] = (((x)[1] & ((y)[1] ^ (z)[1])) ^ (z)[1]) ) | |||
| /* | /* | |||
| * ((x & y) ^ (x & z) ^ (y & z)) becomes | * ((x & y) ^ (x & z) ^ (y & z)) becomes | |||
| * ((x & (y | z)) | (y & z)) | * ((x & (y | z)) | (y & z)) | |||
| skipping to change at page 55, line 43 ¶ | skipping to change at page 54, line 53 ¶ | |||
| /* | /* | |||
| * Add "length" to the length. | * Add "length" to the length. | |||
| * Set Corrupted when overflow has occurred. | * Set Corrupted when overflow has occurred. | |||
| */ | */ | |||
| static uint32_t addTemp[4] = { 0, 0, 0, 0 }; | static uint32_t addTemp[4] = { 0, 0, 0, 0 }; | |||
| #define SHA384_512AddLength(context, length) ( \ | #define SHA384_512AddLength(context, length) ( \ | |||
| addTemp[3] = (length), SHA512_ADDTO4((context)->Length, addTemp), \ | addTemp[3] = (length), SHA512_ADDTO4((context)->Length, addTemp), \ | |||
| (context)->Corrupted = (((context)->Length[3] < (length)) && \ | (context)->Corrupted = (((context)->Length[3] < (length)) && \ | |||
| ((context)->Length[2] == 0) && ((context)->Length[1] == 0) && \ | ((context)->Length[2] == 0) && ((context)->Length[1] == 0) && \ | |||
| ((context)->Length[0] == 0)) ? shaInputTooLong : shaSuccess ) | ((context)->Length[0] == 0)) ? shaInputTooLong : \ | |||
| (context)->Corrupted ) | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static int SHA384_512Reset(SHA512Context *context, | ||||
| uint32_t H0[SHA512HashSize/4]); | ||||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context); | ||||
| static void SHA384_512Finalize(SHA512Context *context, | static void SHA384_512Finalize(SHA512Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA384_512PadMessage(SHA512Context *context, | static void SHA384_512PadMessage(SHA512Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context); | ||||
| static int SHA384_512Reset(SHA512Context *context, | ||||
| uint32_t H0[SHA512HashSize/4]); | ||||
| static int SHA384_512ResultN( SHA512Context *context, | static int SHA384_512ResultN( SHA512Context *context, | |||
| uint8_t Message_Digest[ ], int HashSize); | uint8_t Message_Digest[ ], int HashSize); | |||
| /* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */ | /* Initial Hash Values: FIPS 180-3 sections 5.3.4 and 5.3.5 */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| static uint32_t SHA384_H0[SHA512HashSize/4] = { | static uint32_t SHA384_H0[SHA512HashSize/4] = { | |||
| 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A, | 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A, | |||
| 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31, | 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31, | |||
| 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, | 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, | |||
| 0xBEFA4FA4 | 0xBEFA4FA4 | |||
| }; | }; | |||
| static uint32_t SHA512_H0[SHA512HashSize/4] = { | static uint32_t SHA512_H0[SHA512HashSize/4] = { | |||
| 0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B, 0x3C6EF372, | 0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B, 0x3C6EF372, | |||
| 0xFE94F82B, 0xA54FF53A, 0x5F1D36F1, 0x510E527F, 0xADE682D1, | 0xFE94F82B, 0xA54FF53A, 0x5F1D36F1, 0x510E527F, 0xADE682D1, | |||
| 0x9B05688C, 0x2B3E6C1F, 0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19, | 0x9B05688C, 0x2B3E6C1F, 0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19, | |||
| 0x137E2179 | 0x137E2179 | |||
| }; | }; | |||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| #include "sha-private.h" | ||||
| /* Define the SHA shift, rotate left and rotate right macro */ | /* Define the SHA shift, rotate left and rotate right macro */ | |||
| #define SHA512_SHR(bits,word) (((uint64_t)(word)) >> (bits)) | #define SHA512_SHR(bits,word) (((uint64_t)(word)) >> (bits)) | |||
| #define SHA512_ROTR(bits,word) ((((uint64_t)(word)) >> (bits)) | \ | #define SHA512_ROTR(bits,word) ((((uint64_t)(word)) >> (bits)) | \ | |||
| (((uint64_t)(word)) << (64-(bits)))) | (((uint64_t)(word)) << (64-(bits)))) | |||
| /* Define the SHA SIGMA and sigma macros */ | /* | |||
| * Define the SHA SIGMA and sigma macros | ||||
| * | ||||
| * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word) | ||||
| */ | ||||
| #define SHA512_SIGMA0(word) \ | #define SHA512_SIGMA0(word) \ | |||
| (SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word)) | (SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word)) | |||
| #define SHA512_SIGMA1(word) \ | #define SHA512_SIGMA1(word) \ | |||
| (SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word)) | (SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word)) | |||
| #define SHA512_sigma0(word) \ | #define SHA512_sigma0(word) \ | |||
| (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) | (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word)) | |||
| #define SHA512_sigma1(word) \ | #define SHA512_sigma1(word) \ | |||
| (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word)) | (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word)) | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Add "length" to the length. | * Add "length" to the length. | |||
| * Set Corrupted when overflow has occurred. | * Set Corrupted when overflow has occurred. | |||
| */ | */ | |||
| static uint64_t addTemp; | static uint64_t addTemp; | |||
| #define SHA384_512AddLength(context, length) \ | #define SHA384_512AddLength(context, length) \ | |||
| (addTemp = context->Length_Low, context->Corrupted = \ | (addTemp = context->Length_Low, context->Corrupted = \ | |||
| ((context->Length_Low += length) < addTemp) && \ | ((context->Length_Low += length) < addTemp) && \ | |||
| (++context->Length_High == 0) ? 1 : 0) | (++context->Length_High == 0) ? shaInputTooLong : \ | |||
| (context)->Corrupted) | ||||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static int SHA384_512Reset(SHA512Context *context, | ||||
| uint64_t H0[SHA512HashSize/8]); | ||||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context); | ||||
| static void SHA384_512Finalize(SHA512Context *context, | static void SHA384_512Finalize(SHA512Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA384_512PadMessage(SHA512Context *context, | static void SHA384_512PadMessage(SHA512Context *context, | |||
| uint8_t Pad_Byte); | uint8_t Pad_Byte); | |||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context); | ||||
| static int SHA384_512Reset(SHA512Context *context, | ||||
| uint64_t H0[SHA512HashSize/8]); | ||||
| static int SHA384_512ResultN(SHA512Context *context, | static int SHA384_512ResultN(SHA512Context *context, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| uint8_t Message_Digest[ ], int HashSize); | uint8_t Message_Digest[ ], int HashSize); | |||
| /* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */ | /* Initial Hash Values: FIPS 180-3 sections 5.3.4 and 5.3.5 */ | |||
| static uint64_t SHA384_H0[ ] = { | static uint64_t SHA384_H0[ ] = { | |||
| 0xCBBB9D5DC1059ED8ll, 0x629A292A367CD507ll, 0x9159015A3070DD17ll, | 0xCBBB9D5DC1059ED8ll, 0x629A292A367CD507ll, 0x9159015A3070DD17ll, | |||
| 0x152FECD8F70E5939ll, 0x67332667FFC00B31ll, 0x8EB44A8768581511ll, | 0x152FECD8F70E5939ll, 0x67332667FFC00B31ll, 0x8EB44A8768581511ll, | |||
| 0xDB0C2E0D64F98FA7ll, 0x47B5481DBEFA4FA4ll | 0xDB0C2E0D64F98FA7ll, 0x47B5481DBEFA4FA4ll | |||
| }; | }; | |||
| static uint64_t SHA512_H0[ ] = { | static uint64_t SHA512_H0[ ] = { | |||
| 0x6A09E667F3BCC908ll, 0xBB67AE8584CAA73Bll, 0x3C6EF372FE94F82Bll, | 0x6A09E667F3BCC908ll, 0xBB67AE8584CAA73Bll, 0x3C6EF372FE94F82Bll, | |||
| 0xA54FF53A5F1D36F1ll, 0x510E527FADE682D1ll, 0x9B05688C2B3E6C1Fll, | 0xA54FF53A5F1D36F1ll, 0x510E527FADE682D1ll, 0x9B05688C2B3E6C1Fll, | |||
| 0x1F83D9ABFB41BD6Bll, 0x5BE0CD19137E2179ll | 0x1F83D9ABFB41BD6Bll, 0x5BE0CD19137E2179ll | |||
| }; | }; | |||
| skipping to change at page 57, line 37 ¶ | skipping to change at page 57, line 4 ¶ | |||
| * for computing a new SHA384 message digest. | * for computing a new SHA384 message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| int SHA384Reset(SHA384Context *context) | int SHA384Reset(SHA384Context *context) | |||
| { | { | |||
| return SHA384_512Reset(context, SHA384_H0); | return SHA384_512Reset(context, SHA384_H0); | |||
| } | } | |||
| /* | /* | |||
| * SHA384Input | * SHA384Input | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA384Input(SHA384Context *context, | int SHA384Input(SHA384Context *context, | |||
| const uint8_t *message_array, unsigned int length) | const uint8_t *message_array, unsigned int length) | |||
| { | { | |||
| return SHA512Input(context, message_array, length); | return SHA512Input(context, message_array, length); | |||
| skipping to change at page 58, line 38 ¶ | skipping to change at page 58, line 4 ¶ | |||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | */ | |||
| int SHA384FinalBits(SHA384Context *context, | int SHA384FinalBits(SHA384Context *context, | |||
| uint8_t message_bits, unsigned int length) | uint8_t message_bits, unsigned int length) | |||
| { | { | |||
| return SHA512FinalBits(context, message_bits, length); | return SHA512FinalBits(context, message_bits, length); | |||
| } | } | |||
| /* | /* | |||
| * SHA384Result | * SHA384Result | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the 384-bit message digest | * This function will return the 384-bit message digest | |||
| * into the Message_Digest array provided by the caller. | * into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 47. | * the last octet of hash in the element with index 47. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA384Result(SHA384Context *context, | int SHA384Result(SHA384Context *context, | |||
| uint8_t Message_Digest[SHA384HashSize]) | uint8_t Message_Digest[SHA384HashSize]) | |||
| { | { | |||
| return SHA384_512ResultN(context, Message_Digest, SHA384HashSize); | return SHA384_512ResultN(context, Message_Digest, SHA384HashSize); | |||
| skipping to change at page 59, line 38 ¶ | skipping to change at page 59, line 4 ¶ | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA512Reset(SHA512Context *context) | int SHA512Reset(SHA512Context *context) | |||
| { | { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return SHA384_512Reset(context, SHA512_H0); | return SHA384_512Reset(context, SHA512_H0); | |||
| } | } | |||
| /* | /* | |||
| * SHA512Input | * SHA512Input | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA512Input(SHA512Context *context, | int SHA512Input(SHA512Context *context, | |||
| const uint8_t *message_array, | const uint8_t *message_array, | |||
| unsigned int length) | unsigned int length) | |||
| { | { | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (!message_array) return shaNull; | ||||
| if (!context || !message_array) | if (context->Computed) return context->Corrupted = shaStateError; | |||
| return shaNull; | if (context->Corrupted) return context->Corrupted; | |||
| if (context->Computed) | ||||
| return context->Corrupted = shaStateError; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| while (length-- && !context->Corrupted) { | while (length--) { | |||
| context->Message_Block[context->Message_Block_Index++] = | context->Message_Block[context->Message_Block_Index++] = | |||
| (*message_array & 0xFF); | *message_array; | |||
| if ((SHA384_512AddLength(context, 8) == shaSuccess) && | if ((SHA384_512AddLength(context, 8) == shaSuccess) && | |||
| (context->Message_Block_Index == SHA512_Message_Block_Size)) | (context->Message_Block_Index == SHA512_Message_Block_Size)) | |||
| SHA384_512ProcessMessageBlock(context); | SHA384_512ProcessMessageBlock(context); | |||
| message_array++; | message_array++; | |||
| } | } | |||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| * SHA512FinalBits | * SHA512FinalBits | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Description: | * Description: | |||
| * This function will add in any final bits of the message. | * This function will add in any final bits of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA512FinalBits(SHA512Context *context, | int SHA512FinalBits(SHA512Context *context, | |||
| uint8_t message_bits, unsigned int length) | uint8_t message_bits, unsigned int length) | |||
| { | { | |||
| uint8_t masks[8] = { | static uint8_t masks[8] = { | |||
| /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | |||
| /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0, | |||
| /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8, | |||
| /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE | |||
| }; | }; | |||
| uint8_t markbit[8] = { | static uint8_t markbit[8] = { | |||
| /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40, | |||
| /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10, | |||
| /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04, | |||
| /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01 | |||
| }; | }; | |||
| if (!length) | if (!context) return shaNull; | |||
| return shaSuccess; | if (!length) return shaSuccess; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (!context) | if (context->Computed) return context->Corrupted = shaStateError; | |||
| return shaNull; | if (length >= 8) return context->Corrupted = shaBadParam; | |||
| if (context->Computed) | ||||
| return context->Corrupted = shaStateError; | ||||
| if ((length >= 8) || (length == 0)) | ||||
| return context->Corrupted = shaBadParam; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| SHA384_512AddLength(context, length); | SHA384_512AddLength(context, length); | |||
| SHA384_512Finalize(context, (uint8_t) | SHA384_512Finalize(context, (uint8_t) | |||
| ((message_bits & masks[length]) | markbit[length])); | ((message_bits & masks[length]) | markbit[length])); | |||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| * SHA384_512Finalize | * SHA512Result | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function finishes off the digest calculations. | ||||
| * | ||||
| * Parameters: | ||||
| * context: [in/out] | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| * The SHA context to update | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the digest before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * sha Error Code. | ||||
| * | ||||
| */ | ||||
| static void SHA384_512Finalize(SHA512Context *context, | ||||
| uint8_t Pad_Byte) | ||||
| { | ||||
| int_least16_t i; | ||||
| SHA384_512PadMessage(context, Pad_Byte); | ||||
| /* message may be sensitive, clear it out */ | ||||
| for (i = 0; i < SHA512_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| #ifdef USE_32BIT_ONLY /* and clear length */ | ||||
| context->Length[0] = context->Length[1] = 0; | ||||
| context->Length[2] = context->Length[3] = 0; | ||||
| #else /* !USE_32BIT_ONLY */ | ||||
| context->Length_Low = 0; | ||||
| context->Length_High = 0; | ||||
| #endif /* USE_32BIT_ONLY */ | ||||
| context->Computed = 1; | ||||
| } | ||||
| /* | ||||
| * SHA512Result | ||||
| * | ||||
| * Description: | ||||
| * This function will return the 512-bit message digest | * This function will return the 512-bit message digest | |||
| * into the Message_Digest array provided by the caller. | * into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 63. | * the last octet of hash in the element with index 63. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA512Result(SHA512Context *context, | int SHA512Result(SHA512Context *context, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| uint8_t Message_Digest[SHA512HashSize]) | uint8_t Message_Digest[SHA512HashSize]) | |||
| { | { | |||
| return SHA384_512ResultN(context, Message_Digest, SHA512HashSize); | return SHA384_512ResultN(context, Message_Digest, SHA512HashSize); | |||
| } | } | |||
| /* | /* | |||
| * SHA384_512PadMessage | * SHA384_512Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * According to the standard, the message must be padded to the next | * This helper function will initialize the SHA512Context in | |||
| * even multiple of 1024 bits. The first padding bit must be a '1'. | * preparation for computing a new SHA384 or SHA512 message | |||
| * The last 128 bits represent the length of the original message. | * digest. | |||
| * All bits in between should be 0. This helper function will | ||||
| * pad the message according to those rules by filling the | ||||
| * Message_Block array accordingly. When it returns, it can be | ||||
| * assumed that the message digest has been computed. | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to pad | * The context to reset. | |||
| * Pad_Byte: [in] | * H0[ ]: [in] | |||
| * The last byte to add to the digest before the 0-padding | * The initial hash value array to use. | |||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| static void SHA384_512PadMessage(SHA512Context *context, | #ifdef USE_32BIT_ONLY | |||
| uint8_t Pad_Byte) | static int SHA384_512Reset(SHA512Context *context, | |||
| uint32_t H0[SHA512HashSize/4]) | ||||
| #else /* !USE_32BIT_ONLY */ | ||||
| static int SHA384_512Reset(SHA512Context *context, | ||||
| uint64_t H0[SHA512HashSize/8]) | ||||
| #endif /* USE_32BIT_ONLY */ | ||||
| { | { | |||
| /* | int i; | |||
| * Check to see if the current message block is too small to hold | if (!context) return shaNull; | |||
| * the initial padding bits and length. If so, we will pad the | ||||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA512_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| SHA384_512ProcessMessageBlock(context); | ||||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < (SHA512_Message_Block_Size-16)) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| /* | context->Message_Block_Index = 0; | |||
| * Store the message length as the last 16 octets | ||||
| */ | ||||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| context->Message_Block[112] = (uint8_t)(context->Length[0] >> 24); | context->Length[0] = context->Length[1] = | |||
| context->Message_Block[113] = (uint8_t)(context->Length[0] >> 16); | context->Length[2] = context->Length[3] = 0; | |||
| context->Message_Block[114] = (uint8_t)(context->Length[0] >> 8); | ||||
| context->Message_Block[115] = (uint8_t)(context->Length[0]); | ||||
| context->Message_Block[116] = (uint8_t)(context->Length[1] >> 24); | ||||
| context->Message_Block[117] = (uint8_t)(context->Length[1] >> 16); | ||||
| context->Message_Block[118] = (uint8_t)(context->Length[1] >> 8); | ||||
| context->Message_Block[119] = (uint8_t)(context->Length[1]); | ||||
| context->Message_Block[120] = (uint8_t)(context->Length[2] >> 24); | for (i = 0; i < SHA512HashSize/4; i++) | |||
| context->Message_Block[121] = (uint8_t)(context->Length[2] >> 16); | context->Intermediate_Hash[i] = H0[i]; | |||
| context->Message_Block[122] = (uint8_t)(context->Length[2] >> 8); | ||||
| context->Message_Block[123] = (uint8_t)(context->Length[2]); | ||||
| context->Message_Block[124] = (uint8_t)(context->Length[3] >> 24); | ||||
| context->Message_Block[125] = (uint8_t)(context->Length[3] >> 16); | ||||
| context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8); | ||||
| context->Message_Block[127] = (uint8_t)(context->Length[3]); | ||||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| context->Message_Block[112] = (uint8_t)(context->Length_High >> 56); | context->Length_High = context->Length_Low = 0; | |||
| context->Message_Block[113] = (uint8_t)(context->Length_High >> 48); | ||||
| context->Message_Block[114] = (uint8_t)(context->Length_High >> 40); | ||||
| context->Message_Block[115] = (uint8_t)(context->Length_High >> 32); | ||||
| context->Message_Block[116] = (uint8_t)(context->Length_High >> 24); | ||||
| context->Message_Block[117] = (uint8_t)(context->Length_High >> 16); | ||||
| context->Message_Block[118] = (uint8_t)(context->Length_High >> 8); | ||||
| context->Message_Block[119] = (uint8_t)(context->Length_High); | ||||
| context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56); | for (i = 0; i < SHA512HashSize/8; i++) | |||
| context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48); | context->Intermediate_Hash[i] = H0[i]; | |||
| context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40); | ||||
| context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32); | ||||
| context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24); | ||||
| context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16); | ||||
| context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8); | ||||
| context->Message_Block[127] = (uint8_t)(context->Length_Low); | ||||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| SHA384_512ProcessMessageBlock(context); | context->Computed = 0; | |||
| context->Corrupted = shaSuccess; | ||||
| return shaSuccess; | ||||
| } | } | |||
| /* | /* | |||
| * SHA384_512ProcessMessageBlock | * SHA384_512ProcessMessageBlock | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will process the next 1024 bits of the | * This helper function will process the next 1024 bits of the | |||
| * message stored in the Message_Block array. | * message stored in the Message_Block array. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| * | * | |||
| * Comments: | * Comments: | |||
| * Many of the variable names in this code, especially the | * Many of the variable names in this code, especially the | |||
| * single character names, were used because those were the | * single character names, were used because those were the | |||
| * names used in the publication. | * names used in the Secure Hash Standard. | |||
| * | * | |||
| * | * | |||
| */ | */ | |||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context) | static void SHA384_512ProcessMessageBlock(SHA512Context *context) | |||
| { | { | |||
| /* Constants defined in FIPS-180-2, section 4.2.3 */ | ||||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| /* Constants defined in FIPS 180-3, section 4.2.3 */ | ||||
| static const uint32_t K[80*2] = { | static const uint32_t K[80*2] = { | |||
| 0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF, | 0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF, | |||
| 0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538, | 0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538, | |||
| 0x59F111F1, 0xB605D019, 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5, | 0x59F111F1, 0xB605D019, 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0xDA6D8118, 0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE, | 0xDA6D8118, 0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE, | |||
| 0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, 0x72BE5D74, | 0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, 0x72BE5D74, | |||
| 0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235, | 0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235, | |||
| 0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786, | 0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786, | |||
| 0x384F25E3, 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65, | 0x384F25E3, 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65, | |||
| 0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC, | 0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC, | |||
| 0xBD41FBD4, 0x76F988DA, 0x831153B5, 0x983E5152, 0xEE66DFAB, | 0xBD41FBD4, 0x76F988DA, 0x831153B5, 0x983E5152, 0xEE66DFAB, | |||
| 0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, 0xBF597FC7, | 0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, 0xBF597FC7, | |||
| 0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725, | 0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725, | |||
| 0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85, | 0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85, | |||
| skipping to change at page 66, line 4 ¶ | skipping to change at page 63, line 34 ¶ | |||
| 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, | 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, | |||
| 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, 0x5B9CCA4F, 0x7763E373, | 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, 0x5B9CCA4F, 0x7763E373, | |||
| 0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, 0x78A5636F, | 0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, 0x78A5636F, | |||
| 0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC, | 0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC, | |||
| 0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7, | 0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7, | |||
| 0xB2C67915, 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C, | 0xB2C67915, 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C, | |||
| 0xD186B8C7, 0x21C0C207, 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F, | 0xD186B8C7, 0x21C0C207, 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F, | |||
| 0xEE6ED178, 0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6, | 0xEE6ED178, 0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6, | |||
| 0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, 0x28DB77F5, | 0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, 0x28DB77F5, | |||
| 0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC, | 0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, | 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, | |||
| 0xFC657E2A, 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817 | 0xFC657E2A, 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817 | |||
| }; | }; | |||
| int t, t2, t8; /* Loop counter */ | int t, t2, t8; /* Loop counter */ | |||
| uint32_t temp1[2], temp2[2], /* Temporary word values */ | uint32_t temp1[2], temp2[2], /* Temporary word values */ | |||
| temp3[2], temp4[2], temp5[2]; | temp3[2], temp4[2], temp5[2]; | |||
| uint32_t W[2*80]; /* Word sequence */ | uint32_t W[2*80]; /* Word sequence */ | |||
| uint32_t A[2], B[2], C[2], D[2], /* Word buffers */ | uint32_t A[2], B[2], C[2], D[2], /* Word buffers */ | |||
| E[2], F[2], G[2], H[2]; | E[2], F[2], G[2], H[2]; | |||
| skipping to change at page 66, line 30 ¶ | skipping to change at page 64, line 4 ¶ | |||
| ((((uint32_t)context->Message_Block[t8 + 1])) << 16) | | ((((uint32_t)context->Message_Block[t8 + 1])) << 16) | | |||
| ((((uint32_t)context->Message_Block[t8 + 2])) << 8) | | ((((uint32_t)context->Message_Block[t8 + 2])) << 8) | | |||
| ((((uint32_t)context->Message_Block[t8 + 3]))); | ((((uint32_t)context->Message_Block[t8 + 3]))); | |||
| W[t2++] = ((((uint32_t)context->Message_Block[t8 + 4])) << 24) | | W[t2++] = ((((uint32_t)context->Message_Block[t8 + 4])) << 24) | | |||
| ((((uint32_t)context->Message_Block[t8 + 5])) << 16) | | ((((uint32_t)context->Message_Block[t8 + 5])) << 16) | | |||
| ((((uint32_t)context->Message_Block[t8 + 6])) << 8) | | ((((uint32_t)context->Message_Block[t8 + 6])) << 8) | | |||
| ((((uint32_t)context->Message_Block[t8 + 7]))); | ((((uint32_t)context->Message_Block[t8 + 7]))); | |||
| } | } | |||
| for (t = 16; t < 80; t++, t2 += 2) { | for (t = 16; t < 80; t++, t2 += 2) { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* W[t] = SHA512_sigma1(W[t-2]) + W[t-7] + | /* W[t] = SHA512_sigma1(W[t-2]) + W[t-7] + | |||
| SHA512_sigma0(W[t-15]) + W[t-16]; */ | SHA512_sigma0(W[t-15]) + W[t-16]; */ | |||
| uint32_t *Wt2 = &W[t2-2*2]; | uint32_t *Wt2 = &W[t2-2*2]; | |||
| uint32_t *Wt7 = &W[t2-7*2]; | uint32_t *Wt7 = &W[t2-7*2]; | |||
| uint32_t *Wt15 = &W[t2-15*2]; | uint32_t *Wt15 = &W[t2-15*2]; | |||
| uint32_t *Wt16 = &W[t2-16*2]; | uint32_t *Wt16 = &W[t2-16*2]; | |||
| SHA512_sigma1(Wt2, temp1); | SHA512_sigma1(Wt2, temp1); | |||
| SHA512_ADD(temp1, Wt7, temp2); | SHA512_ADD(temp1, Wt7, temp2); | |||
| SHA512_sigma0(Wt15, temp1); | SHA512_sigma0(Wt15, temp1); | |||
| SHA512_ADD(temp1, Wt16, temp3); | SHA512_ADD(temp1, Wt16, temp3); | |||
| skipping to change at page 67, line 4 ¶ | skipping to change at page 64, line 34 ¶ | |||
| C[0] = context->Intermediate_Hash[4]; | C[0] = context->Intermediate_Hash[4]; | |||
| C[1] = context->Intermediate_Hash[5]; | C[1] = context->Intermediate_Hash[5]; | |||
| D[0] = context->Intermediate_Hash[6]; | D[0] = context->Intermediate_Hash[6]; | |||
| D[1] = context->Intermediate_Hash[7]; | D[1] = context->Intermediate_Hash[7]; | |||
| E[0] = context->Intermediate_Hash[8]; | E[0] = context->Intermediate_Hash[8]; | |||
| E[1] = context->Intermediate_Hash[9]; | E[1] = context->Intermediate_Hash[9]; | |||
| F[0] = context->Intermediate_Hash[10]; | F[0] = context->Intermediate_Hash[10]; | |||
| F[1] = context->Intermediate_Hash[11]; | F[1] = context->Intermediate_Hash[11]; | |||
| G[0] = context->Intermediate_Hash[12]; | G[0] = context->Intermediate_Hash[12]; | |||
| G[1] = context->Intermediate_Hash[13]; | G[1] = context->Intermediate_Hash[13]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| H[0] = context->Intermediate_Hash[14]; | H[0] = context->Intermediate_Hash[14]; | |||
| H[1] = context->Intermediate_Hash[15]; | H[1] = context->Intermediate_Hash[15]; | |||
| for (t = t2 = 0; t < 80; t++, t2 += 2) { | for (t = t2 = 0; t < 80; t++, t2 += 2) { | |||
| /* | /* | |||
| * temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | * temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | |||
| */ | */ | |||
| SHA512_SIGMA1(E,temp1); | SHA512_SIGMA1(E,temp1); | |||
| SHA512_ADD(H, temp1, temp2); | SHA512_ADD(H, temp1, temp2); | |||
| SHA_Ch(E,F,G,temp3); | SHA_Ch(E,F,G,temp3); | |||
| skipping to change at page 67, line 30 ¶ | skipping to change at page 65, line 4 ¶ | |||
| /* | /* | |||
| * temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); | * temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); | |||
| */ | */ | |||
| SHA512_SIGMA0(A,temp3); | SHA512_SIGMA0(A,temp3); | |||
| SHA_Maj(A,B,C,temp4); | SHA_Maj(A,B,C,temp4); | |||
| SHA512_ADD(temp3, temp4, temp2); | SHA512_ADD(temp3, temp4, temp2); | |||
| H[0] = G[0]; H[1] = G[1]; | H[0] = G[0]; H[1] = G[1]; | |||
| G[0] = F[0]; G[1] = F[1]; | G[0] = F[0]; G[1] = F[1]; | |||
| F[0] = E[0]; F[1] = E[1]; | F[0] = E[0]; F[1] = E[1]; | |||
| SHA512_ADD(D, temp1, E); | SHA512_ADD(D, temp1, E); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| D[0] = C[0]; D[1] = C[1]; | D[0] = C[0]; D[1] = C[1]; | |||
| C[0] = B[0]; C[1] = B[1]; | C[0] = B[0]; C[1] = B[1]; | |||
| B[0] = A[0]; B[1] = A[1]; | B[0] = A[0]; B[1] = A[1]; | |||
| SHA512_ADD(temp1, temp2, A); | SHA512_ADD(temp1, temp2, A); | |||
| } | } | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[0], A); | SHA512_ADDTO2(&context->Intermediate_Hash[0], A); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[2], B); | SHA512_ADDTO2(&context->Intermediate_Hash[2], B); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[4], C); | SHA512_ADDTO2(&context->Intermediate_Hash[4], C); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[6], D); | SHA512_ADDTO2(&context->Intermediate_Hash[6], D); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[8], E); | SHA512_ADDTO2(&context->Intermediate_Hash[8], E); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[10], F); | SHA512_ADDTO2(&context->Intermediate_Hash[10], F); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[12], G); | SHA512_ADDTO2(&context->Intermediate_Hash[12], G); | |||
| SHA512_ADDTO2(&context->Intermediate_Hash[14], H); | SHA512_ADDTO2(&context->Intermediate_Hash[14], H); | |||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| /* Constants defined in FIPS 180-3, section 4.2.3 */ | ||||
| static const uint64_t K[80] = { | static const uint64_t K[80] = { | |||
| 0x428A2F98D728AE22ll, 0x7137449123EF65CDll, 0xB5C0FBCFEC4D3B2Fll, | 0x428A2F98D728AE22ll, 0x7137449123EF65CDll, 0xB5C0FBCFEC4D3B2Fll, | |||
| 0xE9B5DBA58189DBBCll, 0x3956C25BF348B538ll, 0x59F111F1B605D019ll, | 0xE9B5DBA58189DBBCll, 0x3956C25BF348B538ll, 0x59F111F1B605D019ll, | |||
| 0x923F82A4AF194F9Bll, 0xAB1C5ED5DA6D8118ll, 0xD807AA98A3030242ll, | 0x923F82A4AF194F9Bll, 0xAB1C5ED5DA6D8118ll, 0xD807AA98A3030242ll, | |||
| 0x12835B0145706FBEll, 0x243185BE4EE4B28Cll, 0x550C7DC3D5FFB4E2ll, | 0x12835B0145706FBEll, 0x243185BE4EE4B28Cll, 0x550C7DC3D5FFB4E2ll, | |||
| 0x72BE5D74F27B896Fll, 0x80DEB1FE3B1696B1ll, 0x9BDC06A725C71235ll, | 0x72BE5D74F27B896Fll, 0x80DEB1FE3B1696B1ll, 0x9BDC06A725C71235ll, | |||
| 0xC19BF174CF692694ll, 0xE49B69C19EF14AD2ll, 0xEFBE4786384F25E3ll, | 0xC19BF174CF692694ll, 0xE49B69C19EF14AD2ll, 0xEFBE4786384F25E3ll, | |||
| 0x0FC19DC68B8CD5B5ll, 0x240CA1CC77AC9C65ll, 0x2DE92C6F592B0275ll, | 0x0FC19DC68B8CD5B5ll, 0x240CA1CC77AC9C65ll, 0x2DE92C6F592B0275ll, | |||
| 0x4A7484AA6EA6E483ll, 0x5CB0A9DCBD41FBD4ll, 0x76F988DA831153B5ll, | 0x4A7484AA6EA6E483ll, 0x5CB0A9DCBD41FBD4ll, 0x76F988DA831153B5ll, | |||
| 0x983E5152EE66DFABll, 0xA831C66D2DB43210ll, 0xB00327C898FB213Fll, | 0x983E5152EE66DFABll, 0xA831C66D2DB43210ll, 0xB00327C898FB213Fll, | |||
| 0xBF597FC7BEEF0EE4ll, 0xC6E00BF33DA88FC2ll, 0xD5A79147930AA725ll, | 0xBF597FC7BEEF0EE4ll, 0xC6E00BF33DA88FC2ll, 0xD5A79147930AA725ll, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0x06CA6351E003826Fll, 0x142929670A0E6E70ll, 0x27B70A8546D22FFCll, | 0x06CA6351E003826Fll, 0x142929670A0E6E70ll, 0x27B70A8546D22FFCll, | |||
| 0x2E1B21385C26C926ll, 0x4D2C6DFC5AC42AEDll, 0x53380D139D95B3DFll, | 0x2E1B21385C26C926ll, 0x4D2C6DFC5AC42AEDll, 0x53380D139D95B3DFll, | |||
| 0x650A73548BAF63DEll, 0x766A0ABB3C77B2A8ll, 0x81C2C92E47EDAEE6ll, | 0x650A73548BAF63DEll, 0x766A0ABB3C77B2A8ll, 0x81C2C92E47EDAEE6ll, | |||
| 0x92722C851482353Bll, 0xA2BFE8A14CF10364ll, 0xA81A664BBC423001ll, | 0x92722C851482353Bll, 0xA2BFE8A14CF10364ll, 0xA81A664BBC423001ll, | |||
| 0xC24B8B70D0F89791ll, 0xC76C51A30654BE30ll, 0xD192E819D6EF5218ll, | 0xC24B8B70D0F89791ll, 0xC76C51A30654BE30ll, 0xD192E819D6EF5218ll, | |||
| 0xD69906245565A910ll, 0xF40E35855771202All, 0x106AA07032BBD1B8ll, | 0xD69906245565A910ll, 0xF40E35855771202All, 0x106AA07032BBD1B8ll, | |||
| 0x19A4C116B8D2D0C8ll, 0x1E376C085141AB53ll, 0x2748774CDF8EEB99ll, | 0x19A4C116B8D2D0C8ll, 0x1E376C085141AB53ll, 0x2748774CDF8EEB99ll, | |||
| 0x34B0BCB5E19B48A8ll, 0x391C0CB3C5C95A63ll, 0x4ED8AA4AE3418ACBll, | 0x34B0BCB5E19B48A8ll, 0x391C0CB3C5C95A63ll, 0x4ED8AA4AE3418ACBll, | |||
| 0x5B9CCA4F7763E373ll, 0x682E6FF3D6B2B8A3ll, 0x748F82EE5DEFB2FCll, | 0x5B9CCA4F7763E373ll, 0x682E6FF3D6B2B8A3ll, 0x748F82EE5DEFB2FCll, | |||
| 0x78A5636F43172F60ll, 0x84C87814A1F0AB72ll, 0x8CC702081A6439ECll, | 0x78A5636F43172F60ll, 0x84C87814A1F0AB72ll, 0x8CC702081A6439ECll, | |||
| skipping to change at page 68, line 30 ¶ | skipping to change at page 66, line 5 ¶ | |||
| 0x0A637DC5A2C898A6ll, 0x113F9804BEF90DAEll, 0x1B710B35131C471Bll, | 0x0A637DC5A2C898A6ll, 0x113F9804BEF90DAEll, 0x1B710B35131C471Bll, | |||
| 0x28DB77F523047D84ll, 0x32CAAB7B40C72493ll, 0x3C9EBE0A15C9BEBCll, | 0x28DB77F523047D84ll, 0x32CAAB7B40C72493ll, 0x3C9EBE0A15C9BEBCll, | |||
| 0x431D67C49C100D4Cll, 0x4CC5D4BECB3E42B6ll, 0x597F299CFC657E2All, | 0x431D67C49C100D4Cll, 0x4CC5D4BECB3E42B6ll, 0x597F299CFC657E2All, | |||
| 0x5FCB6FAB3AD6FAECll, 0x6C44198C4A475817ll | 0x5FCB6FAB3AD6FAECll, 0x6C44198C4A475817ll | |||
| }; | }; | |||
| int t, t8; /* Loop counter */ | int t, t8; /* Loop counter */ | |||
| uint64_t temp1, temp2; /* Temporary word value */ | uint64_t temp1, temp2; /* Temporary word value */ | |||
| uint64_t W[80]; /* Word sequence */ | uint64_t W[80]; /* Word sequence */ | |||
| uint64_t A, B, C, D, E, F, G, H; /* Word buffers */ | uint64_t A, B, C, D, E, F, G, H; /* Word buffers */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Initialize the first 16 words in the array W | * Initialize the first 16 words in the array W | |||
| */ | */ | |||
| for (t = t8 = 0; t < 16; t++, t8 += 8) | for (t = t8 = 0; t < 16; t++, t8 += 8) | |||
| W[t] = ((uint64_t)(context->Message_Block[t8 ]) << 56) | | W[t] = ((uint64_t)(context->Message_Block[t8 ]) << 56) | | |||
| ((uint64_t)(context->Message_Block[t8 + 1]) << 48) | | ((uint64_t)(context->Message_Block[t8 + 1]) << 48) | | |||
| ((uint64_t)(context->Message_Block[t8 + 2]) << 40) | | ((uint64_t)(context->Message_Block[t8 + 2]) << 40) | | |||
| ((uint64_t)(context->Message_Block[t8 + 3]) << 32) | | ((uint64_t)(context->Message_Block[t8 + 3]) << 32) | | |||
| ((uint64_t)(context->Message_Block[t8 + 4]) << 24) | | ((uint64_t)(context->Message_Block[t8 + 4]) << 24) | | |||
| ((uint64_t)(context->Message_Block[t8 + 5]) << 16) | | ((uint64_t)(context->Message_Block[t8 + 5]) << 16) | | |||
| skipping to change at page 69, line 4 ¶ | skipping to change at page 66, line 34 ¶ | |||
| A = context->Intermediate_Hash[0]; | A = context->Intermediate_Hash[0]; | |||
| B = context->Intermediate_Hash[1]; | B = context->Intermediate_Hash[1]; | |||
| C = context->Intermediate_Hash[2]; | C = context->Intermediate_Hash[2]; | |||
| D = context->Intermediate_Hash[3]; | D = context->Intermediate_Hash[3]; | |||
| E = context->Intermediate_Hash[4]; | E = context->Intermediate_Hash[4]; | |||
| F = context->Intermediate_Hash[5]; | F = context->Intermediate_Hash[5]; | |||
| G = context->Intermediate_Hash[6]; | G = context->Intermediate_Hash[6]; | |||
| H = context->Intermediate_Hash[7]; | H = context->Intermediate_Hash[7]; | |||
| for (t = 0; t < 80; t++) { | for (t = 0; t < 80; t++) { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t]; | |||
| temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); | temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C); | |||
| H = G; | H = G; | |||
| G = F; | G = F; | |||
| F = E; | F = E; | |||
| E = D + temp1; | E = D + temp1; | |||
| D = C; | D = C; | |||
| C = B; | C = B; | |||
| B = A; | B = A; | |||
| A = temp1 + temp2; | A = temp1 + temp2; | |||
| skipping to change at page 69, line 30 ¶ | skipping to change at page 67, line 4 ¶ | |||
| context->Intermediate_Hash[1] += B; | context->Intermediate_Hash[1] += B; | |||
| context->Intermediate_Hash[2] += C; | context->Intermediate_Hash[2] += C; | |||
| context->Intermediate_Hash[3] += D; | context->Intermediate_Hash[3] += D; | |||
| context->Intermediate_Hash[4] += E; | context->Intermediate_Hash[4] += E; | |||
| context->Intermediate_Hash[5] += F; | context->Intermediate_Hash[5] += F; | |||
| context->Intermediate_Hash[6] += G; | context->Intermediate_Hash[6] += G; | |||
| context->Intermediate_Hash[7] += H; | context->Intermediate_Hash[7] += H; | |||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| /* | /* | |||
| * SHA384_512Reset | * SHA384_512Finalize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will initialize the SHA512Context in | * This helper function finishes off the digest calculations. | |||
| * preparation for computing a new SHA384 or SHA512 message | ||||
| * digest. | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The SHA context to update | |||
| * H0 | * Pad_Byte: [in] | |||
| * The initial hash value to use. | * The last byte to add to the message block before the 0-padding | |||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| #ifdef USE_32BIT_ONLY | static void SHA384_512Finalize(SHA512Context *context, | |||
| static int SHA384_512Reset(SHA512Context *context, | uint8_t Pad_Byte) | |||
| uint32_t H0[SHA512HashSize/4]) | { | |||
| int_least16_t i; | ||||
| SHA384_512PadMessage(context, Pad_Byte); | ||||
| /* message may be sensitive, clear it out */ | ||||
| for (i = 0; i < SHA512_Message_Block_Size; ++i) | ||||
| context->Message_Block[i] = 0; | ||||
| #ifdef USE_32BIT_ONLY /* and clear length */ | ||||
| context->Length[0] = context->Length[1] = 0; | ||||
| context->Length[2] = context->Length[3] = 0; | ||||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| static int SHA384_512Reset(SHA512Context *context, | context->Length_High = context->Length_Low = 0; | |||
| uint64_t H0[SHA512HashSize/8]) | ||||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| context->Computed = 1; | ||||
| } | ||||
| /* | ||||
| * SHA384_512PadMessage | ||||
| * | ||||
| * Description: | ||||
| * According to the standard, the message must be padded to the next | ||||
| * even multiple of 1024 bits. The first padding bit must be a '1'. | ||||
| * The last 128 bits represent the length of the original message. | ||||
| * All bits in between should be 0. This helper function will | ||||
| * pad the message according to those rules by filling the | ||||
| * Message_Block array accordingly. When it returns, it can be | ||||
| * assumed that the message digest has been computed. | ||||
| * | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| * Parameters: | ||||
| * context: [in/out] | ||||
| * The context to pad | ||||
| * Pad_Byte: [in] | ||||
| * The last byte to add to the message block before the 0-padding | ||||
| * and length. This will contain the last bits of the message | ||||
| * followed by another single bit. If the message was an | ||||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | ||||
| * | ||||
| * Returns: | ||||
| * Nothing. | ||||
| * | ||||
| */ | ||||
| static void SHA384_512PadMessage(SHA512Context *context, | ||||
| uint8_t Pad_Byte) | ||||
| { | { | |||
| int i; | /* | |||
| if (!context) | * Check to see if the current message block is too small to hold | |||
| return shaNull; | * the initial padding bits and length. If so, we will pad the | |||
| * block, process it, and then continue padding into a second | ||||
| * block. | ||||
| */ | ||||
| if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) { | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < SHA512_Message_Block_Size) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| context->Message_Block_Index = 0; | SHA384_512ProcessMessageBlock(context); | |||
| } else | ||||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | ||||
| while (context->Message_Block_Index < (SHA512_Message_Block_Size-16)) | ||||
| context->Message_Block[context->Message_Block_Index++] = 0; | ||||
| /* | ||||
| * Store the message length as the last 16 octets | ||||
| */ | ||||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| context->Length[0] = context->Length[1] = | context->Message_Block[112] = (uint8_t)(context->Length[0] >> 24); | |||
| context->Length[2] = context->Length[3] = 0; | context->Message_Block[113] = (uint8_t)(context->Length[0] >> 16); | |||
| context->Message_Block[114] = (uint8_t)(context->Length[0] >> 8); | ||||
| context->Message_Block[115] = (uint8_t)(context->Length[0]); | ||||
| context->Message_Block[116] = (uint8_t)(context->Length[1] >> 24); | ||||
| context->Message_Block[117] = (uint8_t)(context->Length[1] >> 16); | ||||
| context->Message_Block[118] = (uint8_t)(context->Length[1] >> 8); | ||||
| context->Message_Block[119] = (uint8_t)(context->Length[1]); | ||||
| for (i = 0; i < SHA512HashSize/4; i++) | context->Message_Block[120] = (uint8_t)(context->Length[2] >> 24); | |||
| context->Intermediate_Hash[i] = H0[i]; | context->Message_Block[121] = (uint8_t)(context->Length[2] >> 16); | |||
| context->Message_Block[122] = (uint8_t)(context->Length[2] >> 8); | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Message_Block[123] = (uint8_t)(context->Length[2]); | ||||
| context->Message_Block[124] = (uint8_t)(context->Length[3] >> 24); | ||||
| context->Message_Block[125] = (uint8_t)(context->Length[3] >> 16); | ||||
| context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8); | ||||
| context->Message_Block[127] = (uint8_t)(context->Length[3]); | ||||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| context->Length_High = context->Length_Low = 0; | context->Message_Block[112] = (uint8_t)(context->Length_High >> 56); | |||
| context->Message_Block[113] = (uint8_t)(context->Length_High >> 48); | ||||
| context->Message_Block[114] = (uint8_t)(context->Length_High >> 40); | ||||
| context->Message_Block[115] = (uint8_t)(context->Length_High >> 32); | ||||
| context->Message_Block[116] = (uint8_t)(context->Length_High >> 24); | ||||
| context->Message_Block[117] = (uint8_t)(context->Length_High >> 16); | ||||
| context->Message_Block[118] = (uint8_t)(context->Length_High >> 8); | ||||
| context->Message_Block[119] = (uint8_t)(context->Length_High); | ||||
| for (i = 0; i < SHA512HashSize/8; i++) | context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56); | |||
| context->Intermediate_Hash[i] = H0[i]; | context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48); | |||
| context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40); | ||||
| context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32); | ||||
| context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24); | ||||
| context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16); | ||||
| context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8); | ||||
| context->Message_Block[127] = (uint8_t)(context->Length_Low); | ||||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| context->Computed = 0; | SHA384_512ProcessMessageBlock(context); | |||
| context->Corrupted = 0; | ||||
| return shaSuccess; | ||||
| } | } | |||
| /* | /* | |||
| * SHA384_512ResultN | * SHA384_512ResultN | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will return the 384-bit or 512-bit message | * This helper function will return the 384-bit or 512-bit message | |||
| * digest into the Message_Digest array provided by the caller. | * digest into the Message_Digest array provided by the caller. | |||
| * NOTE: | * NOTE: | |||
| * The first octet of hash is stored in the element with index 0, | * The first octet of hash is stored in the element with index 0, | |||
| * the last octet of hash in the element with index 47/63. | * the last octet of hash in the element with index 47/63. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the SHA hash. | * The context to use to calculate the SHA hash. | |||
| * Message_Digest: [out] | * Message_Digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * HashSize: [in] | * HashSize: [in] | |||
| * The size of the hash, either 48 or 64. | * The size of the hash, either 48 or 64. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| static int SHA384_512ResultN(SHA512Context *context, | ||||
| uint8_t Message_Digest[ ], int HashSize) | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| static int SHA384_512ResultN(SHA512Context *context, | ||||
| uint8_t Message_Digest[ ], int HashSize) | ||||
| { | { | |||
| int i; | int i; | |||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| int i2; | int i2; | |||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| if (!context || !Message_Digest) | if (!context) return shaNull; | |||
| return shaNull; | if (!Message_Digest) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | ||||
| if (context->Corrupted) | ||||
| return context->Corrupted; | ||||
| if (!context->Computed) | if (!context->Computed) | |||
| SHA384_512Finalize(context, 0x80); | SHA384_512Finalize(context, 0x80); | |||
| #ifdef USE_32BIT_ONLY | #ifdef USE_32BIT_ONLY | |||
| for (i = i2 = 0; i < HashSize; ) { | for (i = i2 = 0; i < HashSize; ) { | |||
| Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>24); | Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>24); | |||
| Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>16); | Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>16); | |||
| Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>8); | Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>8); | |||
| Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2++]); | Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2++]); | |||
| skipping to change at page 72, line 28 ¶ | skipping to change at page 71, line 28 ¶ | |||
| * The context to reset. | * The context to reset. | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * Selects which SHA reset to call | * Selects which SHA reset to call | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int USHAReset(USHAContext *context, enum SHAversion whichSha) | int USHAReset(USHAContext *context, enum SHAversion whichSha) | |||
| { | { | |||
| if (context) { | if (!context) return shaNull; | |||
| context->whichSha = whichSha; | context->whichSha = whichSha; | |||
| switch (whichSha) { | switch (whichSha) { | |||
| case SHA1: return SHA1Reset((SHA1Context*)&context->ctx); | case SHA1: return SHA1Reset((SHA1Context*)&context->ctx); | |||
| case SHA224: return SHA224Reset((SHA224Context*)&context->ctx); | case SHA224: return SHA224Reset((SHA224Context*)&context->ctx); | |||
| case SHA256: return SHA256Reset((SHA256Context*)&context->ctx); | case SHA256: return SHA256Reset((SHA256Context*)&context->ctx); | |||
| case SHA384: return SHA384Reset((SHA384Context*)&context->ctx); | case SHA384: return SHA384Reset((SHA384Context*)&context->ctx); | |||
| case SHA512: return SHA512Reset((SHA512Context*)&context->ctx); | case SHA512: return SHA512Reset((SHA512Context*)&context->ctx); | |||
| default: return shaBadParam; | default: return shaBadParam; | |||
| } | ||||
| } else { | ||||
| return shaNull; | ||||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * USHAInput | * USHAInput | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. | * of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_array: [in] | * message_array: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * length: [in] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * The length of the message in message_array | * The length of the message in message_array | |||
| * | * | |||
| * Returns: | * Returns: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int USHAInput(USHAContext *context, | int USHAInput(USHAContext *context, | |||
| const uint8_t *bytes, unsigned int bytecount) | const uint8_t *bytes, unsigned int bytecount) | |||
| { | { | |||
| if (context) { | if (!context) return shaNull; | |||
| switch (context->whichSha) { | switch (context->whichSha) { | |||
| case SHA1: | case SHA1: | |||
| return SHA1Input((SHA1Context*)&context->ctx, bytes, | return SHA1Input((SHA1Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| case SHA224: | case SHA224: | |||
| return SHA224Input((SHA224Context*)&context->ctx, bytes, | return SHA224Input((SHA224Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| case SHA256: | case SHA256: | |||
| return SHA256Input((SHA256Context*)&context->ctx, bytes, | return SHA256Input((SHA256Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| case SHA384: | case SHA384: | |||
| return SHA384Input((SHA384Context*)&context->ctx, bytes, | return SHA384Input((SHA384Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| case SHA512: | case SHA512: | |||
| return SHA512Input((SHA512Context*)&context->ctx, bytes, | return SHA512Input((SHA512Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| default: return shaBadParam; | default: return shaBadParam; | |||
| } | ||||
| } else { | ||||
| return shaNull; | ||||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * USHAFinalBits | * USHAFinalBits | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will add in any final bits of the message. | * This function will add in any final bits of the message. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int USHAFinalBits(USHAContext *context, | int USHAFinalBits(USHAContext *context, | |||
| uint8_t bits, unsigned int bit_count) | uint8_t bits, unsigned int bit_count) | |||
| { | { | |||
| if (context) { | if (!context) return shaNull; | |||
| switch (context->whichSha) { | ||||
| case SHA1: | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| return SHA1FinalBits((SHA1Context*)&context->ctx, bits, | ||||
| bit_count); | switch (context->whichSha) { | |||
| case SHA224: | case SHA1: | |||
| return SHA224FinalBits((SHA224Context*)&context->ctx, bits, | return SHA1FinalBits((SHA1Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| case SHA256: | case SHA224: | |||
| return SHA256FinalBits((SHA256Context*)&context->ctx, bits, | return SHA224FinalBits((SHA224Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| case SHA384: | case SHA256: | |||
| return SHA384FinalBits((SHA384Context*)&context->ctx, bits, | return SHA256FinalBits((SHA256Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| case SHA512: | case SHA384: | |||
| return SHA512FinalBits((SHA512Context*)&context->ctx, bits, | return SHA384FinalBits((SHA384Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| default: return shaBadParam; | case SHA512: | |||
| } | return SHA512FinalBits((SHA512Context*)&context->ctx, bits, | |||
| } else { | bit_count); | |||
| return shaNull; | default: return shaBadParam; | |||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * USHAResult | * USHAResult | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the message digest of the appropriate | * This function will return the message digest of the appropriate | |||
| * bit size, as returned by USHAHashSizeBits(whichSHA) for the | * bit size, as returned by USHAHashSizeBits(whichSHA) for the | |||
| * 'whichSHA' value used in the preceeding call to USHAReset, | * 'whichSHA' value used in the preceeding call to USHAReset, | |||
| skipping to change at page 75, line 4 ¶ | skipping to change at page 73, line 48 ¶ | |||
| * The context to use to calculate the SHA-1 hash. | * The context to use to calculate the SHA-1 hash. | |||
| * Message_Digest: [out] | * Message_Digest: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int USHAResult(USHAContext *context, | int USHAResult(USHAContext *context, | |||
| uint8_t Message_Digest[USHAMaxHashSize]) | uint8_t Message_Digest[USHAMaxHashSize]) | |||
| { | ||||
| if (!context) return shaNull; | ||||
| switch (context->whichSha) { | ||||
| case SHA1: | ||||
| return SHA1Result((SHA1Context*)&context->ctx, Message_Digest); | ||||
| case SHA224: | ||||
| return SHA224Result((SHA224Context*)&context->ctx, | ||||
| Message_Digest); | ||||
| case SHA256: | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| { | return SHA256Result((SHA256Context*)&context->ctx, | |||
| if (context) { | Message_Digest); | |||
| switch (context->whichSha) { | case SHA384: | |||
| case SHA1: | return SHA384Result((SHA384Context*)&context->ctx, | |||
| return SHA1Result((SHA1Context*)&context->ctx, Message_Digest); | Message_Digest); | |||
| case SHA224: | case SHA512: | |||
| return SHA224Result((SHA224Context*)&context->ctx, | return SHA512Result((SHA512Context*)&context->ctx, | |||
| Message_Digest); | Message_Digest); | |||
| case SHA256: | default: return shaBadParam; | |||
| return SHA256Result((SHA256Context*)&context->ctx, | ||||
| Message_Digest); | ||||
| case SHA384: | ||||
| return SHA384Result((SHA384Context*)&context->ctx, | ||||
| Message_Digest); | ||||
| case SHA512: | ||||
| return SHA512Result((SHA512Context*)&context->ctx, | ||||
| Message_Digest); | ||||
| default: return shaBadParam; | ||||
| } | ||||
| } else { | ||||
| return shaNull; | ||||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * USHABlockSize | * USHABlockSize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the blocksize for the given SHA | * This function will return the blocksize for the given SHA | |||
| * algorithm. | * algorithm. | |||
| * | * | |||
| skipping to change at page 76, line 4 ¶ | skipping to change at page 74, line 45 ¶ | |||
| { | { | |||
| switch (whichSha) { | switch (whichSha) { | |||
| case SHA1: return SHA1_Message_Block_Size; | case SHA1: return SHA1_Message_Block_Size; | |||
| case SHA224: return SHA224_Message_Block_Size; | case SHA224: return SHA224_Message_Block_Size; | |||
| case SHA256: return SHA256_Message_Block_Size; | case SHA256: return SHA256_Message_Block_Size; | |||
| case SHA384: return SHA384_Message_Block_Size; | case SHA384: return SHA384_Message_Block_Size; | |||
| default: | default: | |||
| case SHA512: return SHA512_Message_Block_Size; | case SHA512: return SHA512_Message_Block_Size; | |||
| } | } | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * USHAHashSize | * USHAHashSize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the hashsize for the given SHA | * This function will return the hashsize for the given SHA | |||
| * algorithm. | * algorithm. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * whichSha: | * whichSha: | |||
| * which SHA algorithm to query | * which SHA algorithm to query | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Returns: | * Returns: | |||
| * hash size | * hash size | |||
| * | * | |||
| */ | */ | |||
| int USHAHashSize(enum SHAversion whichSha) | int USHAHashSize(enum SHAversion whichSha) | |||
| { | { | |||
| switch (whichSha) { | switch (whichSha) { | |||
| case SHA1: return SHA1HashSize; | case SHA1: return SHA1HashSize; | |||
| case SHA224: return SHA224HashSize; | case SHA224: return SHA224HashSize; | |||
| case SHA256: return SHA256HashSize; | case SHA256: return SHA256HashSize; | |||
| skipping to change at page 77, line 4 ¶ | skipping to change at page 75, line 46 ¶ | |||
| * | * | |||
| */ | */ | |||
| int USHAHashSizeBits(enum SHAversion whichSha) | int USHAHashSizeBits(enum SHAversion whichSha) | |||
| { | { | |||
| switch (whichSha) { | switch (whichSha) { | |||
| case SHA1: return SHA1HashSizeBits; | case SHA1: return SHA1HashSizeBits; | |||
| case SHA224: return SHA224HashSizeBits; | case SHA224: return SHA224HashSizeBits; | |||
| case SHA256: return SHA256HashSizeBits; | case SHA256: return SHA256HashSizeBits; | |||
| case SHA384: return SHA384HashSizeBits; | case SHA384: return SHA384HashSizeBits; | |||
| default: | default: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| case SHA512: return SHA512HashSizeBits; | case SHA512: return SHA512HashSizeBits; | |||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * USHAHashName | * USHAHashName | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the name of the given SHA algorithm | * This function will return the name of the given SHA algorithm | |||
| * as a string. | * as a string. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Parameters: | * Parameters: | |||
| * whichSha: | * whichSha: | |||
| * which SHA algorithm to query | * which SHA algorithm to query | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * character string with the name in it | * character string with the name in it | |||
| * | * | |||
| */ | */ | |||
| const char *USHAHashName(enum SHAversion whichSha) | const char *USHAHashName(enum SHAversion whichSha) | |||
| { | { | |||
| skipping to change at page 78, line 4 ¶ | skipping to change at page 76, line 43 ¶ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the HMAC algorithm (Keyed-Hashing for | * This file implements the HMAC algorithm (Keyed-Hashing for | |||
| * Message Authentication, [RFC 2104]), expressed in terms of | * Message Authentication, [RFC 2104]), expressed in terms of | |||
| * the various SHA algorithms. | * the various SHA algorithms. | |||
| */ | */ | |||
| #include "sha.h" | #include "sha.h" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * hmac | * hmac | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will compute an HMAC message digest. | * This function will compute an HMAC message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * key: [in] | * message_array[ ]: [in] | |||
| * The secret shared key. | ||||
| * key_len: [in] | ||||
| * The length of the secret shared key. | ||||
| * message_array: [in] | ||||
| * An array of octets representing the message. | * An array of octets representing the message. | |||
| * Note: in RFC 2109, this parameter is known | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Note: in RFC 2104, this parameter is known | ||||
| * as 'text'. | * as 'text'. | |||
| * length: [in] | * length: [in] | |||
| * The length of the message in message_array. | * The length of the message in message_array. | |||
| * digest: [out] | * key[ ]: [in] | |||
| * Where the digest is returned. | * The secret shared key. | |||
| * key_len: [in] | ||||
| * The length of the secret shared key. | ||||
| * digest[ ]: [out] | ||||
| * Where the digest is to be returned. | ||||
| * NOTE: The length of the digest is determined by | * NOTE: The length of the digest is determined by | |||
| * the value of whichSha. | * the value of whichSha. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hmac(SHAversion whichSha, | int hmac(SHAversion whichSha, | |||
| const unsigned char *message_array, int length, | const unsigned char *message_array, int length, | |||
| const unsigned char *key, int key_len, | const unsigned char *key, int key_len, | |||
| skipping to change at page 79, line 4 ¶ | skipping to change at page 77, line 46 ¶ | |||
| * hmacReset | * hmacReset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the hmacContext in preparation | * This function will initialize the hmacContext in preparation | |||
| * for computing a new HMAC message digest. | * for computing a new HMAC message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * whichSha: [in] | * whichSha: [in] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * key: [in] | * key[ ]: [in] | |||
| * The secret shared key. | * The secret shared key. | |||
| * key_len: [in] | * key_len: [in] | |||
| * The length of the secret shared key. | * The length of the secret shared key. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hmacReset(HMACContext *context, enum SHAversion whichSha, | int hmacReset(HMACContext *context, enum SHAversion whichSha, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| const unsigned char *key, int key_len) | const unsigned char *key, int key_len) | |||
| { | { | |||
| int i, blocksize, hashsize, ret; | int i, blocksize, hashsize, ret; | |||
| /* inner padding - key XORd with ipad */ | /* inner padding - key XORd with ipad */ | |||
| unsigned char k_ipad[USHA_Max_Message_Block_Size]; | unsigned char k_ipad[USHA_Max_Message_Block_Size]; | |||
| /* temporary buffer when keylen > blocksize */ | /* temporary buffer when keylen > blocksize */ | |||
| unsigned char tempkey[USHAMaxHashSize]; | unsigned char tempkey[USHAMaxHashSize]; | |||
| skipping to change at page 80, line 4 ¶ | skipping to change at page 78, line 45 ¶ | |||
| key = tempkey; | key = tempkey; | |||
| key_len = hashsize; | key_len = hashsize; | |||
| } | } | |||
| /* | /* | |||
| * The HMAC transform looks like: | * The HMAC transform looks like: | |||
| * | * | |||
| * SHA(K XOR opad, SHA(K XOR ipad, text)) | * SHA(K XOR opad, SHA(K XOR ipad, text)) | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * where K is an n byte key, 0-padded to a total of blocksize bytes, | * where K is an n byte key, 0-padded to a total of blocksize bytes, | |||
| * ipad is the byte 0x36 repeated blocksize times, | * ipad is the byte 0x36 repeated blocksize times, | |||
| * opad is the byte 0x5c repeated blocksize times, | * opad is the byte 0x5c repeated blocksize times, | |||
| * and text is the data being protected. | * and text is the data being protected. | |||
| */ | */ | |||
| /* store key into the pads, XOR'd with ipad and opad values */ | /* store key into the pads, XOR'd with ipad and opad values */ | |||
| for (i = 0; i < key_len; i++) { | for (i = 0; i < key_len; i++) { | |||
| k_ipad[i] = key[i] ^ 0x36; | k_ipad[i] = key[i] ^ 0x36; | |||
| context->k_opad[i] = key[i] ^ 0x5c; | context->k_opad[i] = key[i] ^ 0x5c; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* remaining pad bytes are '\0' XOR'd with ipad and opad values */ | /* remaining pad bytes are '\0' XOR'd with ipad and opad values */ | |||
| for ( ; i < blocksize; i++) { | for ( ; i < blocksize; i++) { | |||
| k_ipad[i] = 0x36; | k_ipad[i] = 0x36; | |||
| context->k_opad[i] = 0x5c; | context->k_opad[i] = 0x5c; | |||
| } | } | |||
| /* perform inner hash */ | /* perform inner hash */ | |||
| /* init context for 1st pass */ | /* init context for 1st pass */ | |||
| ret = USHAReset(&context->shaContext, whichSha) || | ret = USHAReset(&context->shaContext, whichSha) || | |||
| /* and start with inner pad */ | /* and start with inner pad */ | |||
| skipping to change at page 80, line 42 ¶ | skipping to change at page 79, line 31 ¶ | |||
| /* | /* | |||
| * hmacInput | * hmacInput | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the message. It may be called multiple times. | * of the message. It may be called multiple times. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The HMAC context to update | * The HMAC context to update | |||
| * message_array: [in] | * text[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the message. | * the message. | |||
| * length: [in] | * text_len: [in] | |||
| * The length of the message in message_array | * The length of the message in text | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hmacInput(HMACContext *context, const unsigned char *text, | int hmacInput(HMACContext *context, const unsigned char *text, | |||
| int text_len) | int text_len) | |||
| { | { | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| /* then text of datagram */ | /* then text of datagram */ | |||
| return context->Corrupted = | return context->Corrupted = | |||
| USHAInput(&context->shaContext, text, text_len); | USHAInput(&context->shaContext, text, text_len); | |||
| } | } | |||
| /* | /* | |||
| * hmacFinalBits | * hmacFinalBits | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will add in any final bits of the message. | * This function will add in any final bits of the message. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The HMAC context to update | * The HMAC context to update | |||
| * message_bits: [in] | * message_bits: [in] | |||
| * The final bits of the message, in the upper portion of the | * The final bits of the message, in the upper portion of the | |||
| * byte. (Use 0b###00000 instead of 0b00000### to input the | * byte. (Use 0b###00000 instead of 0b00000### to input the | |||
| * three bits ###.) | * three bits ###.) | |||
| * length: [in] | * length: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| skipping to change at page 81, line 53 ¶ | skipping to change at page 80, line 42 ¶ | |||
| /* | /* | |||
| * hmacResult | * hmacResult | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the N-byte message digest into the | * This function will return the N-byte message digest into the | |||
| * Message_Digest array provided by the caller. | * Message_Digest array provided by the caller. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to use to calculate the HMAC hash. | * The context to use to calculate the HMAC hash. | |||
| * digest: [out] | * digest[ ]: [out] | |||
| * Where the digest is returned. | * Where the digest is returned. | |||
| * NOTE 2: The length of the hash is determined by the value of | * NOTE 2: The length of the hash is determined by the value of | |||
| * whichSha that was passed to hmacReset(). | * whichSha that was passed to hmacReset(). | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hmacResult(HMACContext *context, uint8_t *digest) | int hmacResult(HMACContext *context, uint8_t *digest) | |||
| { | { | |||
| int ret; | int ret; | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* finish up 1st pass */ | /* finish up 1st pass */ | |||
| /* (Use digest here as a temporary buffer.) */ | /* (Use digest here as a temporary buffer.) */ | |||
| ret = | ret = | |||
| USHAResult(&context->shaContext, digest) || | USHAResult(&context->shaContext, digest) || | |||
| /* perform outer SHA */ | /* perform outer SHA */ | |||
| /* init context for 2nd pass */ | /* init context for 2nd pass */ | |||
| USHAReset(&context->shaContext, context->whichSha) || | USHAReset(&context->shaContext, context->whichSha) || | |||
| /* start with outer pad */ | /* start with outer pad */ | |||
| skipping to change at page 83, line 4 ¶ | skipping to change at page 81, line 43 ¶ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| /* Copyright (c) 2010 IETF Trust and the persons identified as */ | /* Copyright (c) 2010 IETF Trust and the persons identified as */ | |||
| /* authors of the code. All rights reserved. */ | /* authors of the code. All rights reserved. */ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file implements the HKDF algorithm (HMAC-based | * This file implements the HKDF algorithm (HMAC-based | |||
| * Extract-and-Expand Key Derivation Function, RFC 5869), | * Extract-and-Expand Key Derivation Function, RFC 5869), | |||
| * expressed in terms of the various SHA algorithms. | * expressed in terms of the various SHA algorithms. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | */ | |||
| #include "sha.h" | #include "sha.h" | |||
| #include <string.h> | #include <string.h> | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| /* | /* | |||
| * hkdf | * hkdf | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will compute an HKDF message digest. | * This function will generate keying material using HKDF. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Parameters: | * Parameters: | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * salt: [in] | * salt[ ]: [in] | |||
| * The optional salt value (a non-secret random value); | * The optional salt value (a non-secret random value); | |||
| * if not provided (salt == NULL), it is set internally | * if not provided (salt == NULL), it is set internally | |||
| * to a string of HashLen(whichSha) zeros. | * to a string of HashLen(whichSha) zeros. | |||
| * salt_len: [in] | * salt_len: [in] | |||
| * The length of the salt value. (Ignored if salt == NULL.) | * The length of the salt value. (Ignored if salt == NULL.) | |||
| * ikm: [in] | * ikm[ ]: [in] | |||
| * Input keying material. | * Input keying material. | |||
| * ikm_len: [in] | * ikm_len: [in] | |||
| * The length of the input keying material. | * The length of the input keying material. | |||
| * info: [in] | * info[ ]: [in] | |||
| * The optional context and application specific information. | * The optional context and application specific information. | |||
| * If info == NULL or a zero-length string, it is ignored. | * If info == NULL or a zero-length string, it is ignored. | |||
| * info_len: [in] | * info_len: [in] | |||
| * The length of the optional context and application specific | * The length of the optional context and application specific | |||
| * information. (Ignored if info == NULL.) | * information. (Ignored if info == NULL.) | |||
| * okm: [out] | * okm[ ]: [out] | |||
| * Where the HKDF is to be stored. | * Where the HKDF is to be stored. | |||
| * okm_len: [in] | * okm_len: [in] | |||
| * The length of the buffer to hold okm. | * The length of the buffer to hold okm. | |||
| * okm_len must be <= 255 * USHABlockSize(whichSha) | * okm_len must be <= 255 * USHABlockSize(whichSha) | |||
| * | * | |||
| * Notes: | * Notes: | |||
| * Calls hkdfExtract() and hkdfExpand(). | * Calls hkdfExtract() and hkdfExpand(). | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdf(SHAversion whichSha, | int hkdf(SHAversion whichSha, | |||
| const unsigned char *salt, int salt_len, | const unsigned char *salt, int salt_len, | |||
| const unsigned char *ikm, int ikm_len, | const unsigned char *ikm, int ikm_len, | |||
| const unsigned char *info, int info_len, | const unsigned char *info, int info_len, | |||
| uint8_t okm[ ], int okm_len) | uint8_t okm[ ], int okm_len) | |||
| { | { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| uint8_t prk[USHAMaxHashSize]; | uint8_t prk[USHAMaxHashSize]; | |||
| return hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk) || | return hkdfExtract(whichSha, salt, salt_len, ikm, ikm_len, prk) || | |||
| hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, | hkdfExpand(whichSha, prk, USHAHashSize(whichSha), info, | |||
| info_len, okm, okm_len); | info_len, okm, okm_len); | |||
| } | } | |||
| /* | /* | |||
| * hkdfExtract | * hkdfExtract | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will perform HKDF extraction. | * This function will perform HKDF extraction. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Parameters: | * Parameters: | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * salt: [in] | * salt[ ]: [in] | |||
| * The optional salt value (a non-secret random value); | * The optional salt value (a non-secret random value); | |||
| * if not provided (salt == NULL), it is set internally | * if not provided (salt == NULL), it is set internally | |||
| * to a string of HashLen(whichSha) zeros. | * to a string of HashLen(whichSha) zeros. | |||
| * salt_len: [in] | * salt_len: [in] | |||
| * The length of the salt value. (Ignored if salt == NULL.) | * The length of the salt value. (Ignored if salt == NULL.) | |||
| * ikm: [in] | * ikm[ ]: [in] | |||
| * Input keying material. | * Input keying material. | |||
| * ikm_len: [in] | * ikm_len: [in] | |||
| * The length of the input keying material. | * The length of the input keying material. | |||
| * prk: [out] | * prk[ ]: [out] | |||
| * Where the HKDF extraction is to be stored. | * Array where the HKDF extraction is to be stored. | |||
| * Must be larger than USHAHashSize(whichSha); | * Must be larger than USHAHashSize(whichSha); | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdfExtract(SHAversion whichSha, | int hkdfExtract(SHAversion whichSha, | |||
| const unsigned char *salt, int salt_len, | const unsigned char *salt, int salt_len, | |||
| const unsigned char *ikm, int ikm_len, | const unsigned char *ikm, int ikm_len, | |||
| uint8_t prk[USHAMaxHashSize]) | uint8_t prk[USHAMaxHashSize]) | |||
| skipping to change at page 85, line 4 ¶ | skipping to change at page 83, line 45 ¶ | |||
| salt = nullSalt; | salt = nullSalt; | |||
| salt_len = USHAHashSize(whichSha); | salt_len = USHAHashSize(whichSha); | |||
| memset(nullSalt, '\0', salt_len); | memset(nullSalt, '\0', salt_len); | |||
| } else if (salt_len < 0) { | } else if (salt_len < 0) { | |||
| return shaBadParam; | return shaBadParam; | |||
| } | } | |||
| return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk); | return hmac(whichSha, ikm, ikm_len, salt, salt_len, prk); | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * hkdfExpand | * hkdfExpand | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will perform HKDF expansion. | * This function will perform HKDF expansion. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * info: [in] | * prk[ ]: [in] | |||
| * The pseudorandom key to be expanded; either obtained | ||||
| * directly from a cryptographically strong, uniformly | ||||
| * distributed pseudorandom number generator, or as the | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * output from hkdfExtract(). | ||||
| * prk_len: [in] | ||||
| * The length of the pseudorandom key in prk; | ||||
| * should at least be equal to USHAHashSize(whichSHA). | ||||
| * info[ ]: [in] | ||||
| * The optional context and application specific information. | * The optional context and application specific information. | |||
| * If info == NULL or a zero-length string, it is ignored. | * If info == NULL or a zero-length string, it is ignored. | |||
| * info_len: [in] | * info_len: [in] | |||
| * The length of the optional context and application specific | * The length of the optional context and application specific | |||
| * information. (Ignored if info == NULL.) | * information. (Ignored if info == NULL.) | |||
| * okm: [out] | * okm[ ]: [out] | |||
| * Where the HKDF is to be stored. | * Where the HKDF is to be stored. | |||
| * okm_len: [in] | * okm_len: [in] | |||
| * The length of the buffer to hold okm. | * The length of the buffer to hold okm. | |||
| * okm_len must be <= 255 * USHABlockSize(whichSha) | * okm_len must be <= 255 * USHABlockSize(whichSha) | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdfExpand(SHAversion whichSha, const uint8_t prk[ ], int prk_len, | int hkdfExpand(SHAversion whichSha, const uint8_t prk[ ], int prk_len, | |||
| skipping to change at page 85, line 43 ¶ | skipping to change at page 84, line 40 ¶ | |||
| { | { | |||
| int hash_len, N; | int hash_len, N; | |||
| unsigned char T[USHAMaxHashSize]; | unsigned char T[USHAMaxHashSize]; | |||
| int Tlen, where, i; | int Tlen, where, i; | |||
| if (info == 0) { | if (info == 0) { | |||
| info = (const unsigned char *)""; | info = (const unsigned char *)""; | |||
| info_len = 0; | info_len = 0; | |||
| } else if (info_len < 0) { | } else if (info_len < 0) { | |||
| return shaBadParam; | return shaBadParam; | |||
| } else if (prk_len < 0) { | ||||
| return shaBadParam; | ||||
| } else if (!okm) { | ||||
| return shaBadParam; | ||||
| } | } | |||
| if (okm_len <= 0) return shaBadParam; | ||||
| if (!okm) return shaBadParam; | ||||
| hash_len = USHAHashSize(whichSha); | hash_len = USHAHashSize(whichSha); | |||
| if (prk_len < hash_len) return shaBadParam; | if (prk_len < hash_len) return shaBadParam; | |||
| N = okm_len / hash_len; | N = okm_len / hash_len; | |||
| if ((okm_len % hash_len) != 0) N++; | if ((okm_len % hash_len) != 0) N++; | |||
| if (N > 255) return shaBadParam; | if (N > 255) return shaBadParam; | |||
| Tlen = 0; | Tlen = 0; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| where = 0; | where = 0; | |||
| for (i = 1; i <= N; i++) { | for (i = 1; i <= N; i++) { | |||
| HMACContext context; | HMACContext context; | |||
| unsigned char c = i; | unsigned char c = i; | |||
| int ret = hmacReset(&context, whichSha, prk, hash_len) || | int ret = hmacReset(&context, whichSha, prk, prk_len) || | |||
| hmacInput(&context, T, Tlen) || | hmacInput(&context, T, Tlen) || | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| hmacInput(&context, info, info_len) || | hmacInput(&context, info, info_len) || | |||
| hmacInput(&context, &c, 1) || | hmacInput(&context, &c, 1) || | |||
| hmacResult(&context, T); | hmacResult(&context, T); | |||
| if (ret != shaSuccess) return ret; | if (ret != shaSuccess) return ret; | |||
| memcpy(okm + where, T, | memcpy(okm + where, T, | |||
| (i != N) ? hash_len : (okm_len - where)); | (i != N) ? hash_len : (okm_len - where)); | |||
| where += hash_len; | where += hash_len; | |||
| Tlen = hash_len; | Tlen = hash_len; | |||
| } | } | |||
| return shaSuccess; | return shaSuccess; | |||
| } | } | |||
| /* | /* | |||
| * hkdfReset | * hkdfReset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the hkdfContext in preparation | * This function will initialize the hkdfContext in preparation | |||
| * for computing a new HKDF message digest. It is used for | * for key derivation using the modular HKDF interface for | |||
| * arbitrary length inputs. | * arbitrary length inputs. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * whichSha: [in] | * whichSha: [in] | |||
| * One of SHA1, SHA224, SHA256, SHA384, SHA512 | * One of SHA1, SHA224, SHA256, SHA384, SHA512 | |||
| * salt: [in] | * salt[ ]: [in] | |||
| * The optional salt value (a non-secret random value); | * The optional salt value (a non-secret random value); | |||
| * if not provided (salt == NULL), it is set internally | * if not provided (salt == NULL), it is set internally | |||
| * to a string of HashLen(whichSha) zeros. | * to a string of HashLen(whichSha) zeros. | |||
| * salt_len: [in] | * salt_len: [in] | |||
| * The length of the salt value. (Ignored if salt == NULL.) | * The length of the salt value. (Ignored if salt == NULL.) | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdfReset(HKDFContext *context, enum SHAversion whichSha, | int hkdfReset(HKDFContext *context, enum SHAversion whichSha, | |||
| const unsigned char *salt, int salt_len) | const unsigned char *salt, int salt_len) | |||
| { | { | |||
| unsigned char nullSalt[USHAMaxHashSize]; | unsigned char nullSalt[USHAMaxHashSize]; | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| context->whichSha = whichSha; | context->whichSha = whichSha; | |||
| context->hashSize = USHAHashSize(whichSha); | context->hashSize = USHAHashSize(whichSha); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (salt == 0) { | if (salt == 0) { | |||
| salt = nullSalt; | salt = nullSalt; | |||
| salt_len = context->hashSize; | salt_len = context->hashSize; | |||
| memset(nullSalt, '\0', salt_len); | memset(nullSalt, '\0', salt_len); | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return hmacReset(&context->hmacContext, whichSha, salt, salt_len); | return hmacReset(&context->hmacContext, whichSha, salt, salt_len); | |||
| } | } | |||
| /* | /* | |||
| * hkdfInput | * hkdfInput | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function accepts an array of octets as the next portion | * This function accepts an array of octets as the next portion | |||
| * of the input keying material. It may be called multiple times. | * of the input keying material. It may be called multiple times. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The HKDF context to update. | * The HKDF context to update. | |||
| * ikm: [in] | * ikm[ ]: [in] | |||
| * An array of octets representing the next portion of | * An array of octets representing the next portion of | |||
| * the input keying material. | * the input keying material. | |||
| * ikm_len: [in] | * ikm_len: [in] | |||
| * The length of ikm. | * The length of ikm. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdfInput(HKDFContext *context, const unsigned char *ikm, | int hkdfInput(HKDFContext *context, const unsigned char *ikm, | |||
| skipping to change at page 88, line 4 ¶ | skipping to change at page 86, line 51 ¶ | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will add in any final bits of the | * This function will add in any final bits of the | |||
| * input keying material. | * input keying material. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The HKDF context to update | * The HKDF context to update | |||
| * ikm_bits: [in] | * ikm_bits: [in] | |||
| * The final bits of the input keying material, in the upper | * The final bits of the input keying material, in the upper | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * portion of the byte. (Use 0b###00000 instead of 0b00000### | * portion of the byte. (Use 0b###00000 instead of 0b00000### | |||
| * to input the three bits ###.) | * to input the three bits ###.) | |||
| * ikm_bit_count: [in] | * ikm_bit_count: [in] | |||
| * The number of bits in message_bits, between 1 and 7. | * The number of bits in message_bits, between 1 and 7. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits, | int hkdfFinalBits(HKDFContext *context, uint8_t ikm_bits, | |||
| unsigned int ikm_bit_count) | unsigned int ikm_bit_count) | |||
| { | { | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| return hmacFinalBits(&context->hmacContext, ikm_bits, ikm_bit_count); | return hmacFinalBits(&context->hmacContext, ikm_bits, ikm_bit_count); | |||
| } | } | |||
| skipping to change at page 88, line 34 ¶ | skipping to change at page 87, line 28 ¶ | |||
| /* | /* | |||
| * hkdfResult | * hkdfResult | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will finish the HKDF extraction and perform the | * This function will finish the HKDF extraction and perform the | |||
| * final HKDF expansion. | * final HKDF expansion. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The HKDF context to use to calculate the HKDF hash. | * The HKDF context to use to calculate the HKDF hash. | |||
| * prk: [out] | * prk[ ]: [out] | |||
| * An optional location to store the HKDF extraction. | * An optional location to store the HKDF extraction. | |||
| * Either NULL, or pointer to a buffer that must be | * Either NULL, or pointer to a buffer that must be | |||
| * larger than USHAHashSize(whichSha); | * larger than USHAHashSize(whichSha); | |||
| * info: [in] | * info[ ]: [in] | |||
| * The optional context and application specific information. | * The optional context and application specific information. | |||
| * If info == NULL or a zero-length string, it is ignored. | * If info == NULL or a zero-length string, it is ignored. | |||
| * info_len: [in] | * info_len: [in] | |||
| * The length of the optional context and application specific | * The length of the optional context and application specific | |||
| * information. (Ignored if info == NULL.) | * information. (Ignored if info == NULL.) | |||
| * okm: [out] | * okm[ ]: [out] | |||
| * Where the HKDF is to be stored. | * Where the HKDF is to be stored. | |||
| * okm_len: [in] | * okm_len: [in] | |||
| * The length of the buffer to hold okm. | * The length of the buffer to hold okm. | |||
| * okm_len must be <= 255 * USHABlockSize(whichSha) | * okm_len must be <= 255 * USHABlockSize(whichSha) | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int hkdfResult(HKDFContext *context, | int hkdfResult(HKDFContext *context, | |||
| uint8_t prk[USHAMaxHashSize], | uint8_t prk[USHAMaxHashSize], | |||
| const unsigned char *info, int info_len, | const unsigned char *info, int info_len, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| uint8_t okm[ ], int okm_len) | uint8_t okm[ ], int okm_len) | |||
| { | { | |||
| uint8_t prkbuf[USHAMaxHashSize]; | uint8_t prkbuf[USHAMaxHashSize]; | |||
| int ret; | int ret; | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| if (context->Computed) return context->Corrupted = shaStateError; | if (context->Computed) return context->Corrupted = shaStateError; | |||
| if (!okm) return context->Corrupted = shaBadParam; | if (!okm) return context->Corrupted = shaBadParam; | |||
| if (!prk) prk = prkbuf; | if (!prk) prk = prkbuf; | |||
| ret = hmacResult(&context->hmacContext, prk) || | ret = hmacResult(&context->hmacContext, prk) || | |||
| hkdfExpand(context->whichSha, prk, context->hashSize, info, | hkdfExpand(context->whichSha, prk, context->hashSize, info, | |||
| info_len, okm, okm_len); | info_len, okm, okm_len); | |||
| context->Computed = 1; | context->Computed = 1; | |||
| return context->Corrupted = ret; | return context->Corrupted = ret; | |||
| skipping to change at page 89, line 43 ¶ | skipping to change at page 88, line 37 ¶ | |||
| /************************** shatest.c **************************/ | /************************** shatest.c **************************/ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| /* Copyright (c) 2010 IETF Trust and the persons identified as */ | /* Copyright (c) 2010 IETF Trust and the persons identified as */ | |||
| /* authors of the code. All rights reserved. */ | /* authors of the code. All rights reserved. */ | |||
| /* See sha.h for terms of use and redistribution. */ | /* See sha.h for terms of use and redistribution. */ | |||
| /* | /* | |||
| * Description: | * Description: | |||
| * This file will exercise the SHA code performing | * This file will exercise the SHA code performing | |||
| * the three tests documented in FIPS PUB 180-2 | * the three tests documented in FIPS PUB 180-3 | |||
| * (http://csrc.nist.gov/publications/fips/ | * (http://csrc.nist.gov/publications/fips/ | |||
| * fips180-2/fips180-2withchangenotice.pdf) | * fips180-2/fips180-2withchangenotice.pdf) | |||
| * one that calls SHAInput with an exact multiple of 512 bits | * one that calls SHAInput with an exact multiple of 512 bits | |||
| * the seven tests documented for each algorithm in | * the seven tests documented for each algorithm in | |||
| * "The Secure Hash Algorithm Validation System (SHAVS)" | * "The Secure Hash Algorithm Validation System (SHAVS)" | |||
| * (http://csrc.nist.gov/cryptval/shs/SHAVS.pdf), | * (http://csrc.nist.gov/cryptval/shs/SHAVS.pdf), | |||
| * three of which are bit-level tests | * three of which are bit-level tests | |||
| * | * | |||
| * These tests have subsequently been moved to pages linked from | ||||
| * http://csrc.nist.gov/groups/ST/toolkit/examples.html | ||||
| * | ||||
| * This file will exercise the HMAC SHA1 code performing | * This file will exercise the HMAC SHA1 code performing | |||
| * the seven tests documented in RFCs [RFC 2202] and [RFC 4231]. | * the seven tests documented in RFCs [RFC 2202] and [RFC 4231]. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * This file will exercise the HKDF code performing | * This file will exercise the HKDF code performing | |||
| * the seven tests documented in RFC 4869. | * the seven tests documented in RFC 4869. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * To run the tests and just see PASSED/FAILED, use the -p option. | * To run the tests and just see PASSED/FAILED, use the -p option. | |||
| * | * | |||
| * Other options exercise: | * Other options exercise: | |||
| * hashing an arbitrary string | * hashing an arbitrary string | |||
| * hashing a file's contents | * hashing a file's contents | |||
| * a few error test checks | * a few error test checks | |||
| * printing the results in raw format | * printing the results in raw format | |||
| * | * | |||
| * Portability Issues: | * Portability Issues: | |||
| * None. | * None. | |||
| skipping to change at page 91, line 4 ¶ | skipping to change at page 89, line 54 ¶ | |||
| /* an exact multiple of 512 bits */ | /* an exact multiple of 512 bits */ | |||
| #define TEST4 TEST4a TEST4b /* times 10 */ | #define TEST4 TEST4a TEST4b /* times 10 */ | |||
| #define TEST7_1 \ | #define TEST7_1 \ | |||
| "\x49\xb2\xae\xc2\x59\x4b\xbe\x3a\x3b\x11\x75\x42\xd9\x4a\xc8" | "\x49\xb2\xae\xc2\x59\x4b\xbe\x3a\x3b\x11\x75\x42\xd9\x4a\xc8" | |||
| #define TEST8_1 \ | #define TEST8_1 \ | |||
| "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46" | "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46" | |||
| #define TEST9_1 \ | #define TEST9_1 \ | |||
| "\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4\xa2\xe7\x1a\xe7\x02\x20" \ | "\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4\xa2\xe7\x1a\xe7\x02\x20" \ | |||
| "\xaa\xce\xc8\x96\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea\xaa\x10" \ | "\xaa\xce\xc8\x96\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea\xaa\x10" \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e\x43\x66\x5a\x5a\xf2\xcd\x03\xfe" \ | "\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e\x43\x66\x5a\x5a\xf2\xcd\x03\xfe" \ | |||
| "\x67\x8e\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2\x8b\x91\x09\xf4" \ | "\x67\x8e\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2\x8b\x91\x09\xf4" \ | |||
| "\x69\xda\xc9\x2a\xaa\xb3\xaa\x7c\x11\xa1\xb3\x2a" | "\x69\xda\xc9\x2a\xaa\xb3\xaa\x7c\x11\xa1\xb3\x2a" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define TEST10_1 \ | #define TEST10_1 \ | |||
| "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f" \ | "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f" \ | |||
| "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15" \ | "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15" \ | |||
| "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92" \ | "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92" \ | |||
| "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f" \ | "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f" \ | |||
| "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" \ | "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" \ | |||
| "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca" \ | "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca" \ | |||
| "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b" \ | "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b" \ | |||
| "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60" \ | "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60" \ | |||
| "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80" \ | "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80" \ | |||
| skipping to change at page 92, line 4 ¶ | skipping to change at page 90, line 54 ¶ | |||
| "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" | "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52" | |||
| #define TEST9_256 \ | #define TEST9_256 \ | |||
| "\x3e\x74\x03\x71\xc8\x10\xc2\xb9\x9f\xc0\x4e\x80\x49\x07\xef\x7c" \ | "\x3e\x74\x03\x71\xc8\x10\xc2\xb9\x9f\xc0\x4e\x80\x49\x07\xef\x7c" \ | |||
| "\xf2\x6b\xe2\x8b\x57\xcb\x58\xa3\xe2\xf3\xc0\x07\x16\x6e\x49\xc1" \ | "\xf2\x6b\xe2\x8b\x57\xcb\x58\xa3\xe2\xf3\xc0\x07\x16\x6e\x49\xc1" \ | |||
| "\x2e\x9b\xa3\x4c\x01\x04\x06\x91\x29\xea\x76\x15\x64\x25\x45\x70" \ | "\x2e\x9b\xa3\x4c\x01\x04\x06\x91\x29\xea\x76\x15\x64\x25\x45\x70" \ | |||
| "\x3a\x2b\xd9\x01\xe1\x6e\xb0\xe0\x5d\xeb\xa0\x14\xeb\xff\x64\x06" \ | "\x3a\x2b\xd9\x01\xe1\x6e\xb0\xe0\x5d\xeb\xa0\x14\xeb\xff\x64\x06" \ | |||
| "\xa0\x7d\x54\x36\x4e\xff\x74\x2d\xa7\x79\xb0\xb3" | "\xa0\x7d\x54\x36\x4e\xff\x74\x2d\xa7\x79\xb0\xb3" | |||
| #define TEST10_256 \ | #define TEST10_256 \ | |||
| "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ | "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \ | |||
| "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ | "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ | "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \ | |||
| "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ | "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \ | |||
| "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ | "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ | "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \ | |||
| "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ | "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \ | |||
| "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ | "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \ | |||
| "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ | "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \ | |||
| "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ | "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \ | |||
| "\x3d\x54\xd6" | "\x3d\x54\xd6" | |||
| #define TEST7_384 \ | #define TEST7_384 \ | |||
| "\x8b\xc5\x00\xc7\x7c\xee\xd9\x87\x9d\xa9\x89\x10\x7c\xe0\xaa" | "\x8b\xc5\x00\xc7\x7c\xee\xd9\x87\x9d\xa9\x89\x10\x7c\xe0\xaa" | |||
| #define TEST8_384 \ | #define TEST8_384 \ | |||
| "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39" | "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39" | |||
| skipping to change at page 93, line 4 ¶ | skipping to change at page 91, line 54 ¶ | |||
| "\x08\xec\xb5\x2e\xba\xe1\xf7\x42\x2d\xb6\x2b\xcd\x54\x26\x70" | "\x08\xec\xb5\x2e\xba\xe1\xf7\x42\x2d\xb6\x2b\xcd\x54\x26\x70" | |||
| #define TEST8_512 \ | #define TEST8_512 \ | |||
| "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" | "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0" | |||
| #define TEST9_512 \ | #define TEST9_512 \ | |||
| "\x3a\xdd\xec\x85\x59\x32\x16\xd1\x61\x9a\xa0\x2d\x97\x56\x97\x0b" \ | "\x3a\xdd\xec\x85\x59\x32\x16\xd1\x61\x9a\xa0\x2d\x97\x56\x97\x0b" \ | |||
| "\xfc\x70\xac\xe2\x74\x4f\x7c\x6b\x27\x88\x15\x10\x28\xf7\xb6\xa2" \ | "\xfc\x70\xac\xe2\x74\x4f\x7c\x6b\x27\x88\x15\x10\x28\xf7\xb6\xa2" \ | |||
| "\x55\x0f\xd7\x4a\x7e\x6e\x69\xc2\xc9\xb4\x5f\xc4\x54\x96\x6d\xc3" \ | "\x55\x0f\xd7\x4a\x7e\x6e\x69\xc2\xc9\xb4\x5f\xc4\x54\x96\x6d\xc3" \ | |||
| "\x1d\x2e\x10\xda\x1f\x95\xce\x02\xbe\xb4\xbf\x87\x65\x57\x4c\xbd" \ | "\x1d\x2e\x10\xda\x1f\x95\xce\x02\xbe\xb4\xbf\x87\x65\x57\x4c\xbd" \ | |||
| "\x6e\x83\x37\xef\x42\x0a\xdc\x98\xc1\x5c\xb6\xd5\xe4\xa0\x24\x1b" \ | "\x6e\x83\x37\xef\x42\x0a\xdc\x98\xc1\x5c\xb6\xd5\xe4\xa0\x24\x1b" \ | |||
| "\xa0\x04\x6d\x25\x0e\x51\x02\x31\xca\xc2\x04\x6c\x99\x16\x06\xab" \ | "\xa0\x04\x6d\x25\x0e\x51\x02\x31\xca\xc2\x04\x6c\x99\x16\x06\xab" \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "\x4e\xe4\x14\x5b\xee\x2f\xf4\xbb\x12\x3a\xab\x49\x8d\x9d\x44\x79" \ | "\x4e\xe4\x14\x5b\xee\x2f\xf4\xbb\x12\x3a\xab\x49\x8d\x9d\x44\x79" \ | |||
| "\x4f\x99\xcc\xad\x89\xa9\xa1\x62\x12\x59\xed\xa7\x0a\x5b\x6d\xd4" \ | "\x4f\x99\xcc\xad\x89\xa9\xa1\x62\x12\x59\xed\xa7\x0a\x5b\x6d\xd4" \ | |||
| "\xbd\xd8\x77\x78\xc9\x04\x3b\x93\x84\xf5\x49\x06" | "\xbd\xd8\x77\x78\xc9\x04\x3b\x93\x84\xf5\x49\x06" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define TEST10_512 \ | #define TEST10_512 \ | |||
| "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ | "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \ | |||
| "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ | "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \ | |||
| "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ | "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \ | |||
| "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ | "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \ | |||
| "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ | "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \ | |||
| "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ | "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \ | |||
| "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ | "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \ | |||
| "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ | "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \ | |||
| "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ | "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \ | |||
| skipping to change at page 94, line 4 ¶ | skipping to change at page 92, line 54 ¶ | |||
| #define HMACTESTCOUNT 7 | #define HMACTESTCOUNT 7 | |||
| #define HKDFTESTCOUNT 7 | #define HKDFTESTCOUNT 7 | |||
| #define PRINTNONE 0 | #define PRINTNONE 0 | |||
| #define PRINTTEXT 1 | #define PRINTTEXT 1 | |||
| #define PRINTRAW 2 | #define PRINTRAW 2 | |||
| #define PRINTHEX 3 | #define PRINTHEX 3 | |||
| #define PRINTBASE64 4 | #define PRINTBASE64 4 | |||
| #define PRINTPASSFAIL 1 | #define PRINTPASSFAIL 1 | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define PRINTFAIL 2 | #define PRINTFAIL 2 | |||
| #define length(x) (sizeof(x)-1) | #define length(x) (sizeof(x)-1) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* Test arrays for hashes. */ | /* Test arrays for hashes. */ | |||
| struct hash { | struct hash { | |||
| const char *name; | const char *name; | |||
| SHAversion whichSha; | SHAversion whichSha; | |||
| int hashsize; | int hashsize; | |||
| struct { | struct { | |||
| const char *testarray; | const char *testarray; | |||
| int length; | int length; | |||
| long repeatcount; | long repeatcount; | |||
| skipping to change at page 95, line 4 ¶ | skipping to change at page 93, line 52 ¶ | |||
| /* 10 */ { TEST10_1, length(TEST10_1), 1, 0, 0, | /* 10 */ { TEST10_1, length(TEST10_1), 1, 0, 0, | |||
| "CB0082C8F197D260991BA6A460E76E202BAD27B3" } | "CB0082C8F197D260991BA6A460E76E202BAD27B3" } | |||
| }, SHA1_SEED, { "E216836819477C7F78E0D843FE4FF1B6D6C14CD4", | }, SHA1_SEED, { "E216836819477C7F78E0D843FE4FF1B6D6C14CD4", | |||
| "A2DBC7A5B1C6C0A8BCB7AAA41252A6A7D0690DBC", | "A2DBC7A5B1C6C0A8BCB7AAA41252A6A7D0690DBC", | |||
| "DB1F9050BB863DFEF4CE37186044E2EEB17EE013", | "DB1F9050BB863DFEF4CE37186044E2EEB17EE013", | |||
| "127FDEDF43D372A51D5747C48FBFFE38EF6CDF7B" | "127FDEDF43D372A51D5747C48FBFFE38EF6CDF7B" | |||
| } }, | } }, | |||
| { "SHA224", SHA224, SHA224HashSize, | { "SHA224", SHA224, SHA224HashSize, | |||
| { | { | |||
| /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" }, | "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" }, | |||
| /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0, | /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0, | |||
| "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" }, | "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" }, | |||
| /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" }, | "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" }, | |||
| /* 4 */ { TEST4, length(TEST4), 10, 0, 0, | /* 4 */ { TEST4, length(TEST4), 10, 0, 0, | |||
| "567F69F168CD7844E65259CE658FE7AADFA25216E68ECA0EB7AB8262" }, | "567F69F168CD7844E65259CE658FE7AADFA25216E68ECA0EB7AB8262" }, | |||
| /* 5 */ { "", 0, 0, 0x68, 5, | /* 5 */ { "", 0, 0, 0x68, 5, | |||
| "E3B048552C3C387BCAB37F6EB06BB79B96A4AEE5FF27F51531A9551C" }, | "E3B048552C3C387BCAB37F6EB06BB79B96A4AEE5FF27F51531A9551C" }, | |||
| /* 6 */ { "\x07", 1, 1, 0, 0, | /* 6 */ { "\x07", 1, 1, 0, 0, | |||
| "00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450BEE2AA8C2A" }, | "00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450BEE2AA8C2A" }, | |||
| /* 7 */ { TEST7_224, length(TEST7_224), 1, 0xA0, 3, | /* 7 */ { TEST7_224, length(TEST7_224), 1, 0xA0, 3, | |||
| "1B01DB6CB4A9E43DED1516BEB3DB0B87B6D1EA43187462C608137150" }, | "1B01DB6CB4A9E43DED1516BEB3DB0B87B6D1EA43187462C608137150" }, | |||
| /* 8 */ { TEST8_224, length(TEST8_224), 1, 0, 0, | /* 8 */ { TEST8_224, length(TEST8_224), 1, 0, 0, | |||
| skipping to change at page 96, line 4 ¶ | skipping to change at page 94, line 53 ¶ | |||
| "9C821FF2A1279089FA091B35B8CD960BCAF7DE01C6A7680756BEB972" }, | "9C821FF2A1279089FA091B35B8CD960BCAF7DE01C6A7680756BEB972" }, | |||
| /* 8 */ { TEST8_256, length(TEST8_256), 1, 0, 0, "175EE69B02BA" | /* 8 */ { TEST8_256, length(TEST8_256), 1, 0, 0, "175EE69B02BA" | |||
| "9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" }, | "9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" }, | |||
| /* 9 */ { TEST9_256, length(TEST9_256), 1, 0xA0, 3, "3E9AD646" | /* 9 */ { TEST9_256, length(TEST9_256), 1, 0xA0, 3, "3E9AD646" | |||
| "8BBBAD2AC3C2CDC292E018BA5FD70B960CF1679777FCE708FDB066E9" }, | "8BBBAD2AC3C2CDC292E018BA5FD70B960CF1679777FCE708FDB066E9" }, | |||
| /* 10 */ { TEST10_256, length(TEST10_256), 1, 0, 0, "97DBCA7D" | /* 10 */ { TEST10_256, length(TEST10_256), 1, 0, 0, "97DBCA7D" | |||
| "F46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" }, | "F46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" }, | |||
| }, SHA256_SEED, { "83D28614D49C3ADC1D6FC05DB5F48037C056F8D2A4CE44" | }, SHA256_SEED, { "83D28614D49C3ADC1D6FC05DB5F48037C056F8D2A4CE44" | |||
| "EC6457DEA5DD797CD1", "99DBE3127EF2E93DD9322D6A07909EB33B6399" | "EC6457DEA5DD797CD1", "99DBE3127EF2E93DD9322D6A07909EB33B6399" | |||
| "5E529B3F954B8581621BB74D39", "8D4BE295BB64661CA3C7EFD129A2F7" | "5E529B3F954B8581621BB74D39", "8D4BE295BB64661CA3C7EFD129A2F7" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "25B33072DBDDE32385B9A87B9AF88EA76F", "40AF5D3F9716B040DF9408" | "25B33072DBDDE32385B9A87B9AF88EA76F", "40AF5D3F9716B040DF9408" | |||
| "E31536B70FF906EC51B00447CA97D7DD97C12411F4" | "E31536B70FF906EC51B00447CA97D7DD97C12411F4" | |||
| } }, | } }, | |||
| { "SHA384", SHA384, SHA384HashSize, | { "SHA384", SHA384, SHA384HashSize, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { | { | |||
| /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | |||
| "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED163" | "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED163" | |||
| "1A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" }, | "1A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" }, | |||
| /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0, | /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0, | |||
| "09330C33F71147E83D192FC782CD1B4753111B173B3B05D2" | "09330C33F71147E83D192FC782CD1B4753111B173B3B05D2" | |||
| "2FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" }, | "2FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" }, | |||
| /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | |||
| "9D0E1809716474CB086E834E310A4A1CED149E9C00F24852" | "9D0E1809716474CB086E834E310A4A1CED149E9C00F24852" | |||
| "7972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" }, | "7972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" }, | |||
| skipping to change at page 97, line 4 ¶ | skipping to change at page 95, line 53 ¶ | |||
| "638A01418F", "0CA76BD0813AF1509E170907A96005938BC985628290B2" | "638A01418F", "0CA76BD0813AF1509E170907A96005938BC985628290B2" | |||
| "5FEF73CF6FAD68DDBA0AC8920C94E0541607B0915A7B4457F7" | "5FEF73CF6FAD68DDBA0AC8920C94E0541607B0915A7B4457F7" | |||
| } }, | } }, | |||
| { "SHA512", SHA512, SHA512HashSize, | { "SHA512", SHA512, SHA512HashSize, | |||
| { | { | |||
| /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | /* 1 */ { TEST1, length(TEST1), 1, 0, 0, | |||
| "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" | "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2" | |||
| "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" | "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD" | |||
| "454D4423643CE80E2A9AC94FA54CA49F" }, | "454D4423643CE80E2A9AC94FA54CA49F" }, | |||
| /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0, | /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" | "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1" | |||
| "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" | "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A" | |||
| "C7D329EEB6DD26545E96E55B874BE909" }, | "C7D329EEB6DD26545E96E55B874BE909" }, | |||
| /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "E718483D0CE769644E2E42C7BC15B4638E1F98B13B204428" | "E718483D0CE769644E2E42C7BC15B4638E1F98B13B204428" | |||
| "5632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31B" | "5632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31B" | |||
| "EB009C5C2C49AA2E4EADB217AD8CC09B" }, | "EB009C5C2C49AA2E4EADB217AD8CC09B" }, | |||
| /* 4 */ { TEST4, length(TEST4), 10, 0, 0, | /* 4 */ { TEST4, length(TEST4), 10, 0, 0, | |||
| "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024" | "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024" | |||
| "DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB51" | "DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB51" | |||
| "0813A39CD5A84C4ACAA64D3F3FB7BAE9" }, | "0813A39CD5A84C4ACAA64D3F3FB7BAE9" }, | |||
| /* 5 */ { "", 0, 0, 0xB0, 5, | /* 5 */ { "", 0, 0, 0xB0, 5, | |||
| "D4EE29A9E90985446B913CF1D1376C836F4BE2C1CF3CADA0" | "D4EE29A9E90985446B913CF1D1376C836F4BE2C1CF3CADA0" | |||
| "720A6BF4857D886A7ECB3C4E4C0FA8C7F95214E41DC1B0D2" | "720A6BF4857D886A7ECB3C4E4C0FA8C7F95214E41DC1B0D2" | |||
| skipping to change at page 98, line 4 ¶ | skipping to change at page 96, line 53 ¶ | |||
| "92E5C3F6C36547DA1C13DBB9EA4F73EA4CBBAF89411527906D35B1B06C1B" | "92E5C3F6C36547DA1C13DBB9EA4F73EA4CBBAF89411527906D35B1B06C1B" | |||
| "6A8007D05EC66DF0A406066829EAB618BDE3976515AAFC", "46E36B007D" | "6A8007D05EC66DF0A406066829EAB618BDE3976515AAFC", "46E36B007D" | |||
| "19876CDB0B29AD074FE3C08CDD174D42169D6ABE5A1414B6E79707DF5877" | "19876CDB0B29AD074FE3C08CDD174D42169D6ABE5A1414B6E79707DF5877" | |||
| "6A98091CF431854147BB6D3C66D43BFBC108FD715BDE6AA127C2B0E79F" | "6A98091CF431854147BB6D3C66D43BFBC108FD715BDE6AA127C2B0E79F" | |||
| } | } | |||
| } | } | |||
| }; | }; | |||
| /* Test arrays for HMAC. */ | /* Test arrays for HMAC. */ | |||
| struct hmachash { | struct hmachash { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| const char *keyarray[5]; | const char *keyarray[5]; | |||
| int keylength[5]; | int keylength[5]; | |||
| const char *dataarray[5]; | const char *dataarray[5]; | |||
| int datalength[5]; | int datalength[5]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| const char *resultarray[5]; | const char *resultarray[5]; | |||
| int resultlength[5]; | int resultlength[5]; | |||
| } hmachashes[HMACTESTCOUNT] = { | } hmachashes[HMACTESTCOUNT] = { | |||
| { /* 1 */ { | { /* 1 */ { | |||
| "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | |||
| "\x0b\x0b\x0b\x0b\x0b" | "\x0b\x0b\x0b\x0b\x0b" | |||
| }, { 20 }, { | }, { 20 }, { | |||
| "\x48\x69\x20\x54\x68\x65\x72\x65" /* "Hi There" */ | "\x48\x69\x20\x54\x68\x65\x72\x65" /* "Hi There" */ | |||
| }, { 8 }, { | }, { 8 }, { | |||
| /* HMAC-SHA-1 */ | /* HMAC-SHA-1 */ | |||
| skipping to change at page 99, line 4 ¶ | skipping to change at page 97, line 53 ¶ | |||
| "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E6148008FD05E44", | "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E6148008FD05E44", | |||
| /* HMAC-SHA-256 */ | /* HMAC-SHA-256 */ | |||
| "5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC" | "5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC" | |||
| "3843", | "3843", | |||
| /* HMAC-SHA-384 */ | /* HMAC-SHA-384 */ | |||
| "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B47E42EC3736322" | "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B47E42EC3736322" | |||
| "445E8E2240CA5E69E2C78B3239ECFAB21649", | "445E8E2240CA5E69E2C78B3239ECFAB21649", | |||
| /* HMAC-SHA-512 */ | /* HMAC-SHA-512 */ | |||
| "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831FD610270CD7EA25" | "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831FD610270CD7EA25" | |||
| "05549758BF75C05A994A6D034F65F8F0E6FDCAEAB1A34D4A6B4B636E070A" | "05549758BF75C05A994A6D034F65F8F0E6FDCAEAB1A34D4A6B4B636E070A" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "38BCE737" | "38BCE737" | |||
| }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | |||
| SHA384HashSize, SHA512HashSize } | SHA384HashSize, SHA512HashSize } | |||
| }, | }, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { /* 3 */ | { /* 3 */ | |||
| { | { | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa" | |||
| }, { 20 }, { | }, { 20 }, { | |||
| "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | |||
| "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | |||
| "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd" | |||
| "\xdd\xdd\xdd\xdd\xdd" | "\xdd\xdd\xdd\xdd\xdd" | |||
| }, { 50 }, { | }, { 50 }, { | |||
| skipping to change at page 100, line 4 ¶ | skipping to change at page 98, line 53 ¶ | |||
| /* HMAC-SHA-1 */ | /* HMAC-SHA-1 */ | |||
| "4C9007F4026250C6BC8414F9BF50C86C2D7235DA", | "4C9007F4026250C6BC8414F9BF50C86C2D7235DA", | |||
| /* HMAC-SHA-224 */ | /* HMAC-SHA-224 */ | |||
| "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC012DE7AFEC5A", | "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC012DE7AFEC5A", | |||
| /* HMAC-SHA-256 */ | /* HMAC-SHA-256 */ | |||
| "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8077A2E3FF46729" | "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8077A2E3FF46729" | |||
| "665B", | "665B", | |||
| /* HMAC-SHA-384 */ | /* HMAC-SHA-384 */ | |||
| "3E8A69B7783C25851933AB6290AF6CA77A9981480850009CC5577C6E1F57" | "3E8A69B7783C25851933AB6290AF6CA77A9981480850009CC5577C6E1F57" | |||
| "3B4E6801DD23C4A7D679CCF8A386C674CFFB", | "3B4E6801DD23C4A7D679CCF8A386C674CFFB", | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* HMAC-SHA-512 */ | /* HMAC-SHA-512 */ | |||
| "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B872DE76F8050361E" | "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B872DE76F8050361E" | |||
| "E3DBA91CA5C11AA25EB4D679275CC5788063A5F19741120C4F2DE2ADEBEB" | "E3DBA91CA5C11AA25EB4D679275CC5788063A5F19741120C4F2DE2ADEBEB" | |||
| "10A298DD" | "10A298DD" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | |||
| SHA384HashSize, SHA512HashSize } | SHA384HashSize, SHA512HashSize } | |||
| }, | }, | |||
| { /* 5 */ { | { /* 5 */ { | |||
| "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" | "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c" | |||
| "\x0c\x0c\x0c\x0c\x0c" | "\x0c\x0c\x0c\x0c\x0c" | |||
| }, { 20 }, { | }, { 20 }, { | |||
| "Test With Truncation" | "Test With Truncation" | |||
| }, { 20 }, { | }, { 20 }, { | |||
| /* HMAC-SHA-1 */ | /* HMAC-SHA-1 */ | |||
| skipping to change at page 101, line 4 ¶ | skipping to change at page 99, line 53 ¶ | |||
| /* HMAC-SHA-224 */ | /* HMAC-SHA-224 */ | |||
| "95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7273FA6870E", | "95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7273FA6870E", | |||
| /* HMAC-SHA-256 */ | /* HMAC-SHA-256 */ | |||
| "60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5140546040F0EE3" | "60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5140546040F0EE3" | |||
| "7F54", | "7F54", | |||
| /* HMAC-SHA-384 */ | /* HMAC-SHA-384 */ | |||
| "4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B588F3CD11F05033A" | "4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B588F3CD11F05033A" | |||
| "C4C60C2EF6AB4030FE8296248DF163F44952", | "C4C60C2EF6AB4030FE8296248DF163F44952", | |||
| /* HMAC-SHA-512 */ | /* HMAC-SHA-512 */ | |||
| "80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEEC1121B013783F8" | "80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEEC1121B013783F8" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "F3526B56D037E05F2598BD0FD2215D6A1E5295E64F73F63F0AEC8B915A98" | "F3526B56D037E05F2598BD0FD2215D6A1E5295E64F73F63F0AEC8B915A98" | |||
| "5D786598" | "5D786598" | |||
| }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | |||
| SHA384HashSize, SHA512HashSize } | SHA384HashSize, SHA512HashSize } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| }, | }, | |||
| { /* 7 */ { | { /* 7 */ { | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa" | |||
| skipping to change at page 102, line 4 ¶ | skipping to change at page 100, line 53 ¶ | |||
| /* HMAC-SHA-384 */ | /* HMAC-SHA-384 */ | |||
| "6617178E941F020D351E2F254E8FD32C602420FEB0B8FB9ADCCEBB82461E" | "6617178E941F020D351E2F254E8FD32C602420FEB0B8FB9ADCCEBB82461E" | |||
| "99C5A678CC31E799176D3860E6110C46523E", | "99C5A678CC31E799176D3860E6110C46523E", | |||
| /* HMAC-SHA-512 */ | /* HMAC-SHA-512 */ | |||
| "E37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289865DF5A32D20CD" | "E37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289865DF5A32D20CD" | |||
| "C944B6022CAC3C4982B10D5EEB55C3E4DE15134676FB6DE0446065C97440" | "C944B6022CAC3C4982B10D5EEB55C3E4DE15134676FB6DE0446065C97440" | |||
| "FA8C6A58" | "FA8C6A58" | |||
| }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | }, { SHA1HashSize, SHA224HashSize, SHA256HashSize, | |||
| SHA384HashSize, SHA512HashSize } | SHA384HashSize, SHA512HashSize } | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| }; | }; | |||
| /* Test arrays for HKDF. */ | /* Test arrays for HKDF. */ | |||
| struct hkdfhash { | struct hkdfhash { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| SHAversion whichSha; | SHAversion whichSha; | |||
| int ikmlength; | int ikmlength; | |||
| const char *ikmarray; | const char *ikmarray; | |||
| int saltlength; | int saltlength; | |||
| const char *saltarray; | const char *saltarray; | |||
| int infolength; | int infolength; | |||
| const char *infoarray; | const char *infoarray; | |||
| int prklength; | int prklength; | |||
| const char *prkarray; | const char *prkarray; | |||
| int okmlength; | int okmlength; | |||
| skipping to change at page 103, line 4 ¶ | skipping to change at page 101, line 52 ¶ | |||
| "\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", | "\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf", | |||
| 80, "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd" | 80, "\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd" | |||
| "\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb" | "\xbe\xbf\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb" | |||
| "\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9" | "\xcc\xcd\xce\xcf\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9" | |||
| "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7" | "\xda\xdb\xdc\xdd\xde\xdf\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7" | |||
| "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5" | "\xe8\xe9\xea\xeb\xec\xed\xee\xef\xf0\xf1\xf2\xf3\xf4\xf5" | |||
| "\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", | "\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff", | |||
| 32, "06A6B88C5853361A06104C9CEB35B45C" | 32, "06A6B88C5853361A06104C9CEB35B45C" | |||
| "EF760014904671014A193F40C15FC244", | "EF760014904671014A193F40C15FC244", | |||
| 82, "B11E398DC80327A1C8E7F78C596A4934" | 82, "B11E398DC80327A1C8E7F78C596A4934" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "4F012EDA2D4EFAD8A050CC4C19AFA97C" | "4F012EDA2D4EFAD8A050CC4C19AFA97C" | |||
| "59045A99CAC7827271CB41C65E590E09" | "59045A99CAC7827271CB41C65E590E09" | |||
| "DA3275600C2F09B8367793A9ACA3DB71" | "DA3275600C2F09B8367793A9ACA3DB71" | |||
| "CC30C58179EC3E87C14C01D5C1F3434F" | "CC30C58179EC3E87C14C01D5C1F3434F" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "1D87" | "1D87" | |||
| }, | }, | |||
| { /* RFC 5869 A.3. Test Case 3 */ | { /* RFC 5869 A.3. Test Case 3 */ | |||
| SHA256, | SHA256, | |||
| 22, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | 22, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | |||
| "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", | "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", | |||
| 0, "", | 0, "", | |||
| 0, "", | 0, "", | |||
| 32, "19EF24A32C717B167F33A91D6F648BDF" | 32, "19EF24A32C717B167F33A91D6F648BDF" | |||
| "96596776AFDB6377AC434C1C293CCB04", | "96596776AFDB6377AC434C1C293CCB04", | |||
| skipping to change at page 104, line 4 ¶ | skipping to change at page 102, line 53 ¶ | |||
| "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5" | "\x98\x99\x9A\x9B\x9C\x9D\x9E\x9F\xA0\xA1\xA2\xA3\xA4\xA5" | |||
| "\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", | "\xA6\xA7\xA8\xA9\xAA\xAB\xAC\xAD\xAE\xAF", | |||
| 80, "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD" | 80, "\xB0\xB1\xB2\xB3\xB4\xB5\xB6\xB7\xB8\xB9\xBA\xBB\xBC\xBD" | |||
| "\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB" | "\xBE\xBF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB" | |||
| "\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9" | "\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD7\xD8\xD9" | |||
| "\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7" | "\xDA\xDB\xDC\xDD\xDE\xDF\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7" | |||
| "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5" | "\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5" | |||
| "\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", | "\xF6\xF7\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xFF", | |||
| 20, "8ADAE09A2A307059478D309B26C4115A224CFAF6", | 20, "8ADAE09A2A307059478D309B26C4115A224CFAF6", | |||
| 82, "0BD770A74D1160F7C9F12CD5912A06EB" | 82, "0BD770A74D1160F7C9F12CD5912A06EB" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "FF6ADCAE899D92191FE4305673BA2FFE" | "FF6ADCAE899D92191FE4305673BA2FFE" | |||
| "8FA3F1A4E5AD79F3F334B3B202B2173C" | "8FA3F1A4E5AD79F3F334B3B202B2173C" | |||
| "486EA37CE3D397ED034C7F9DFEB15C5E" | "486EA37CE3D397ED034C7F9DFEB15C5E" | |||
| "927336D0441F4C4300E2CFF0D0900B52" | "927336D0441F4C4300E2CFF0D0900B52" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "D3B4" | "D3B4" | |||
| }, | }, | |||
| { /* RFC 5869 A.6. Test Case 6 */ | { /* RFC 5869 A.6. Test Case 6 */ | |||
| SHA1, | SHA1, | |||
| 22, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | 22, "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b" | |||
| "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", | "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b", | |||
| 0, "", | 0, "", | |||
| 0, "", | 0, "", | |||
| 20, "DA8C8A73C7FA77288EC6F5E7C297786AA0D32D01", | 20, "DA8C8A73C7FA77288EC6F5E7C297786AA0D32D01", | |||
| 42, "0AC1AF7002B3D761D1E55298DA9D0506" | 42, "0AC1AF7002B3D761D1E55298DA9D0506" | |||
| skipping to change at page 105, line 4 ¶ | skipping to change at page 103, line 53 ¶ | |||
| return 0; | return 0; | |||
| if (*hexstr++ != hexdigits[hashvalue[i] & 0xF]) return 0; | if (*hexstr++ != hexdigits[hashvalue[i] & 0xF]) return 0; | |||
| } | } | |||
| return 1; | return 1; | |||
| } | } | |||
| /* | /* | |||
| * Print the string, converting non-printable characters to "." | * Print the string, converting non-printable characters to "." | |||
| */ | */ | |||
| void printstr(const char *str, int len) | void printstr(const char *str, int len) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { | { | |||
| for ( ; len-- > 0; str++) | for ( ; len-- > 0; str++) | |||
| putchar(isprint((unsigned char)*str) ? *str : '.'); | putchar(isprint((unsigned char)*str) ? *str : '.'); | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Print the string, converting all characters to hex "## ". | * Print the string, converting all characters to hex "## ". | |||
| */ | */ | |||
| void printxstr(const char *str, int len) | void printxstr(const char *str, int len) | |||
| { | { | |||
| char *sep = ""; | char *sep = ""; | |||
| for ( ; len-- > 0; str++) { | for ( ; len-- > 0; str++) { | |||
| printf("%s%c%c", sep, hexdigits[(*str >> 4) & 0xF], | printf("%s%c%c", sep, hexdigits[(*str >> 4) & 0xF], | |||
| hexdigits[*str & 0xF]); | hexdigits[*str & 0xF]); | |||
| skipping to change at page 106, line 4 ¶ | skipping to change at page 104, line 51 ¶ | |||
| "\t%s [-m | -d] [-l loopcount] [-t test#] [-e]\n" | "\t%s [-m | -d] [-l loopcount] [-t test#] [-e]\n" | |||
| "\t\t[-r randomseed] [-R randomloop-count] " | "\t\t[-r randomseed] [-R randomloop-count] " | |||
| "[-p] [-P|-X]\n" | "[-p] [-P|-X]\n" | |||
| "-h\thash to test: " | "-h\thash to test: " | |||
| "0|SHA1, 1|SHA224, 2|SHA256, 3|SHA384, 4|SHA512\n" | "0|SHA1, 1|SHA224, 2|SHA256, 3|SHA384, 4|SHA512\n" | |||
| "-m\tperform hmac standard tests\n" | "-m\tperform hmac standard tests\n" | |||
| "-k\tkey for hmac test\n" | "-k\tkey for hmac test\n" | |||
| "-d\tperform hkdf standard tests\n" | "-d\tperform hkdf standard tests\n" | |||
| "-t\ttest case to run, 1-10\n" | "-t\ttest case to run, 1-10\n" | |||
| "-l\thow many times to run the test\n" | "-l\thow many times to run the test\n" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "-e\ttest error returns\n" | "-e\ttest error returns\n" | |||
| "-p\tdo not print results\n" | "-p\tdo not print results\n" | |||
| "-P\tdo not print PASSED/FAILED\n" | "-P\tdo not print PASSED/FAILED\n" | |||
| "-X\tprint FAILED, but not PASSED\n" | "-X\tprint FAILED, but not PASSED\n" | |||
| "-r\tseed for random test\n" | "-r\tseed for random test\n" | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| "-R\thow many times to run random test\n" | "-R\thow many times to run random test\n" | |||
| "-s\tstring to hash\n" | "-s\tstring to hash\n" | |||
| "-S\texpected result of hashed string, in hex\n" | "-S\texpected result of hashed string, in hex\n" | |||
| "-w\toutput hash in raw format\n" | "-w\toutput hash in raw format\n" | |||
| "-x\toutput hash in hex format\n" | "-x\toutput hash in hex format\n" | |||
| "-6\toutput hash in base64 format\n" | "-6\toutput hash in base64 format\n" | |||
| "-B\t# extra bits to add in after string or file input\n" | "-B\t# extra bits to add in after string or file input\n" | |||
| "-b\textra bits to add (high order bits of #, 0# or 0x#)\n" | "-b\textra bits to add (high order bits of #, 0# or 0x#)\n" | |||
| "-H\tinput hashstr or randomseed is in hex\n" | "-H\tinput hashstr or randomseed is in hex\n" | |||
| , argv0, argv0, argv0, argv0); | , argv0, argv0, argv0, argv0); | |||
| skipping to change at page 107, line 4 ¶ | skipping to change at page 105, line 52 ¶ | |||
| putchar(hexdigits[Message_Digest[i] & 0xF]); | putchar(hexdigits[Message_Digest[i] & 0xF]); | |||
| } | } | |||
| putchar('\n'); | putchar('\n'); | |||
| } else if (printResults == PRINTBASE64) { | } else if (printResults == PRINTBASE64) { | |||
| unsigned char b; | unsigned char b; | |||
| char *sm = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | char *sm = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" | |||
| "0123456789+/"; | "0123456789+/"; | |||
| for (i = 0; i < hashsize; i += 3) { | for (i = 0; i < hashsize; i += 3) { | |||
| putchar(sm[Message_Digest[i] >> 2]); | putchar(sm[Message_Digest[i] >> 2]); | |||
| b = (Message_Digest[i] & 0x03) << 4; | b = (Message_Digest[i] & 0x03) << 4; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (i+1 < hashsize) b |= Message_Digest[i+1] >> 4; | if (i+1 < hashsize) b |= Message_Digest[i+1] >> 4; | |||
| putchar(sm[b]); | putchar(sm[b]); | |||
| if (i+1 < hashsize) { | if (i+1 < hashsize) { | |||
| b = (Message_Digest[i+1] & 0x0f) << 2; | b = (Message_Digest[i+1] & 0x0f) << 2; | |||
| if (i+2 < hashsize) b |= Message_Digest[i+2] >> 6; | if (i+2 < hashsize) b |= Message_Digest[i+2] >> 6; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| putchar(sm[b]); | putchar(sm[b]); | |||
| } else putchar('='); | } else putchar('='); | |||
| if (i+2 < hashsize) putchar(sm[Message_Digest[i+2] & 0x3f]); | if (i+2 < hashsize) putchar(sm[Message_Digest[i+2] & 0x3f]); | |||
| else putchar('='); | else putchar('='); | |||
| } | } | |||
| putchar('\n'); | putchar('\n'); | |||
| } | } | |||
| if (printResults && resultarray) { | if (printResults && resultarray) { | |||
| printf(" Should match:\n\t"); | printf(" Should match:\n\t"); | |||
| skipping to change at page 108, line 5 ¶ | skipping to change at page 106, line 53 ¶ | |||
| int printPassFail) | int printPassFail) | |||
| { | { | |||
| USHAContext sha; | USHAContext sha; | |||
| HMACContext hmac; | HMACContext hmac; | |||
| HKDFContext hkdf; | HKDFContext hkdf; | |||
| int err, i; | int err, i; | |||
| uint8_t Message_Digest_Buf[USHAMaxHashSize]; | uint8_t Message_Digest_Buf[USHAMaxHashSize]; | |||
| uint8_t *Message_Digest = Message_Digest_Buf; | uint8_t *Message_Digest = Message_Digest_Buf; | |||
| char buf[20]; | char buf[20]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (printResults == PRINTTEXT) { | if (printResults == PRINTTEXT) { | |||
| printf("\nTest %d: Iteration %d, Repeat %ld\n\t'", testno+1, | printf("\nTest %d: Iteration %d, Repeat %ld\n\t'", testno+1, | |||
| loopno, repeatcount); | loopno, repeatcount); | |||
| printstr(testarray, length); | printstr(testarray, length); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| printf("'\n\t'"); | printf("'\n\t'"); | |||
| printxstr(testarray, length); | printxstr(testarray, length); | |||
| printf("'\n"); | printf("'\n"); | |||
| printf(" Length=%d bytes (%d bits), ", length, length * 8); | printf(" Length=%d bytes (%d bits), ", length, length * 8); | |||
| printf("ExtraBits %d: %2.2x\n", numberExtrabits, extrabits); | printf("ExtraBits %d: %2.2x\n", numberExtrabits, extrabits); | |||
| } | } | |||
| if (info) Message_Digest = malloc(okmlen); | if (info) Message_Digest = malloc(okmlen); | |||
| memset(&sha, '\343', sizeof(sha)); /* force bad data into struct */ | memset(&sha, '\343', sizeof(sha)); /* force bad data into struct */ | |||
| memset(&hmac, '\343', sizeof(hmac)); | memset(&hmac, '\343', sizeof(hmac)); | |||
| skipping to change at page 109, line 4 ¶ | skipping to change at page 107, line 53 ¶ | |||
| err = info ? hkdfFinalBits(&hkdf, extrabits, numberExtrabits) : | err = info ? hkdfFinalBits(&hkdf, extrabits, numberExtrabits) : | |||
| keyarray ? hmacFinalBits(&hmac, (uint8_t) extrabits, | keyarray ? hmacFinalBits(&hmac, (uint8_t) extrabits, | |||
| numberExtrabits) : | numberExtrabits) : | |||
| USHAFinalBits(&sha, (uint8_t) extrabits, | USHAFinalBits(&sha, (uint8_t) extrabits, | |||
| numberExtrabits); | numberExtrabits); | |||
| if (err != shaSuccess) { | if (err != shaSuccess) { | |||
| fprintf(stderr, "hash(): %sFinalBits Error %d.\n", | fprintf(stderr, "hash(): %sFinalBits Error %d.\n", | |||
| info ? "hkdf" : keyarray ? "hmac" : "sha", err); | info ? "hkdf" : keyarray ? "hmac" : "sha", err); | |||
| return err; | return err; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| err = info ? hkdfResult(&hkdf, 0, info, infolen, | err = info ? hkdfResult(&hkdf, 0, info, infolen, | |||
| Message_Digest, okmlen) : | Message_Digest, okmlen) : | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| keyarray ? hmacResult(&hmac, Message_Digest) : | keyarray ? hmacResult(&hmac, Message_Digest) : | |||
| USHAResult(&sha, Message_Digest); | USHAResult(&sha, Message_Digest); | |||
| if (err != shaSuccess) { | if (err != shaSuccess) { | |||
| fprintf(stderr, "hash(): %s Result Error %d, could not compute " | fprintf(stderr, "hash(): %s Result Error %d, could not compute " | |||
| "message digest.\n", | "message digest.\n", | |||
| info ? "hkdf" : keyarray ? "hmac" : "sha", err); | info ? "hkdf" : keyarray ? "hmac" : "sha", err); | |||
| return err; | return err; | |||
| } | } | |||
| sprintf(buf, "%d", testno+1); | sprintf(buf, "%d", testno+1); | |||
| skipping to change at page 110, line 4 ¶ | skipping to change at page 108, line 53 ¶ | |||
| printxstr(hkdfhashes[testno].ikmarray, | printxstr(hkdfhashes[testno].ikmarray, | |||
| hkdfhashes[testno].ikmlength); | hkdfhashes[testno].ikmlength); | |||
| printf("'\n\tINFO\t'"); | printf("'\n\tINFO\t'"); | |||
| printxstr(hkdfhashes[testno].infoarray, | printxstr(hkdfhashes[testno].infoarray, | |||
| hkdfhashes[testno].infolength); | hkdfhashes[testno].infolength); | |||
| printf("'\n"); | printf("'\n"); | |||
| printf(" L=%d bytes\n", hkdfhashes[testno].okmlength); | printf(" L=%d bytes\n", hkdfhashes[testno].okmlength); | |||
| } | } | |||
| /* Run hkdf() against the test vectors */ | /* Run hkdf() against the test vectors */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| err = hkdf(hkdfhashes[testno].whichSha, | err = hkdf(hkdfhashes[testno].whichSha, | |||
| (const uint8_t *) hkdfhashes[testno].saltarray, | (const uint8_t *) hkdfhashes[testno].saltarray, | |||
| hkdfhashes[testno].saltlength, | hkdfhashes[testno].saltlength, | |||
| (const uint8_t *) hkdfhashes[testno].ikmarray, | (const uint8_t *) hkdfhashes[testno].ikmarray, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| hkdfhashes[testno].ikmlength, | hkdfhashes[testno].ikmlength, | |||
| (const uint8_t *) hkdfhashes[testno].infoarray, | (const uint8_t *) hkdfhashes[testno].infoarray, | |||
| hkdfhashes[testno].infolength, okm, | hkdfhashes[testno].infolength, okm, | |||
| hkdfhashes[testno].okmlength); | hkdfhashes[testno].okmlength); | |||
| if (err != shaSuccess) { | if (err != shaSuccess) { | |||
| fprintf(stderr, "hashHkdf(): hkdf Error %d.\n", err); | fprintf(stderr, "hashHkdf(): hkdf Error %d.\n", err); | |||
| return err; | return err; | |||
| } | } | |||
| sprintf(buf, "hkdf %d", testno+1); | sprintf(buf, "hkdf %d", testno+1); | |||
| printResult(okm, hkdfhashes[testno].okmlength, | printResult(okm, hkdfhashes[testno].okmlength, | |||
| skipping to change at page 111, line 4 ¶ | skipping to change at page 109, line 53 ¶ | |||
| fprintf(stderr, "hashHkdf(): hkdfExpand Error %d.\n", err); | fprintf(stderr, "hashHkdf(): hkdfExpand Error %d.\n", err); | |||
| return err; | return err; | |||
| } | } | |||
| sprintf(buf, "hkdfExpand %d", testno+1); | sprintf(buf, "hkdfExpand %d", testno+1); | |||
| printResult(okm, hkdfhashes[testno].okmlength, | printResult(okm, hkdfhashes[testno].okmlength, | |||
| USHAHashName(hkdfhashes[testno].whichSha), "hkdf standard test", | USHAHashName(hkdfhashes[testno].whichSha), "hkdf standard test", | |||
| buf, hkdfhashes[testno].okmarray, printResults, printPassFail); | buf, hkdfhashes[testno].okmarray, printResults, printPassFail); | |||
| return err; | return err; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Exercise a hash series of functions. The input is a filename. | * Exercise a hash series of functions. The input is a filename. | |||
| * If the result is known, it is in resultarray in uppercase hex. | * If the result is known, it is in resultarray in uppercase hex. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| */ | */ | |||
| int hashfile(int hashno, const char *hashfilename, int bits, | int hashfile(int hashno, const char *hashfilename, int bits, | |||
| int bitcount, int skipSpaces, const unsigned char *keyarray, | int bitcount, int skipSpaces, const unsigned char *keyarray, | |||
| int keylen, const unsigned char *info, int infolen, int okmlen, | int keylen, const unsigned char *info, int infolen, int okmlen, | |||
| const char *resultarray, int hashsize, | const char *resultarray, int hashsize, | |||
| int printResults, int printPassFail) | int printResults, int printPassFail) | |||
| { | { | |||
| USHAContext sha; | USHAContext sha; | |||
| HMACContext hmac; | HMACContext hmac; | |||
| HKDFContext hkdf; | HKDFContext hkdf; | |||
| skipping to change at page 112, line 4 ¶ | skipping to change at page 110, line 54 ¶ | |||
| if (skipSpaces) | if (skipSpaces) | |||
| while ((c = getc(hashfp)) != EOF) { | while ((c = getc(hashfp)) != EOF) { | |||
| if (!isspace(c)) { | if (!isspace(c)) { | |||
| cc = (unsigned char)c; | cc = (unsigned char)c; | |||
| err = info ? hkdfInput(&hkdf, &cc, 1) : | err = info ? hkdfInput(&hkdf, &cc, 1) : | |||
| keyarray ? hmacInput(&hmac, &cc, 1) : | keyarray ? hmacInput(&hmac, &cc, 1) : | |||
| USHAInput(&sha, &cc, 1); | USHAInput(&sha, &cc, 1); | |||
| if (err != shaSuccess) { | if (err != shaSuccess) { | |||
| fprintf(stderr, "hashfile(): %sInput Error %d.\n", | fprintf(stderr, "hashfile(): %sInput Error %d.\n", | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| info ? "hkdf" : keyarray ? "hmac" : "sha", err); | info ? "hkdf" : keyarray ? "hmac" : "sha", err); | |||
| if (hashfp != stdin) fclose(hashfp); | if (hashfp != stdin) fclose(hashfp); | |||
| return err; | return err; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| } | } | |||
| } | } | |||
| else | else | |||
| while ((nread = fread(buf, 1, sizeof(buf), hashfp)) > 0) { | while ((nread = fread(buf, 1, sizeof(buf), hashfp)) > 0) { | |||
| err = info ? hkdfInput(&hkdf, buf, nread) : | err = info ? hkdfInput(&hkdf, buf, nread) : | |||
| keyarray ? hmacInput(&hmac, buf, nread) : | keyarray ? hmacInput(&hmac, buf, nread) : | |||
| USHAInput(&sha, buf, nread); | USHAInput(&sha, buf, nread); | |||
| if (err != shaSuccess) { | if (err != shaSuccess) { | |||
| fprintf(stderr, "hashfile(): %s Error %d.\n", | fprintf(stderr, "hashfile(): %s Error %d.\n", | |||
| skipping to change at page 113, line 4 ¶ | skipping to change at page 111, line 54 ¶ | |||
| if (hashfp != stdin) fclose(hashfp); | if (hashfp != stdin) fclose(hashfp); | |||
| return err; | return err; | |||
| } | } | |||
| printResult(Message_Digest, info ? okmlen : hashsize, | printResult(Message_Digest, info ? okmlen : hashsize, | |||
| hashes[hashno].name, "file", hashfilename, resultarray, | hashes[hashno].name, "file", hashfilename, resultarray, | |||
| printResults, printPassFail); | printResults, printPassFail); | |||
| if (hashfp != stdin) fclose(hashfp); | if (hashfp != stdin) fclose(hashfp); | |||
| if (info) free(Message_Digest); | if (info) free(Message_Digest); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return err; | return err; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Exercise a hash series of functions through multiple permutations. | * Exercise a hash series of functions through multiple permutations. | |||
| * The input is an initial seed. That seed is replicated 3 times. | * The input is an initial seed. That seed is replicated 3 times. | |||
| * For 1000 rounds, the previous three results are used as the input. | * For 1000 rounds, the previous three results are used as the input. | |||
| * This result is then checked, and used to seed the next cycle. | * This result is then checked, and used to seed the next cycle. | |||
| * If the result is known, it is in resultarrays in uppercase hex. | * If the result is known, it is in resultarrays in uppercase hex. | |||
| */ | */ | |||
| void randomtest(int hashno, const char *seed, int hashsize, | void randomtest(int hashno, const char *seed, int hashsize, | |||
| const char **resultarrays, int randomcount, | const char **resultarrays, int randomcount, | |||
| skipping to change at page 114, line 4 ¶ | skipping to change at page 112, line 53 ¶ | |||
| } | } | |||
| /* MDj = Seed = MDi; */ | /* MDj = Seed = MDi; */ | |||
| memcpy(SEED, MD[i-1], hashsize); | memcpy(SEED, MD[i-1], hashsize); | |||
| /* OUTPUT: MDj */ | /* OUTPUT: MDj */ | |||
| sprintf(buf, "%d", j); | sprintf(buf, "%d", j); | |||
| printResult(SEED, hashsize, hashes[hashno].name, "random test", | printResult(SEED, hashsize, hashes[hashno].name, "random test", | |||
| buf, resultarrays ? resultarrays[j] : 0, printResults, | buf, resultarrays ? resultarrays[j] : 0, printResults, | |||
| (j < RANDOMCOUNT) ? printPassFail : 0); | (j < RANDOMCOUNT) ? printPassFail : 0); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * Look up a hash name. | * Look up a hash name. | |||
| */ | */ | |||
| int findhash(const char *argv0, const char *opt) | int findhash(const char *argv0, const char *opt) | |||
| { | { | |||
| int i; | int i; | |||
| const char *names[HASHCOUNT][2] = { | const char *names[HASHCOUNT][2] = { | |||
| { "0", "sha1" }, { "1", "sha224" }, { "2", "sha256" }, | { "0", "sha1" }, { "1", "sha224" }, { "2", "sha256" }, | |||
| { "3", "sha384" }, { "4", "sha512" } | { "3", "sha384" }, { "4", "sha512" } | |||
| skipping to change at page 115, line 4 ¶ | skipping to change at page 113, line 53 ¶ | |||
| printf ("\nError %d. Should be %d.\n", err, shaStateError); | printf ("\nError %d. Should be %d.\n", err, shaStateError); | |||
| if ((printPassFail == PRINTPASSFAIL) || | if ((printPassFail == PRINTPASSFAIL) || | |||
| ((printPassFail == PRINTFAIL) && (err != shaStateError))) | ((printPassFail == PRINTFAIL) && (err != shaStateError))) | |||
| printf("%s se: %s\n", hashes[hashno].name, | printf("%s se: %s\n", hashes[hashno].name, | |||
| (err == shaStateError) ? "PASSED" : "FAILED"); | (err == shaStateError) ? "PASSED" : "FAILED"); | |||
| err = USHAFinalBits(&usha, 0x80, 3); | err = USHAFinalBits(&usha, 0x80, 3); | |||
| if (printResults == PRINTTEXT) | if (printResults == PRINTTEXT) | |||
| printf ("\nError %d. Should be %d.\n", err, shaStateError); | printf ("\nError %d. Should be %d.\n", err, shaStateError); | |||
| if ((printPassFail == PRINTPASSFAIL) || | if ((printPassFail == PRINTPASSFAIL) || | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| ((printPassFail == PRINTFAIL) && (err != shaStateError))) | ((printPassFail == PRINTFAIL) && (err != shaStateError))) | |||
| printf("%s se: %s\n", hashes[hashno].name, | printf("%s se: %s\n", hashes[hashno].name, | |||
| (err == shaStateError) ? "PASSED" : "FAILED"); | (err == shaStateError) ? "PASSED" : "FAILED"); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| err = USHAReset(0, hashes[hashno].whichSha); | err = USHAReset(0, hashes[hashno].whichSha); | |||
| if (printResults == PRINTTEXT) | if (printResults == PRINTTEXT) | |||
| printf("\nError %d. Should be %d.\n", err, shaNull); | printf("\nError %d. Should be %d.\n", err, shaNull); | |||
| if ((printPassFail == PRINTPASSFAIL) || | if ((printPassFail == PRINTPASSFAIL) || | |||
| ((printPassFail == PRINTFAIL) && (err != shaNull))) | ((printPassFail == PRINTFAIL) && (err != shaNull))) | |||
| printf("%s usha null: %s\n", hashes[hashno].name, | printf("%s usha null: %s\n", hashes[hashno].name, | |||
| (err == shaNull) ? "PASSED" : "FAILED"); | (err == shaNull) ? "PASSED" : "FAILED"); | |||
| switch (hashno) { | switch (hashno) { | |||
| case SHA1: err = SHA1Reset(0); break; | case SHA1: err = SHA1Reset(0); break; | |||
| skipping to change at page 116, line 4 ¶ | skipping to change at page 114, line 53 ¶ | |||
| printf("\nError: bad hex character '%c'\n", *hexstr); | printf("\nError: bad hex character '%c'\n", *hexstr); | |||
| } | } | |||
| if (!*++hexstr) break; | if (!*++hexstr) break; | |||
| if (isalpha((int)(unsigned char)(*hexstr))) { | if (isalpha((int)(unsigned char)(*hexstr))) { | |||
| nibble2 = tolower(*hexstr) - 'a' + 10; | nibble2 = tolower(*hexstr) - 'a' + 10; | |||
| } else if (isdigit((int)(unsigned char)(*hexstr))) { | } else if (isdigit((int)(unsigned char)(*hexstr))) { | |||
| nibble2 = *hexstr - '0'; | nibble2 = *hexstr - '0'; | |||
| } else { | } else { | |||
| printf("\nError: bad hex character '%c'\n", *hexstr); | printf("\nError: bad hex character '%c'\n", *hexstr); | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| *o++ = (char)((nibble1 << 4) | nibble2); | *o++ = (char)((nibble1 << 4) | nibble2); | |||
| len++; | len++; | |||
| } | } | |||
| return len; | return len; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| int main(int argc, char **argv) | int main(int argc, char **argv) | |||
| { | { | |||
| int i, err; | int i, err; | |||
| int loopno, loopnohigh = 1; | int loopno, loopnohigh = 1; | |||
| int hashno, hashnolow = 0, hashnohigh = HASHCOUNT - 1; | int hashno, hashnolow = 0, hashnohigh = HASHCOUNT - 1; | |||
| int testno, testnolow = 0, testnohigh; | int testno, testnolow = 0, testnohigh; | |||
| int ntestnohigh = 0; | int ntestnohigh = 0; | |||
| int printResults = PRINTTEXT; | int printResults = PRINTTEXT; | |||
| skipping to change at page 117, line 4 ¶ | skipping to change at page 115, line 53 ¶ | |||
| case 'F': hashFilename = optarg; break; | case 'F': hashFilename = optarg; break; | |||
| case 'h': hashnolow = hashnohigh = findhash(argv[0], optarg); | case 'h': hashnolow = hashnohigh = findhash(argv[0], optarg); | |||
| break; | break; | |||
| case 'H': strIsHex = 1; break; | case 'H': strIsHex = 1; break; | |||
| case 'i': info = optarg; infolen = strlen(optarg); break; | case 'i': info = optarg; infolen = strlen(optarg); break; | |||
| case 'k': hmacKey = optarg; hmaclen = strlen(optarg); break; | case 'k': hmacKey = optarg; hmaclen = strlen(optarg); break; | |||
| case 'l': loopnohigh = atoi(optarg); break; | case 'l': loopnohigh = atoi(optarg); break; | |||
| case 'L': okmlen = strtol(optarg, 0, 0); break; | case 'L': okmlen = strtol(optarg, 0, 0); break; | |||
| case 'm': runHmacTests = 1; break; | case 'm': runHmacTests = 1; break; | |||
| case 'P': printPassFail = 0; break; | case 'P': printPassFail = 0; break; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| case 'p': printResults = PRINTNONE; break; | case 'p': printResults = PRINTNONE; break; | |||
| case 'R': randomcount = atoi(optarg); break; | case 'R': randomcount = atoi(optarg); break; | |||
| case 'r': randomseedstr = optarg; break; | case 'r': randomseedstr = optarg; break; | |||
| case 's': hashstr = optarg; hashlen = strlen(hashstr); break; | case 's': hashstr = optarg; hashlen = strlen(hashstr); break; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| case 'S': resultstr = optarg; break; | case 'S': resultstr = optarg; break; | |||
| case 't': testnolow = ntestnohigh = atoi(optarg) - 1; break; | case 't': testnolow = ntestnohigh = atoi(optarg) - 1; break; | |||
| case 'w': printResults = PRINTRAW; break; | case 'w': printResults = PRINTRAW; break; | |||
| case 'x': printResults = PRINTHEX; break; | case 'x': printResults = PRINTHEX; break; | |||
| case 'X': printPassFail = 2; break; | case 'X': printPassFail = 2; break; | |||
| case '6': printResults = PRINTBASE64; break; | case '6': printResults = PRINTBASE64; break; | |||
| default: usage(argv[0]); | default: usage(argv[0]); | |||
| } | } | |||
| if (strIsHex) { | if (strIsHex) { | |||
| skipping to change at page 118, line 5 ¶ | skipping to change at page 116, line 54 ¶ | |||
| err = shaSuccess; | err = shaSuccess; | |||
| for (loopno = 1; (loopno <= loopnohigh) && (err == shaSuccess); | for (loopno = 1; (loopno <= loopnohigh) && (err == shaSuccess); | |||
| ++loopno) { | ++loopno) { | |||
| if (hashstr) | if (hashstr) | |||
| err = hash(0, loopno, hashno, hashstr, hashlen, 1, | err = hash(0, loopno, hashno, hashstr, hashlen, 1, | |||
| numberExtrabits, extrabits, (const unsigned char *)hmacKey, | numberExtrabits, extrabits, (const unsigned char *)hmacKey, | |||
| hmaclen, (const uint8_t *) info, infolen, okmlen, resultstr, | hmaclen, (const uint8_t *) info, infolen, okmlen, resultstr, | |||
| hashes[hashno].hashsize, printResults, printPassFail); | hashes[hashno].hashsize, printResults, printPassFail); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| else if (randomseedstr) | else if (randomseedstr) | |||
| randomtest(hashno, randomseedstr, hashes[hashno].hashsize, 0, | randomtest(hashno, randomseedstr, hashes[hashno].hashsize, 0, | |||
| randomcount, printResults, printPassFail); | randomcount, printResults, printPassFail); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| else if (hashfilename) | else if (hashfilename) | |||
| err = hashfile(hashno, hashfilename, extrabits, | err = hashfile(hashno, hashfilename, extrabits, | |||
| numberExtrabits, 0, | numberExtrabits, 0, | |||
| (const unsigned char *)hmacKey, hmaclen, | (const unsigned char *)hmacKey, hmaclen, | |||
| (const uint8_t *) info, infolen, okmlen, | (const uint8_t *) info, infolen, okmlen, | |||
| resultstr, hashes[hashno].hashsize, | resultstr, hashes[hashno].hashsize, | |||
| printResults, printPassFail); | printResults, printPassFail); | |||
| else if (hashFilename) | else if (hashFilename) | |||
| err = hashfile(hashno, hashFilename, extrabits, | err = hashfile(hashno, hashFilename, extrabits, | |||
| skipping to change at page 119, line 4 ¶ | skipping to change at page 117, line 53 ¶ | |||
| hmachashes[testno].keyarray[1] : | hmachashes[testno].keyarray[1] : | |||
| hmachashes[testno].keyarray[0]), | hmachashes[testno].keyarray[0]), | |||
| hmachashes[testno].keylength[hashno] ? | hmachashes[testno].keylength[hashno] ? | |||
| hmachashes[testno].keylength[hashno] : | hmachashes[testno].keylength[hashno] : | |||
| hmachashes[testno].keylength[1] ? | hmachashes[testno].keylength[1] ? | |||
| hmachashes[testno].keylength[1] : | hmachashes[testno].keylength[1] : | |||
| hmachashes[testno].keylength[0], | hmachashes[testno].keylength[0], | |||
| 0, 0, 0, | 0, 0, 0, | |||
| hmachashes[testno].resultarray[hashno], | hmachashes[testno].resultarray[hashno], | |||
| hmachashes[testno].resultlength[hashno], | hmachashes[testno].resultlength[hashno], | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| printResults, printPassFail); | printResults, printPassFail); | |||
| } else if (runHkdfTests) { | } else if (runHkdfTests) { | |||
| err = hashHkdf(testno, loopno, hashno, | err = hashHkdf(testno, loopno, hashno, | |||
| printResults, printPassFail); | printResults, printPassFail); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } else { /* sha tests */ | } else { /* sha tests */ | |||
| err = hash(testno, loopno, hashno, | err = hash(testno, loopno, hashno, | |||
| hashes[hashno].tests[testno].testarray, | hashes[hashno].tests[testno].testarray, | |||
| hashes[hashno].tests[testno].length, | hashes[hashno].tests[testno].length, | |||
| hashes[hashno].tests[testno].repeatcount, | hashes[hashno].tests[testno].repeatcount, | |||
| hashes[hashno].tests[testno].numberExtrabits, | hashes[hashno].tests[testno].numberExtrabits, | |||
| hashes[hashno].tests[testno].extrabits, | hashes[hashno].tests[testno].extrabits, | |||
| 0, 0, 0, 0, 0, | 0, 0, 0, 0, 0, | |||
| hashes[hashno].tests[testno].resultarray, | hashes[hashno].tests[testno].resultarray, | |||
| hashes[hashno].hashsize, | hashes[hashno].hashsize, | |||
| skipping to change at page 121, line 18 ¶ | skipping to change at page 120, line 18 ¶ | |||
| RFC Editor Note: All occurances of "RFC NNNN" should be edited to | RFC Editor Note: All occurances of "RFC NNNN" should be edited to | |||
| replace "NNNN" with this documents RFC number and this note should be | replace "NNNN" with this documents RFC number and this note should be | |||
| deleted. | deleted. | |||
| 12.1 Normative References | 12.1 Normative References | |||
| [RFC2104] - Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | [RFC2104] - Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed- | |||
| Hashing for Message Authentication", RFC 2104, February 1997. | Hashing for Message Authentication", RFC 2104, February 1997. | |||
| [RFC2119] - Bradner, S., "Key words for use in RFCs to Indicate | ||||
| Requirement Levels", BCP 14, RFC 2119, March 1997. | ||||
| [RFC5869] - Krawczyk, H. and P. Eronen, "HMAC-based Extract-and- | [RFC5869] - Krawczyk, H. and P. Eronen, "HMAC-based Extract-and- | |||
| Expand Key Derivation Function (HKDF)", RFC 5869, May 2010. | Expand Key Derivation Function (HKDF)", RFC 5869, May 2010. | |||
| [SHS] - "Secure Hash Standard", United States of American, National | [SHS] - "Secure Hash Standard", United States of American, National | |||
| Institute of Science and Technology, Federal Information | Institute of Science and Technology, Federal Information | |||
| Processing Standard (FIPS) 180-3, | Processing Standard (FIPS) 180-3, | |||
| http://csrc.nist.gov/publications/fips/fips180- | http://csrc.nist.gov/publications/fips/fips180- | |||
| 3/fips180-3_final.pdf. | 3/fips180-3_final.pdf. | |||
| 12.2 Informative References | 12.2 Informative References | |||
| [RFC2202] - P. Cheng, R. Glenn, "Test Cases for HMAC-MD5 and HMAC- | ||||
| SHA-1", September 1997. | ||||
| [RFC3174] - D. Eastlake 3rd, P. Jones, "US Secure Hash Algorithm 1 | [RFC3174] - D. Eastlake 3rd, P. Jones, "US Secure Hash Algorithm 1 | |||
| (SHA1)", September 2001. | (SHA1)", September 2001. | |||
| [RFC3874] - R. Housley, "A 224-bit One-way Hash Function: SHA-224", | [RFC3874] - R. Housley, "A 224-bit One-way Hash Function: SHA-224", | |||
| September 2004. | September 2004. | |||
| [RFC4055] - Schaad, J., Kaliski, B., and R. Housley, "Additional | [RFC4055] - Schaad, J., Kaliski, B., and R. Housley, "Additional | |||
| Algorithms and Identifiers for RSA Cryptography for use in the | Algorithms and Identifiers for RSA Cryptography for use in the | |||
| Internet X.509 Public Key Infrastructure Certificate and | Internet X.509 Public Key Infrastructure Certificate and | |||
| Certificate Revocation List (CRL) Profile", RFC 4055, June 2005 | Certificate Revocation List (CRL) Profile", RFC 4055, June | |||
| 2005. | ||||
| [RFC4086] - D. Eastlake, S. Crocker, J. Schiller, "Randomness | [RFC4086] - D. Eastlake, S. Crocker, J. Schiller, "Randomness | |||
| Requirements for Security", May 2005. | Requirements for Security", May 2005. | |||
| [RFC4231] - M. Nystrom, "Identifiers and Test Vectors for HMAC- | ||||
| SHA-224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512", | ||||
| December 2005. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| [RFC4634] - Eastlake 3rd, D. and T. Hansen, "US Secure Hash | [RFC4634] - Eastlake 3rd, D. and T. Hansen, "US Secure Hash | |||
| Algorithms (SHA and HMAC-SHA)", RFC 4634, July 2006. | Algorithms (SHA and HMAC-SHA)", RFC 4634, July 2006. | |||
| [SHAVS] - "The Secure Hash Algorithm Validation System (SHAVS)", | [SHAVS] - "The Secure Hash Algorithm Validation System (SHAVS)", | |||
| http://csrc.nist.gov/cryptval/shs/SHAVS.pdf. | http://csrc.nist.gov/cryptval/shs/SHAVS.pdf. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| Appendix: Changes from RFC 4634 | Appendix: Changes from RFC 4634 | |||
| skipping to change at page 123, line 32 ¶ | skipping to change at page 121, line 32 ¶ | |||
| 2.c The previous code for SHA-384 and SHA-512 would stop after | 2.c The previous code for SHA-384 and SHA-512 would stop after | |||
| 2^93 bytes (2^96 bits). The fixed code handles up to 2^125 | 2^93 bytes (2^96 bits). The fixed code handles up to 2^125 | |||
| bytes (2^128 bits). | bytes (2^128 bits). | |||
| 2.d Add additional error checking. | 2.d Add additional error checking. | |||
| 3. Update boilerplate, remove special license in [RFC4634] as new | 3. Update boilerplate, remove special license in [RFC4634] as new | |||
| boilerplate mandates simplified BSD license. | boilerplate mandates simplified BSD license. | |||
| 4. Repalce MIT version of getopt with new code to satisfy IETF | 4. Replace MIT version of getopt with new code to satisfy IETF | |||
| incoming and outgoing license restrictions. | incoming and outgoing license restrictions. | |||
| 5. Other assorted editorial improvements. | 5. Other assorted editorial improvements. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| Appendix Z: Edit History | Appendix Z: Edit History | |||
| RFC Editor, Please delete this Appendix Z on publication. | RFC Editor, Please delete this Appendix Z on publication. | |||
| skipping to change at page 125, line 5 ¶ | skipping to change at page 122, line 30 ¶ | |||
| license. | license. | |||
| Z.3 Changes from -02 to -03 | Z.3 Changes from -02 to -03 | |||
| Problem with MIT getopt is given incompletely in -01 to -02 changes. | Problem with MIT getopt is given incompletely in -01 to -02 changes. | |||
| Actual problem includes conflict with IETF incoming license | Actual problem includes conflict with IETF incoming license | |||
| restriction. Also, add this change to Appendix giving changes from | restriction. Also, add this change to Appendix giving changes from | |||
| RFC 4634. Update to incorporate RFC number for the HKDF RFC. | RFC 4634. Update to incorporate RFC number for the HKDF RFC. | |||
| Numerous editorial changes. | Numerous editorial changes. | |||
| Z.4 Changes from -03 to -04 | ||||
| Fix typos and nits. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| Author's Address | Author's Address | |||
| Donald E. Eastlake, 3rd | Donald E. Eastlake, 3rd | |||
| Stellar Switches | Stellar Switches | |||
| 155 Beaver Street | 155 Beaver Street | |||
| Milford, MA 01757 USA | Milford, MA 01757 USA | |||
| Telephone: +1-508-333-2270 | Telephone: +1-508-333-2270 | |||
| End of changes. 346 change blocks. | ||||
| 875 lines changed or deleted | 809 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||