| < draft-eastlake-sha2b-06.txt | draft-eastlake-sha2b-07.txt > | |||
|---|---|---|---|---|
| Network Working Group Donald Eastlake | Network Working Group Donald Eastlake | |||
| INTERNET-DRAFT Huawei | INTERNET-DRAFT Huawei | |||
| 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: July 15, 2011 January 16, 2011 | Expires: August 14, 2011 February 15, 2011 | |||
| 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-06.txt> | <draft-eastlake-sha2b-07.txt> | |||
| Abstract | Abstract | |||
| 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), namely SHA-224, SHA-256, | |||
| SHA-256, SHA-384, and SHA-512. This document makes open source code | SHA-384, and SHA-512. This document makes open source code | |||
| performing the SHA hash functions conveniently available to the | performing these SHA hash functions conveniently available to the | |||
| Internet community. The sample code supports input strings of | Internet community. The sample code supports input strings of | |||
| arbitrary bit length. Much of the text herein was adapted by the | arbitrary bit length. Much of the text herein was adapted by the | |||
| authors from FIPS 180-2. | authors from FIPS 180-2. | |||
| This document replaces RFC 4634, fixing errata and adding code for an | This document replaces RFC 4634, fixing errata and adding code for an | |||
| HMAC-based extract-and-expand key derivation function, HKDF (RFC | HMAC-based extract-and-expand key derivation function, HKDF (RFC | |||
| 5869). As with RFC 4634, code to perform SHA based HMACs is also | 5869). As with RFC 4634, code to perform SHA based HMACs is also | |||
| included. | included. | |||
| Status of This Memo | Status of This Memo | |||
| skipping to change at page 2, line 38 ¶ | skipping to change at page 2, line 38 ¶ | |||
| 7.1 SHA-Based HMACs.......................................17 | 7.1 SHA-Based HMACs.......................................17 | |||
| 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 stdint-example.h....................................29 | 8.1.2 stdint-example.h....................................29 | |||
| 8.1.3 sha-private.h.......................................29 | 8.1.3 sha-private.h.......................................29 | |||
| 8.2 The SHA Code..........................................30 | 8.2 The SHA Code..........................................30 | |||
| 8.2.1 sha1.c..............................................30 | 8.2.1 sha1.c..............................................30 | |||
| 8.2.2 sha224-256.c........................................39 | 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..............................................71 | |||
| 8.3 The HMAC Code.........................................77 | 8.3 The HMAC Code.........................................77 | |||
| 8.4 The HKDF Code.........................................82 | 8.4 The HKDF Code.........................................82 | |||
| 8.5 The Test Driver.......................................89 | 8.5 The Test Driver.......................................89 | |||
| 9. IANA Considerations...................................120 | 9. IANA Considerations...................................120 | |||
| 10. Security Considerations..............................120 | 10. Security Considerations..............................120 | |||
| 11. Acknowledgements.....................................120 | 11. Acknowledgements.....................................120 | |||
| 12. References...........................................121 | 12. References...........................................121 | |||
| 12.1 Normative References................................121 | 12.1 Normative References................................121 | |||
| 12.2 Informative References..............................121 | 12.2 Informative References..............................121 | |||
| Appendix: Changes from RFC 4634..........................122 | Appendix: Changes from RFC 4634..........................123 | |||
| Appendix Z: RFC Editor Note, Edit History................123 | Appendix Z: RFC Editor Note, Edit History................124 | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| 1. Overview of Contents | 1. Overview of Contents | |||
| 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 | |||
| Hash Algorithms (SHAs), code to implement the SHAs, code to implement | Hash Algorithms (SHAs), code to implement the SHAs, code to implement | |||
| HMACs based on the SHAs, and code to implement HKDF based on HMAC. | HMAC (Hashed Message Authentication Code, [RFC2104]) based on the | |||
| Specifications for HMAC and HKDF are not included as they appear | SHAs, and code to implement HKDF (HMAC-based Key Derivation Function, | |||
| elsewhere in the RFC series [RFC2104] [RFC5869]. | [RFC5869]) based on HMAC. Specifications for HMAC and HKDF are not | |||
| included as they appear elsewhere in the RFC series [RFC2104] | ||||
| [RFC5869]. | ||||
| NOTE: Much of the text below is taken from [SHS] and the assertions | NOTE: Much of the text below is taken from [SHS] and the assertions | |||
| of the security of the hash algorithms described therein are made by | of the security of the hash algorithms described therein are made by | |||
| the US Government, the author of [SHS], not by the authors of this | the US Government, the author of [SHS], not by the listed authors of | |||
| document. | this document. See also [SHA1seccon] concerning the security of | |||
| SHA-1. | ||||
| The text below specifies Secure Hash Algorithms, SHA-224 [RFC3874], | The text below specifies Secure Hash Algorithms, SHA-224 [RFC3874], | |||
| SHA-256, SHA-384, and SHA-512, for computing a condensed | SHA-256, SHA-384, and SHA-512, for computing a condensed | |||
| representation of a message or a data file. (SHA-1 is specified in | representation of a message or a data file. (SHA-1 is specified in | |||
| [RFC3174].) When a message of any length < 2^64 bits (for SHA-224 and | [RFC3174].) When a message of any length < 2^64 bits (for SHA-224 and | |||
| SHA-256) or < 2^128 bits (for SHA-384 and SHA-512) is input to one of | SHA-256) or < 2^128 bits (for SHA-384 and SHA-512) is input to one of | |||
| these algorithms, the result is an output called a message digest. | these algorithms, the result is an output called a message digest. | |||
| The message digests range in length from 224 to 512 bits, depending | The message digests range in length from 224 to 512 bits, depending | |||
| on the algorithm. Secure hash algorithms are typically used with | on the algorithm. Secure hash algorithms are typically used with | |||
| other cryptographic algorithms, such as digital signature algorithms | other cryptographic algorithms, such as digital signature algorithms | |||
| and keyed hash authentication codes, the generation of random numbers | and keyed hash authentication codes, the generation of random numbers | |||
| [RFC4086], or in key derivation functions. | [RFC4086], or in key derivation functions. | |||
| The four algorithms specified in this document are called secure | The algorithms specified in this document are called secure because | |||
| because it is computationally infeasible to (1) find a message which | it is computationally infeasible to (1) find a message which | |||
| corresponds to a given message digest, or (2) to find two different | corresponds to a given message digest, or (2) to find two different | |||
| messages that produce the same message digest. Any change to a | messages that produce the same message digest. Any change to a | |||
| message in transit will, with very high probability, result in a | message in transit will, with very high probability, result in a | |||
| different message digest. This will result in a verification failure | different message digest. This will result in a verification failure | |||
| when the secure hash algorithm is used with a digital signature | when the secure hash algorithm is used with a digital signature | |||
| algorithm or a keyed-hash message authentication algorithm. | algorithm or a keyed-hash message authentication algorithm. | |||
| The code provided herein supports input strings of arbitrary bit | The code provided herein supports input strings of arbitrary bit | |||
| length. SHA-1's sample code from [RFC3174] has also been updated to | length. SHA-1's sample code from [RFC3174] has also been updated to | |||
| handle input strings of arbitrary bit length. Permission is granted | handle input strings of arbitrary bit length. Permission is granted | |||
| for all uses, commercial and non-commercial, of this code. | for all uses, commercial and non-commercial, of this code. | |||
| 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. | |||
| ASN.1 OIDs (Object Identifiers) for the SHA algorithms, taken from | ASN.1 OIDs (Object Identifiers) for the SHA algorithms, taken from | |||
| [RFC4055], are as follows: | [RFC4055], are as follows: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| id-sha1 OBJECT IDENTIFIER ::= { iso(1) | id-sha1 OBJECT IDENTIFIER ::= { iso(1) | |||
| identified-organization(3) oiw(14) | identified-organization(3) oiw(14) | |||
| secsig(3) algorithms(2) 26 } | secsig(3) algorithms(2) 26 } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| id-sha224 OBJECT IDENTIFIER ::= {{ joint-iso-itu-t(2) | id-sha224 OBJECT IDENTIFIER ::= {{ joint-iso-itu-t(2) | |||
| country(16) us(840) organization(1) gov(101) | country(16) us(840) organization(1) gov(101) | |||
| csor(3) nistalgorithm(4) hashalgs(2) 4 } | csor(3) nistalgorithm(4) hashalgs(2) 4 } | |||
| id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | id-sha256 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | |||
| country(16) us(840) organization(1) gov(101) | country(16) us(840) organization(1) gov(101) | |||
| csor(3) nistalgorithm(4) hashalgs(2) 1 } | csor(3) nistalgorithm(4) hashalgs(2) 1 } | |||
| id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | id-sha384 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | |||
| country(16) us(840) organization(1) gov(101) | country(16) us(840) organization(1) gov(101) | |||
| csor(3) nistalgorithm(4) hashalgs(2) 2 } | csor(3) nistalgorithm(4) hashalgs(2) 2 } | |||
| id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | id-sha512 OBJECT IDENTIFIER ::= { joint-iso-itu-t(2) | |||
| skipping to change at page 4, line 52 ¶ | skipping to change at page 5, line 4 ¶ | |||
| 7 = 0111, A = 1010. | 7 = 0111, A = 1010. | |||
| b. A word equals a 32-bit or 64-bit string that may be represented | b. A word equals a 32-bit or 64-bit string that may be represented | |||
| as a sequence of 8 or 16 hex digits, respectively. To convert a | as a sequence of 8 or 16 hex digits, respectively. To convert a | |||
| word to hex digits, each 4-bit string is converted to its hex | word to hex digits, each 4-bit string is converted to its hex | |||
| equivalent as described in (a) above. Example: | equivalent as described in (a) above. Example: | |||
| 1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23. | 1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23. | |||
| Throughout this document, the "big-endian" convention is used | Throughout this document, the "big-endian" convention is used | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| when expressing both 32-bit and 64-bit words, so that within | when expressing both 32-bit and 64-bit words, so that within | |||
| each word the most significant bit is shown in the leftmost bit | each word the most significant bit is shown in the leftmost bit | |||
| position. | position. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| c. An integer may be represented as a word or pair of words. | c. An integer may be represented as a word or pair of words. | |||
| An integer between 0 and 2^32 - 1 inclusive may be represented | An integer between 0 and 2^32 - 1 inclusive may be represented | |||
| as a 32-bit word. The least significant four bits of the | as a 32-bit word. The least significant four bits of the | |||
| integer are represented by the rightmost hex digit of the word | integer are represented by the rightmost hex digit of the word | |||
| representation. Example: the integer 291 = 2^8+2^5+2^1+2^0 = | representation. Example: the integer 291 = 2^8+2^5+2^1+2^0 = | |||
| 256+32+2+1 is represented by the hex word, 00000123. | 256+32+2+1 is represented by the hex word, 00000123. | |||
| The same holds true for an integer between 0 and 2^64-1 | The same holds true for an integer between 0 and 2^64-1 | |||
| inclusive, which may be represented as a 64-bit word. | inclusive, which may be represented as a 64-bit word. | |||
| skipping to change at page 5, line 51 ¶ | skipping to change at page 6, line 5 ¶ | |||
| result will still be the same number of bits). | result will still be the same number of bits). | |||
| a. Bitwise logical word operations | a. Bitwise logical word operations | |||
| X AND Y = bitwise logical "and" of X and Y. | X AND Y = bitwise logical "and" of X and Y. | |||
| X OR Y = bitwise logical "inclusive-or" of X and Y. | X OR Y = bitwise logical "inclusive-or" of X and Y. | |||
| X XOR Y = bitwise logical "exclusive-or" of X and Y. | X XOR Y = bitwise logical "exclusive-or" of X and Y. | |||
| NOT X = bitwise logical "complement" of X. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| NOT X = bitwise logical "complement" of X. | ||||
| Example: | Example: | |||
| 01101100101110011101001001111011 | 01101100101110011101001001111011 | |||
| XOR 01100101110000010110100110110111 | XOR 01100101110000010110100110110111 | |||
| -------------------------------- | -------------------------------- | |||
| = 00001001011110001011101111001100 | = 00001001011110001011101111001100 | |||
| b. The operation X + Y is defined as follows: words X and Y | b. The operation X + Y is defined as follows: words X and Y | |||
| represent w-bit integers x and y, where 0 <= x < 2^w and 0 <= y | represent w-bit integers x and y, where 0 <= x < 2^w and 0 <= y | |||
| < 2^w. For positive integers n and m, let | < 2^w. For positive integers n and m, let | |||
| skipping to change at page 6, line 41 ¶ | skipping to change at page 6, line 43 ¶ | |||
| d. The rotate right (circular right shift) operation ROTR^n(x), where | d. The rotate right (circular right shift) operation ROTR^n(x), where | |||
| x is a w-bit word and n is an integer with 0 <= n < w, is | x is a w-bit word and n is an integer with 0 <= n < w, is | |||
| defined by | defined by | |||
| ROTR^n(x) = (x>>n) OR (x<<(w-n)) | ROTR^n(x) = (x>>n) OR (x<<(w-n)) | |||
| e. The rotate left (circular left shift) operation ROTL^n(x), where x | e. The rotate left (circular left shift) operation ROTL^n(x), where x | |||
| is a w-bit word and n is an integer with 0 <= n < w, is defined | is a w-bit word and n is an integer with 0 <= n < w, is defined | |||
| by | by | |||
| ROTL^n(X) = (x<<n) OR (x>>w-n) | ROTL^n(X) = (x<<n) OR (x>>(w-n)) | |||
| Note the following equivalence relationships, where w is fixed | Note the following equivalence relationships, where w is fixed | |||
| in each relationship: | in each relationship: | |||
| ROTL^n(x) = ROTR^(w-n)(x) | ROTL^n(x) = ROTR^(w-n)(x) | |||
| ROTR^n(x) = ROTL^(w-n)(x) | ROTR^n(x) = ROTL^(w-n)(x) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| skipping to change at page 7, line 37 ¶ | skipping to change at page 7, line 37 ¶ | |||
| Suppose a message has length L < 2^64. Before it is input to the | Suppose a message has length L < 2^64. Before it is input to the | |||
| hash function, the message is padded on the right as follows: | hash function, the message is padded on the right as follows: | |||
| a. "1" is appended. Example: if the original message is "01010000", | a. "1" is appended. Example: if the original message is "01010000", | |||
| this is padded to "010100001". | this is padded to "010100001". | |||
| b. K "0"s are appended where K is the smallest, non-negative | b. K "0"s are appended where K is the smallest, non-negative | |||
| solution to the equation | solution to the equation | |||
| L + 1 + K = 448 (mod 512) | ( L + 1 + K ) mod 512 = 448 | |||
| c. Then append the 64-bit block that is L in binary representation. | c. Then append the 64-bit block that is L in binary representation. | |||
| After appending this block, the length of the message will be a | After appending this block, the length of the message will be a | |||
| multiple of 512 bits. | multiple of 512 bits. | |||
| Example: Suppose the original message is the bit string | Example: Suppose the original message is the bit string | |||
| 01100001 01100010 01100011 01100100 01100101 | 01100001 01100010 01100011 01100100 01100101 | |||
| After step (a) this gives | After step (a) this gives | |||
| skipping to change at page 8, line 31 ¶ | skipping to change at page 8, line 31 ¶ | |||
| Suppose a message has length L < 2^128. Before it is input to the | Suppose a message has length L < 2^128. Before it is input to the | |||
| hash function, the message is padded on the right as follows: | hash function, the message is padded on the right as follows: | |||
| a. "1" is appended. Example: if the original message is "01010000", | a. "1" is appended. Example: if the original message is "01010000", | |||
| this is padded to "010100001". | this is padded to "010100001". | |||
| b. K "0"s are appended where K is the smallest, non-negative | b. K "0"s are appended where K is the smallest, non-negative | |||
| solution to the equation | solution to the equation | |||
| L + 1 + K = 896 (mod 1024) | ( L + 1 + K ) mod 1024 = 896 | |||
| c. Then append the 128-bit block that is L in binary representation. | c. Then append the 128-bit block that is L in binary representation. | |||
| After appending this block, the length of the message will be a | After appending this block, the length of the message will be a | |||
| multiple of 1024 bits. | multiple of 1024 bits. | |||
| Example: Suppose the original message is the bit string | Example: Suppose the original message is the bit string | |||
| 01100001 01100010 01100011 01100100 01100101 | 01100001 01100010 01100011 01100100 01100101 | |||
| After step (a) this gives | After step (a) this gives | |||
| skipping to change at page 29, line 11 ¶ | skipping to change at page 29, line 11 ¶ | |||
| uint8_t prk[USHAMaxHashSize], | uint8_t prk[USHAMaxHashSize], | |||
| const unsigned char *info, int info_len, | const unsigned char *info, int info_len, | |||
| uint8_t okm[USHAMaxHashSize], int okm_len); | uint8_t okm[USHAMaxHashSize], int okm_len); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| #endif /* _SHA_H_ */ | #endif /* _SHA_H_ */ | |||
| 8.1.2 stdint-example.h | 8.1.2 stdint-example.h | |||
| If you system does not have <stdint.h>, the following should be | If your system does not have <stdint.h>, the following should be | |||
| adequate as a substitute for compiling the other code in this | adequate as a substitute for compiling the other code in this | |||
| document. | document. | |||
| /*********************** stdint-example.h **********************/ | /*********************** stdint-example.h **********************/ | |||
| /**** Use this file if your system does not have a stdint.h. ***/ | /**** Use this file if your system does not have a stdint.h. ***/ | |||
| /***************** See RFC NNNN for details. *******************/ | /***************** See RFC NNNN for details. *******************/ | |||
| #ifndef STDINT_H | #ifndef STDINT_H | |||
| #define STDINT_H | #define STDINT_H | |||
| typedef unsigned long long uint64_t; /* unsigned 64 bit integer */ | typedef unsigned long long uint64_t; /* unsigned 64 bit integer */ | |||
| skipping to change at page 31, line 7 ¶ | skipping to change at page 31, line 7 ¶ | |||
| * and FIP PUB 180-2. | * 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 | * 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 | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| * given data stream. It should take about 2**n steps to find a | * given data stream that can serve as a means of providing a | |||
| * message with the same digest as a given message and | ||||
| * 2**(n/2) to find any two messages with the same digest, | ||||
| * when n is the digest size in bits. Therefore, this | ||||
| * algorithm can serve as a means of providing a | ||||
| * "fingerprint" for a message. | * "fingerprint" for a message. | |||
| * | * | |||
| * Portability Issues: | * Portability Issues: | |||
| * SHA-1 is defined in terms of 32-bit "words". This code | * SHA-1 is defined in terms of 32-bit "words". This code | |||
| * uses <stdint.h> (included via "sha.h") to define 32 and 8 | * uses <stdint.h> (included via "sha.h") to define 32 and 8 | |||
| * bit unsigned integer types. If your C compiler does not | * 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 | |||
| * appropriate. | * appropriate. | |||
| * | * | |||
| * Caveats: | * Caveats: | |||
| skipping to change at page 32, line 4 ¶ | skipping to change at page 31, line 53 ¶ | |||
| (++(context)->Length_High == 0) ? shaInputTooLong \ | (++(context)->Length_High == 0) ? shaInputTooLong \ | |||
| : (context)->Corrupted ) | : (context)->Corrupted ) | |||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static void SHA1ProcessMessageBlock(SHA1Context *context); | 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); | |||
| /* | /* | |||
| * SHA1Reset | * SHA1Reset | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * 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) | |||
| skipping to change at page 33, line 4 ¶ | skipping to change at page 32, line 53 ¶ | |||
| * 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: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| int SHA1Input(SHA1Context *context, | int SHA1Input(SHA1Context *context, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| const uint8_t *message_array, unsigned length) | const uint8_t *message_array, unsigned length) | |||
| { | { | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| if (!length) return shaSuccess; | if (!length) return shaSuccess; | |||
| if (!message_array) return shaNull; | if (!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--) { | while (length--) { | |||
| context->Message_Block[context->Message_Block_Index++] = | context->Message_Block[context->Message_Block_Index++] = | |||
| skipping to change at page 34, line 4 ¶ | skipping to change at page 33, line 52 ¶ | |||
| * 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) | |||
| { | { | |||
| static uint8_t masks[8] = { | static uint8_t masks[8] = { | |||
| /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* 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 | |||
| }; | }; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| static 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 (!context) return shaNull; | if (!context) return shaNull; | |||
| if (!length) return shaSuccess; | if (!length) return shaSuccess; | |||
| if (context->Corrupted) return context->Corrupted; | if (context->Corrupted) return context->Corrupted; | |||
| skipping to change at page 35, line 4 ¶ | skipping to change at page 34, line 53 ¶ | |||
| * 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) return shaNull; | if (!context) return shaNull; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| if (!Message_Digest) 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) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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; | |||
| } | } | |||
| /* | /* | |||
| skipping to change at page 36, line 4 ¶ | skipping to change at page 35, line 53 ¶ | |||
| 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 | |||
| */ | */ | |||
| for (t = 0; t < 16; t++) { | for (t = 0; t < 16; t++) { | |||
| W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24; | W[t] = ((uint32_t)context->Message_Block[t * 4]) << 24; | |||
| W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16; | W[t] |= ((uint32_t)context->Message_Block[t * 4 + 1]) << 16; | |||
| W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8; | W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]); | W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]); | |||
| } | } | |||
| for (t = 16; t < 80; t++) | for (t = 16; t < 80; t++) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); | W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]); | |||
| 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]; | |||
| for (t = 0; t < 20; t++) { | for (t = 0; t < 20; t++) { | |||
| temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0]; | temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0]; | |||
| skipping to change at page 37, line 4 ¶ | skipping to change at page 36, line 53 ¶ | |||
| 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; | |||
| C = SHA1_ROTL(30,B); | C = SHA1_ROTL(30,B); | |||
| B = A; | B = A; | |||
| A = temp; | A = temp; | |||
| } | } | |||
| context->Intermediate_Hash[0] += A; | context->Intermediate_Hash[0] += A; | |||
| context->Intermediate_Hash[1] += B; | context->Intermediate_Hash[1] += B; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| } | } | |||
| /* | /* | |||
| * SHA1Finalize | * SHA1Finalize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function finishes off the digest calculations. | * This helper function finishes off the digest calculations. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| skipping to change at page 38, line 4 ¶ | skipping to change at page 37, line 53 ¶ | |||
| * | * | |||
| * Description: | * Description: | |||
| * According to the standard, the message must be padded to the next | * 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'. | * even multiple of 512 bits. The first padding bit must be a '1'. | |||
| * The last 64 bits represent the length of the original message. | * The last 64 bits represent the length of the original message. | |||
| * All bits in between should be 0. This helper function will pad | * All bits in between should be 0. This helper function will pad | |||
| * the message according to those rules by filling the Message_Block | * the message according to those rules by filling the Message_Block | |||
| * array accordingly. When it returns, it can be assumed that the | * array accordingly. When it returns, it can be assumed that the | |||
| * message digest has been computed. | * message digest has been computed. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to pad | * The context to pad | |||
| * Pad_Byte: [in] | * Pad_Byte: [in] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * The last byte to add to the message block before the 0-padding | * The last byte to add to the message block before the 0-padding | |||
| * and length. This will contain the last bits of the message | * and length. This will contain the last bits of the message | |||
| * followed by another single bit. If the message was an | * followed by another single bit. If the message was an | |||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | * exact multiple of 8-bits long, Pad_Byte will be 0x80. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| */ | */ | |||
| static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) | static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte) | |||
| { | { | |||
| skipping to change at page 39, line 4 ¶ | skipping to change at page 38, line 49 ¶ | |||
| context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); | context->Message_Block[57] = (uint8_t) (context->Length_High >> 16); | |||
| context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); | context->Message_Block[58] = (uint8_t) (context->Length_High >> 8); | |||
| context->Message_Block[59] = (uint8_t) (context->Length_High); | context->Message_Block[59] = (uint8_t) (context->Length_High); | |||
| context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); | context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24); | |||
| context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); | context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16); | |||
| context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); | context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8); | |||
| context->Message_Block[63] = (uint8_t) (context->Length_Low); | context->Message_Block[63] = (uint8_t) (context->Length_Low); | |||
| SHA1ProcessMessageBlock(context); | SHA1ProcessMessageBlock(context); | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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 */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* 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 U.S. 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-3 published in October 2008 | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * and formerly defined in its predecessors, FIPS PUB 180-1 | * and formerly defined in its predecessors, FIPS PUB 180-1 | |||
| skipping to change at page 40, line 4 ¶ | skipping to change at page 39, line 51 ¶ | |||
| * 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. | |||
| */ | */ | |||
| #include "sha.h" | #include "sha.h" | |||
| #include "sha-private.h" | #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 SHA256_SHR(bits,word) ((word) >> (bits)) | #define SHA256_SHR(bits,word) ((word) >> (bits)) | |||
| #define SHA256_ROTL(bits,word) \ | #define SHA256_ROTL(bits,word) \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| (((word) << (bits)) | ((word) >> (32-(bits)))) | (((word) << (bits)) | ((word) >> (32-(bits)))) | |||
| #define SHA256_ROTR(bits,word) \ | #define SHA256_ROTR(bits,word) \ | |||
| (((word) >> (bits)) | ((word) << (32-(bits)))) | (((word) >> (bits)) | ((word) << (32-(bits)))) | |||
| /* Define the SHA SIGMA and sigma macros */ | /* Define the SHA SIGMA and sigma macros */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #define SHA256_SIGMA0(word) \ | #define SHA256_SIGMA0(word) \ | |||
| (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word)) | (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word)) | |||
| #define SHA256_SIGMA1(word) \ | #define SHA256_SIGMA1(word) \ | |||
| (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word)) | (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word)) | |||
| #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)) | |||
| /* | /* | |||
| skipping to change at page 41, line 4 ¶ | skipping to change at page 40, line 51 ¶ | |||
| /* Initial Hash Values: FIPS 180-3 section 5.3.3 */ | /* 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 | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Description: | * Description: | |||
| * This function will initialize the SHA224Context in preparation | * This function will initialize the SHA224Context in preparation | |||
| * for computing a new SHA224 message digest. | * for computing a new SHA224 message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * context: [in/out] | * context: [in/out] | |||
| * The context to reset. | * The context to reset. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * 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); | |||
| } | } | |||
| skipping to change at page 42, line 4 ¶ | skipping to change at page 41, line 52 ¶ | |||
| } | } | |||
| /* | /* | |||
| * SHA224FinalBits | * SHA224FinalBits | |||
| * | * | |||
| * 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] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 ###.) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 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); | |||
| skipping to change at page 43, line 4 ¶ | skipping to change at page 42, line 52 ¶ | |||
| } | } | |||
| /* | /* | |||
| * SHA256Reset | * SHA256Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the SHA256Context in preparation | * This function will initialize the SHA256Context in preparation | |||
| * for computing a new SHA256 message digest. | * for computing a new SHA256 message digest. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 SHA256Reset(SHA256Context *context) | int SHA256Reset(SHA256Context *context) | |||
| { | { | |||
| return SHA224_256Reset(context, SHA256_H0); | return SHA224_256Reset(context, SHA256_H0); | |||
| } | } | |||
| /* | /* | |||
| * SHA256Input | * SHA256Input | |||
| * | * | |||
| * Description: | * Description: | |||
| skipping to change at page 44, line 5 ¶ | skipping to change at page 43, line 52 ¶ | |||
| context->Message_Block[context->Message_Block_Index++] = | context->Message_Block[context->Message_Block_Index++] = | |||
| *message_array; | *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++; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return context->Corrupted; | return context->Corrupted; | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 | |||
| * 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 | |||
| skipping to change at page 45, line 4 ¶ | skipping to change at page 44, line 51 ¶ | |||
| if (!length) return shaSuccess; | if (!length) return shaSuccess; | |||
| 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 (length >= 8) return context->Corrupted = shaBadParam; | if (length >= 8) return context->Corrupted = shaBadParam; | |||
| 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; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| /* | /* | |||
| * 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. | |||
| skipping to change at page 46, line 5 ¶ | skipping to change at page 45, line 52 ¶ | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| */ | */ | |||
| static int SHA224_256Reset(SHA256Context *context, uint32_t *H0) | static int SHA224_256Reset(SHA256Context *context, uint32_t *H0) | |||
| { | { | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| context->Length_High = context->Length_Low = 0; | context->Length_High = context->Length_Low = 0; | |||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Intermediate_Hash[0] = H0[0]; | context->Intermediate_Hash[0] = H0[0]; | |||
| context->Intermediate_Hash[1] = H0[1]; | context->Intermediate_Hash[1] = H0[1]; | |||
| context->Intermediate_Hash[2] = H0[2]; | context->Intermediate_Hash[2] = H0[2]; | |||
| context->Intermediate_Hash[3] = H0[3]; | context->Intermediate_Hash[3] = H0[3]; | |||
| context->Intermediate_Hash[4] = H0[4]; | context->Intermediate_Hash[4] = H0[4]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Intermediate_Hash[5] = H0[5]; | context->Intermediate_Hash[5] = H0[5]; | |||
| context->Intermediate_Hash[6] = H0[6]; | context->Intermediate_Hash[6] = H0[6]; | |||
| context->Intermediate_Hash[7] = H0[7]; | context->Intermediate_Hash[7] = H0[7]; | |||
| context->Computed = 0; | context->Computed = 0; | |||
| context->Corrupted = shaSuccess; | context->Corrupted = shaSuccess; | |||
| return shaSuccess; | return shaSuccess; | |||
| } | } | |||
| skipping to change at page 47, line 4 ¶ | skipping to change at page 46, line 52 ¶ | |||
| 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, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 | |||
| }; | }; | |||
| 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 */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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) | | |||
| (((uint32_t)context->Message_Block[t4 + 1]) << 16) | | (((uint32_t)context->Message_Block[t4 + 1]) << 16) | | |||
| (((uint32_t)context->Message_Block[t4 + 2]) << 8) | | (((uint32_t)context->Message_Block[t4 + 2]) << 8) | | |||
| (((uint32_t)context->Message_Block[t4 + 3])); | (((uint32_t)context->Message_Block[t4 + 3])); | |||
| skipping to change at page 48, line 5 ¶ | skipping to change at page 47, line 53 ¶ | |||
| 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; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Message_Block_Index = 0; | context->Message_Block_Index = 0; | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * SHA224_256Finalize | * SHA224_256Finalize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function finishes off the digest calculations. | * This helper function finishes off the digest calculations. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * Pad_Byte: [in] | * Pad_Byte: [in] | |||
| * The last byte to add to the message block before the 0-padding | * The last byte to add to the message block before the 0-padding | |||
| skipping to change at page 49, line 4 ¶ | skipping to change at page 48, line 52 ¶ | |||
| * The last 64 bits represent the length of the original message. | * The last 64 bits represent the length of the original message. | |||
| * All bits in between should be 0. This helper function will pad | * All bits in between should be 0. This helper function will pad | |||
| * the message according to those rules by filling the | * the message according to those rules by filling the | |||
| * Message_Block array accordingly. When it returns, it can be | * Message_Block array accordingly. When it returns, it can be | |||
| * assumed that the message digest has been computed. | * assumed that the message digest has been computed. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The context to pad | * The context to pad | |||
| * Pad_Byte: [in] | * Pad_Byte: [in] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * The last byte to add to the message block before the 0-padding | * The last byte to add to the message block before the 0-padding | |||
| * and length. This will contain the last bits of the message | * and length. This will contain the last bits of the message | |||
| * followed by another single bit. If the message was an | * followed by another single bit. If the message was an | |||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | * exact multiple of 8-bits long, Pad_Byte will be 0x80. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| */ | */ | |||
| static void SHA224_256PadMessage(SHA256Context *context, | static void SHA224_256PadMessage(SHA256Context *context, | |||
| uint8_t Pad_Byte) | uint8_t Pad_Byte) | |||
| { | { | |||
| /* | /* | |||
| * Check to see if the current message block is too small to hold | * 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 | * the initial padding bits and length. If so, we will pad the | |||
| skipping to change at page 50, line 4 ¶ | skipping to change at page 49, line 53 ¶ | |||
| SHA224_256ProcessMessageBlock(context); | 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: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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/31. | * the last octet of hash in the element with index 27/31. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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. | |||
| */ | */ | |||
| skipping to change at page 51, line 4 ¶ | skipping to change at page 50, line 51 ¶ | |||
| /* 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 U.S. 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-3 published in October 2008 | * Publication (FIPS PUB) 180-3 published in October 2008 | |||
| * and formerly defined in its predecessors, FIPS PUB 180-1 | * and formerly defined in its predecessors, FIPS PUB 180-1 | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * and FIP PUB 180-2. | * 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/ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * fips180-3/fips180-3_final.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. | |||
| * | * | |||
| skipping to change at page 52, line 4 ¶ | skipping to change at page 51, line 53 ¶ | |||
| /* | /* | |||
| * 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)) : \ | |||
| ((bits) == 32) ? (word)[0] : \ | ((bits) == 32) ? (word)[0] : \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| ((bits) >= 0) ? \ | ((bits) >= 0) ? \ | |||
| (((word)[0] << (32 - (bits))) | \ | (((word)[0] << (32 - (bits))) | \ | |||
| ((word)[1] >> (bits))) : 0 ) | ((word)[1] >> (bits))) : 0 ) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #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) ? \ | |||
| (((word)[0] << (bits)) | \ | (((word)[0] << (bits)) | \ | |||
| ((word)[1] >> (32 - (bits)))) : \ | ((word)[1] >> (32 - (bits)))) : \ | |||
| 0, \ | 0, \ | |||
| (ret)[1] = (((bits) < 32) && ((bits) >= 0)) ? \ | (ret)[1] = (((bits) < 32) && ((bits) >= 0)) ? \ | |||
| ((word)[1] << (bits)) : 0 ) | ((word)[1] << (bits)) : 0 ) | |||
| skipping to change at page 53, line 4 ¶ | skipping to change at page 52, line 53 ¶ | |||
| ( (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) ( \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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], \ | |||
| (word1)[1] += (word2)[1] + ((word1)[2] < ADDTO4_temp2), \ | (word1)[1] += (word2)[1] + ((word1)[2] < ADDTO4_temp2), \ | |||
| (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO4_temp) ) | (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO4_temp) ) | |||
| /* | /* | |||
| * Add the 2word value in word2 to word1. | * Add the 2word value in word2 to word1. | |||
| skipping to change at page 54, line 4 ¶ | skipping to change at page 53, line 52 ¶ | |||
| 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), \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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], | |||
| sigma0_temp3[2], sigma0_temp4[2]; | sigma0_temp3[2], sigma0_temp4[2]; | |||
| #define SHA512_sigma0(word, ret) ( \ | #define SHA512_sigma0(word, ret) ( \ | |||
| SHA512_ROTR( 1, (word), sigma0_temp1), \ | SHA512_ROTR( 1, (word), sigma0_temp1), \ | |||
| SHA512_ROTR( 8, (word), sigma0_temp2), \ | SHA512_ROTR( 8, (word), sigma0_temp2), \ | |||
| skipping to change at page 55, line 4 ¶ | skipping to change at page 54, line 53 ¶ | |||
| 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]; | |||
| #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), \ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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)) ) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #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-3, 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]) ) | |||
| skipping to change at page 56, line 4 ¶ | skipping to change at page 55, line 53 ¶ | |||
| 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 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-3 sections 5.3.4 and 5.3.5 */ | /* Initial Hash Values: FIPS 180-3 sections 5.3.4 and 5.3.5 */ | |||
| static uint32_t SHA384_H0[SHA512HashSize/4] = { | static uint32_t SHA384_H0[SHA512HashSize/4] = { | |||
| 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A, | 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31, | 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31, | |||
| 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, | 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D, | |||
| 0xBEFA4FA4 | 0xBEFA4FA4 | |||
| }; | }; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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 */ | |||
| skipping to change at page 57, line 4 ¶ | skipping to change at page 56, line 51 ¶ | |||
| #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) ? shaInputTooLong : \ | (++context->Length_High == 0) ? shaInputTooLong : \ | |||
| (context)->Corrupted) | (context)->Corrupted) | |||
| /* Local Function Prototypes */ | /* Local Function Prototypes */ | |||
| static int SHA384_512Reset(SHA512Context *context, | static int SHA384_512Reset(SHA512Context *context, | |||
| uint64_t H0[SHA512HashSize/8]); | uint64_t H0[SHA512HashSize/8]); | |||
| static void SHA384_512ProcessMessageBlock(SHA512Context *context); | static void SHA384_512ProcessMessageBlock(SHA512Context *context); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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 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-3 sections 5.3.4 and 5.3.5 */ | /* 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, | |||
| skipping to change at page 58, line 4 ¶ | skipping to change at page 57, line 51 ¶ | |||
| /* | /* | |||
| * 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] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 59, line 4 ¶ | skipping to change at page 58, line 52 ¶ | |||
| 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: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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]) | |||
| skipping to change at page 60, line 4 ¶ | skipping to change at page 59, line 52 ¶ | |||
| * 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] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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 (!context) return shaNull; | if (!context) return shaNull; | |||
| if (!length) return shaSuccess; | if (!length) return shaSuccess; | |||
| skipping to change at page 61, line 4 ¶ | skipping to change at page 60, line 52 ¶ | |||
| * 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 SHA512FinalBits(SHA512Context *context, | int SHA512FinalBits(SHA512Context *context, | |||
| uint8_t message_bits, unsigned int length) | uint8_t message_bits, unsigned int length) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| { | { | |||
| static 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 | |||
| }; | }; | |||
| static 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, | |||
| skipping to change at page 62, line 4 ¶ | skipping to change at page 61, line 52 ¶ | |||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| */ | */ | |||
| int SHA512Result(SHA512Context *context, | int SHA512Result(SHA512Context *context, | |||
| uint8_t Message_Digest[SHA512HashSize]) | uint8_t Message_Digest[SHA512HashSize]) | |||
| { | { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return SHA384_512ResultN(context, Message_Digest, SHA512HashSize); | return SHA384_512ResultN(context, Message_Digest, SHA512HashSize); | |||
| } | } | |||
| /* | /* | |||
| * SHA384_512Reset | * SHA384_512Reset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function will initialize the SHA512Context in | * This helper function will initialize the SHA512Context in | |||
| * preparation for computing a new SHA384 or SHA512 message | * preparation for computing a new SHA384 or SHA512 message | |||
| * digest. | * digest. | |||
| skipping to change at page 63, line 4 ¶ | skipping to change at page 62, line 51 ¶ | |||
| context->Length[0] = context->Length[1] = | context->Length[0] = context->Length[1] = | |||
| context->Length[2] = context->Length[3] = 0; | context->Length[2] = context->Length[3] = 0; | |||
| for (i = 0; i < SHA512HashSize/4; i++) | for (i = 0; i < SHA512HashSize/4; i++) | |||
| context->Intermediate_Hash[i] = H0[i]; | context->Intermediate_Hash[i] = H0[i]; | |||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| context->Length_High = context->Length_Low = 0; | context->Length_High = context->Length_Low = 0; | |||
| for (i = 0; i < SHA512HashSize/8; i++) | for (i = 0; i < SHA512HashSize/8; i++) | |||
| context->Intermediate_Hash[i] = H0[i]; | context->Intermediate_Hash[i] = H0[i]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| context->Computed = 0; | context->Computed = 0; | |||
| context->Corrupted = shaSuccess; | context->Corrupted = shaSuccess; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| return 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. | |||
| * | * | |||
| skipping to change at page 64, line 4 ¶ | skipping to change at page 63, line 52 ¶ | |||
| 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, | |||
| 0x46D22FFC, 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED, | 0x46D22FFC, 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED, | |||
| 0x53380D13, 0x9D95B3DF, 0x650A7354, 0x8BAF63DE, 0x766A0ABB, | 0x53380D13, 0x9D95B3DF, 0x650A7354, 0x8BAF63DE, 0x766A0ABB, | |||
| 0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B, | 0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, 0xC24B8B70, | 0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, 0xC24B8B70, | |||
| 0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218, | 0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218, | |||
| 0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070, | 0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070, | |||
| 0x32BBD1B8, 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53, | 0x32BBD1B8, 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53, | |||
| 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, | 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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, | |||
| 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, | 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C, | |||
| skipping to change at page 65, line 5 ¶ | skipping to change at page 64, line 52 ¶ | |||
| 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); | |||
| SHA512_ADD(temp2, temp3, &W[t2]); | SHA512_ADD(temp2, temp3, &W[t2]); | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| A[0] = context->Intermediate_Hash[0]; | A[0] = context->Intermediate_Hash[0]; | |||
| A[1] = context->Intermediate_Hash[1]; | A[1] = context->Intermediate_Hash[1]; | |||
| B[0] = context->Intermediate_Hash[2]; | B[0] = context->Intermediate_Hash[2]; | |||
| B[1] = context->Intermediate_Hash[3]; | B[1] = context->Intermediate_Hash[3]; | |||
| C[0] = context->Intermediate_Hash[4]; | C[0] = context->Intermediate_Hash[4]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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]; | |||
| H[0] = context->Intermediate_Hash[14]; | H[0] = context->Intermediate_Hash[14]; | |||
| skipping to change at page 66, line 4 ¶ | skipping to change at page 65, line 52 ¶ | |||
| 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); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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 */ | /* Constants defined in FIPS 180-3, section 4.2.3 */ | |||
| static const uint64_t K[80] = { | static const uint64_t K[80] = { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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, | |||
| skipping to change at page 67, line 5 ¶ | skipping to change at page 66, line 53 ¶ | |||
| 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) | | |||
| ((uint64_t)(context->Message_Block[t8 + 6]) << 8) | | ((uint64_t)(context->Message_Block[t8 + 6]) << 8) | | |||
| ((uint64_t)(context->Message_Block[t8 + 7])); | ((uint64_t)(context->Message_Block[t8 + 7])); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| for (t = 16; t < 80; t++) | for (t = 16; t < 80; t++) | |||
| 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]; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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++) { | |||
| skipping to change at page 68, line 4 ¶ | skipping to change at page 67, line 53 ¶ | |||
| * SHA384_512Finalize | * SHA384_512Finalize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This helper function finishes off the digest calculations. | * This helper function finishes off the digest calculations. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * context: [in/out] | * context: [in/out] | |||
| * The SHA context to update | * The SHA context to update | |||
| * Pad_Byte: [in] | * Pad_Byte: [in] | |||
| * The last byte to add to the message block before the 0-padding | * The last byte to add to the message block before the 0-padding | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * and length. This will contain the last bits of the message | * and length. This will contain the last bits of the message | |||
| * followed by another single bit. If the message was an | * followed by another single bit. If the message was an | |||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | * exact multiple of 8-bits long, Pad_Byte will be 0x80. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| static void SHA384_512Finalize(SHA512Context *context, | static void SHA384_512Finalize(SHA512Context *context, | |||
| uint8_t Pad_Byte) | uint8_t Pad_Byte) | |||
| { | { | |||
| int_least16_t i; | int_least16_t i; | |||
| SHA384_512PadMessage(context, Pad_Byte); | SHA384_512PadMessage(context, Pad_Byte); | |||
| /* message may be sensitive, clear it out */ | /* message may be sensitive, clear it out */ | |||
| skipping to change at page 69, line 4 ¶ | skipping to change at page 68, line 53 ¶ | |||
| * Pad_Byte: [in] | * Pad_Byte: [in] | |||
| * The last byte to add to the message block before the 0-padding | * The last byte to add to the message block before the 0-padding | |||
| * and length. This will contain the last bits of the message | * and length. This will contain the last bits of the message | |||
| * followed by another single bit. If the message was an | * followed by another single bit. If the message was an | |||
| * exact multiple of 8-bits long, Pad_Byte will be 0x80. | * exact multiple of 8-bits long, Pad_Byte will be 0x80. | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * Nothing. | * Nothing. | |||
| * | * | |||
| */ | */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| static void SHA384_512PadMessage(SHA512Context *context, | static void SHA384_512PadMessage(SHA512Context *context, | |||
| uint8_t Pad_Byte) | uint8_t Pad_Byte) | |||
| { | { | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Check to see if the current message block is too small to hold | * 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 | * the initial padding bits and length. If so, we will pad the | |||
| * block, process it, and then continue padding into a second | * block, process it, and then continue padding into a second | |||
| * block. | * block. | |||
| */ | */ | |||
| if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) { | if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) { | |||
| context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | context->Message_Block[context->Message_Block_Index++] = Pad_Byte; | |||
| while (context->Message_Block_Index < SHA512_Message_Block_Size) | while (context->Message_Block_Index < SHA512_Message_Block_Size) | |||
| context->Message_Block[context->Message_Block_Index++] = 0; | context->Message_Block[context->Message_Block_Index++] = 0; | |||
| skipping to change at page 70, line 4 ¶ | skipping to change at page 69, line 53 ¶ | |||
| context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8); | context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8); | |||
| context->Message_Block[127] = (uint8_t)(context->Length[3]); | 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->Message_Block[112] = (uint8_t)(context->Length_High >> 56); | |||
| context->Message_Block[113] = (uint8_t)(context->Length_High >> 48); | context->Message_Block[113] = (uint8_t)(context->Length_High >> 48); | |||
| context->Message_Block[114] = (uint8_t)(context->Length_High >> 40); | context->Message_Block[114] = (uint8_t)(context->Length_High >> 40); | |||
| context->Message_Block[115] = (uint8_t)(context->Length_High >> 32); | context->Message_Block[115] = (uint8_t)(context->Length_High >> 32); | |||
| context->Message_Block[116] = (uint8_t)(context->Length_High >> 24); | context->Message_Block[116] = (uint8_t)(context->Length_High >> 24); | |||
| context->Message_Block[117] = (uint8_t)(context->Length_High >> 16); | context->Message_Block[117] = (uint8_t)(context->Length_High >> 16); | |||
| context->Message_Block[118] = (uint8_t)(context->Length_High >> 8); | context->Message_Block[118] = (uint8_t)(context->Length_High >> 8); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Message_Block[119] = (uint8_t)(context->Length_High); | context->Message_Block[119] = (uint8_t)(context->Length_High); | |||
| context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56); | context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56); | |||
| context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48); | context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40); | context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40); | |||
| context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32); | context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32); | |||
| context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24); | context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24); | |||
| context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16); | context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16); | |||
| context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8); | context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8); | |||
| context->Message_Block[127] = (uint8_t)(context->Length_Low); | context->Message_Block[127] = (uint8_t)(context->Length_Low); | |||
| #endif /* USE_32BIT_ONLY */ | #endif /* USE_32BIT_ONLY */ | |||
| SHA384_512ProcessMessageBlock(context); | SHA384_512ProcessMessageBlock(context); | |||
| } | } | |||
| skipping to change at page 71, line 4 ¶ | skipping to change at page 70, line 53 ¶ | |||
| 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) return shaNull; | if (!context) return shaNull; | |||
| if (!Message_Digest) 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) | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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; ) { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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++]); | |||
| 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++]); | |||
| } | } | |||
| #else /* !USE_32BIT_ONLY */ | #else /* !USE_32BIT_ONLY */ | |||
| skipping to change at page 72, line 4 ¶ | skipping to change at page 71, line 51 ¶ | |||
| * USHAReset | * USHAReset | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will initialize the SHA Context in preparation | * This function will initialize the SHA Context in preparation | |||
| * for computing a new SHA message digest. | * for computing a new SHA 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 | ||||
| * Selects which SHA reset to call | * Selects which SHA reset to call | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| */ | */ | |||
| int USHAReset(USHAContext *context, enum SHAversion whichSha) | int USHAReset(USHAContext *context, enum SHAversion whichSha) | |||
| { | { | |||
| if (!context) return shaNull; | 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); | |||
| skipping to change at page 73, line 4 ¶ | skipping to change at page 72, line 53 ¶ | |||
| int USHAInput(USHAContext *context, | int USHAInput(USHAContext *context, | |||
| const uint8_t *bytes, unsigned int bytecount) | const uint8_t *bytes, unsigned int bytecount) | |||
| { | { | |||
| if (!context) return shaNull; | 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, | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| bytecount); | bytecount); | |||
| case SHA256: | case SHA256: | |||
| return SHA256Input((SHA256Context*)&context->ctx, bytes, | return SHA256Input((SHA256Context*)&context->ctx, bytes, | |||
| bytecount); | bytecount); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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; | |||
| } | } | |||
| } | } | |||
| skipping to change at page 74, line 4 ¶ | skipping to change at page 73, line 53 ¶ | |||
| bit_count); | bit_count); | |||
| case SHA224: | case SHA224: | |||
| return SHA224FinalBits((SHA224Context*)&context->ctx, bits, | return SHA224FinalBits((SHA224Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| case SHA256: | case SHA256: | |||
| return SHA256FinalBits((SHA256Context*)&context->ctx, bits, | return SHA256FinalBits((SHA256Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| case SHA384: | case SHA384: | |||
| return SHA384FinalBits((SHA384Context*)&context->ctx, bits, | return SHA384FinalBits((SHA384Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| case SHA512: | case SHA512: | |||
| return SHA512FinalBits((SHA512Context*)&context->ctx, bits, | return SHA512FinalBits((SHA512Context*)&context->ctx, bits, | |||
| bit_count); | bit_count); | |||
| default: return shaBadParam; | default: return shaBadParam; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| } | } | |||
| /* | /* | |||
| * 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 74, line 53 ¶ | |||
| return SHA384Result((SHA384Context*)&context->ctx, | return SHA384Result((SHA384Context*)&context->ctx, | |||
| Message_Digest); | Message_Digest); | |||
| case SHA512: | case SHA512: | |||
| return SHA512Result((SHA512Context*)&context->ctx, | return SHA512Result((SHA512Context*)&context->ctx, | |||
| Message_Digest); | Message_Digest); | |||
| default: return shaBadParam; | default: return shaBadParam; | |||
| } | } | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * USHABlockSize | * USHABlockSize | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the blocksize for the given SHA | * This function will return the blocksize for the given SHA | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * algorithm. | * algorithm. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * whichSha: | * whichSha: | |||
| * which SHA algorithm to query | * which SHA algorithm to query | |||
| * | * | |||
| * Returns: | * Returns: | |||
| * block size | * block size | |||
| * | * | |||
| */ | */ | |||
| skipping to change at page 76, line 4 ¶ | skipping to change at page 75, line 53 ¶ | |||
| */ | */ | |||
| 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; | |||
| case SHA384: return SHA384HashSize; | case SHA384: return SHA384HashSize; | |||
| default: | default: | |||
| case SHA512: return SHA512HashSize; | case SHA512: return SHA512HashSize; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * USHAHashSizeBits | * USHAHashSizeBits | |||
| * | * | |||
| * Description: | * Description: | |||
| * This function will return the hashsize for the given SHA | * This function will return the hashsize for the given SHA | |||
| * algorithm, expressed in bits. | * algorithm, expressed in bits. | |||
| * | * | |||
| * Parameters: | * Parameters: | |||
| * whichSha: | * whichSha: | |||
| * which SHA algorithm to query | * which SHA algorithm to query | |||
| * | * | |||
| skipping to change at page 77, line 4 ¶ | skipping to change at page 76, line 52 ¶ | |||
| * | * | |||
| * 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) | |||
| { | { | |||
| switch (whichSha) { | switch (whichSha) { | |||
| case SHA1: return "SHA1"; | case SHA1: return "SHA1"; | |||
| case SHA224: return "SHA224"; | case SHA224: return "SHA224"; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| case SHA256: return "SHA256"; | case SHA256: return "SHA256"; | |||
| case SHA384: return "SHA384"; | case SHA384: return "SHA384"; | |||
| default: | default: | |||
| case SHA512: return "SHA512"; | case SHA512: return "SHA512"; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| } | } | |||
| } | } | |||
| 8.3 The HMAC Code | 8.3 The HMAC Code | |||
| /**************************** hmac.c ***************************/ | /**************************** hmac.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. */ | |||
| skipping to change at page 78, line 4 ¶ | skipping to change at page 77, line 51 ¶ | |||
| * The length of the message in message_array. | * The length of the message in message_array. | |||
| * 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. | |||
| * digest[ ]: [out] | * digest[ ]: [out] | |||
| * Where the digest is to be returned. | * 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. | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * Returns: | * Returns: | |||
| * sha Error Code. | * sha Error Code. | |||
| * | * | |||
| */ | */ | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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, | |||
| uint8_t digest[USHAMaxHashSize]) | uint8_t digest[USHAMaxHashSize]) | |||
| { | { | |||
| HMACContext context; | HMACContext context; | |||
| return hmacReset(&context, whichSha, key, key_len) || | return hmacReset(&context, whichSha, key, key_len) || | |||
| hmacInput(&context, message_array, length) || | hmacInput(&context, message_array, length) || | |||
| hmacResult(&context, digest); | hmacResult(&context, digest); | |||
| } | } | |||
| skipping to change at page 79, line 5 ¶ | skipping to change at page 78, line 54 ¶ | |||
| /* 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]; | |||
| if (!context) return shaNull; | if (!context) return shaNull; | |||
| context->Computed = 0; | context->Computed = 0; | |||
| context->Corrupted = shaSuccess; | context->Corrupted = shaSuccess; | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| blocksize = context->blockSize = USHABlockSize(whichSha); | blocksize = context->blockSize = USHABlockSize(whichSha); | |||
| hashsize = context->hashSize = USHAHashSize(whichSha); | hashsize = context->hashSize = USHAHashSize(whichSha); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| context->whichSha = whichSha; | context->whichSha = whichSha; | |||
| /* | /* | |||
| * If key is longer than the hash blocksize, | * If key is longer than the hash blocksize, | |||
| * reset it to key = HASH(key). | * reset it to key = HASH(key). | |||
| */ | */ | |||
| if (key_len > blocksize) { | if (key_len > blocksize) { | |||
| USHAContext tcontext; | USHAContext tcontext; | |||
| int err = USHAReset(&tcontext, whichSha) || | int err = USHAReset(&tcontext, whichSha) || | |||
| USHAInput(&tcontext, key, key_len) || | USHAInput(&tcontext, key, key_len) || | |||
| skipping to change at page 80, line 4 ¶ | skipping to change at page 79, line 53 ¶ | |||
| 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 */ | |||
| USHAInput(&context->shaContext, k_ipad, blocksize); | USHAInput(&context->shaContext, k_ipad, blocksize); | |||
| return context->Corrupted = ret; | return context->Corrupted = ret; | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* | /* | |||
| * hmacInput | * hmacInput | |||
| * | * | |||
| 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. 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 | |||
| * text[ ]: [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. | |||
| skipping to change at page 81, line 4 ¶ | skipping to change at page 80, line 54 ¶ | |||
| * 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 hmacFinalBits(HMACContext *context, | int hmacFinalBits(HMACContext *context, | |||
| uint8_t bits, unsigned int bit_count) | uint8_t bits, unsigned int bit_count) | |||
| { | { | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| 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; | |||
| /* then final bits of datagram */ | /* then final bits of datagram */ | |||
| return context->Corrupted = | return context->Corrupted = | |||
| USHAFinalBits(&context->shaContext, bits, bit_count); | USHAFinalBits(&context->shaContext, bits, bit_count); | |||
| } | } | |||
| /* | /* | |||
| * hmacResult | * hmacResult | |||
| skipping to change at page 82, line 5 ¶ | skipping to change at page 81, line 53 ¶ | |||
| 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 */ | |||
| USHAInput(&context->shaContext, context->k_opad, | USHAInput(&context->shaContext, context->k_opad, | |||
| context->blockSize) || | context->blockSize) || | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* then results of 1st hash */ | /* then results of 1st hash */ | |||
| USHAInput(&context->shaContext, digest, context->hashSize) || | USHAInput(&context->shaContext, digest, context->hashSize) || | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| /* finish up 2nd pass */ | /* finish up 2nd pass */ | |||
| USHAResult(&context->shaContext, digest); | USHAResult(&context->shaContext, digest); | |||
| context->Computed = 1; | context->Computed = 1; | |||
| return context->Corrupted = ret; | return context->Corrupted = ret; | |||
| } | } | |||
| 8.4 The HKDF Code | 8.4 The HKDF Code | |||
| /**************************** hkdf.c ***************************/ | /**************************** hkdf.c ***************************/ | |||
| skipping to change at page 83, line 4 ¶ | skipping to change at page 82, line 52 ¶ | |||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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: | |||
| skipping to change at page 84, line 4 ¶ | skipping to change at page 83, line 54 ¶ | |||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * prk[ ]: [out] | * prk[ ]: [out] | |||
| * Array 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); | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * 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 84, line 54 ¶ | |||
| * should at least be equal to USHAHashSize(whichSHA). | * should at least be equal to 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] | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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) | |||
| * | * | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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, | |||
| 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) | |||
| { | { | |||
| int hash_len, N; | int hash_len, N; | |||
| unsigned char T[USHAMaxHashSize]; | unsigned char T[USHAMaxHashSize]; | |||
| skipping to change at page 86, line 4 ¶ | skipping to change at page 85, line 54 ¶ | |||
| 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; | |||
| } | } | |||
| /* | /* | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * hkdfReset | * hkdfReset | |||
| * | * | |||
| * Description: | * Description: | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * This function will initialize the hkdfContext in preparation | * This function will initialize the hkdfContext in preparation | |||
| * for key derivation using the modular HKDF interface 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] | |||
| skipping to change at page 87, line 4 ¶ | skipping to change at page 86, line 54 ¶ | |||
| /* | /* | |||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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, | |||
| int ikm_len) | int ikm_len) | |||
| { | { | |||
| skipping to change at page 88, line 4 ¶ | skipping to change at page 87, line 54 ¶ | |||
| 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); | |||
| } | } | |||
| /* | /* | |||
| * hkdfResult | * hkdfResult | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * | * | |||
| * Description: | * Description: | |||
| * This function will finish the HKDF extraction and perform the | * This function will finish the HKDF extraction and perform the | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| * 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] | |||
| skipping to change at page 115, line 29 ¶ | skipping to change at page 115, line 29 ¶ | |||
| } | } | |||
| /* replace a hex string in place with its value */ | /* replace a hex string in place with its value */ | |||
| int unhexStr(char *hexstr) | int unhexStr(char *hexstr) | |||
| { | { | |||
| char *o = hexstr; | char *o = hexstr; | |||
| int len = 0, nibble1 = 0, nibble2 = 0; | int len = 0, nibble1 = 0, nibble2 = 0; | |||
| if (!hexstr) return 0; | if (!hexstr) return 0; | |||
| for ( ; *hexstr; hexstr++) { | for ( ; *hexstr; hexstr++) { | |||
| if (isalpha((int)(unsigned char)(*hexstr))) { | if (isalpha((int)(unsigned char)(*hexstr))) { | |||
| nibble1 = tolower(*hexstr) - 'a' + 10; | nibble1 = tolower((int)(unsigned char)(*hexstr)) - 'a' + 10; | |||
| } else if (isdigit((int)(unsigned char)(*hexstr))) { | } else if (isdigit((int)(unsigned char)(*hexstr))) { | |||
| nibble1 = *hexstr - '0'; | nibble1 = *hexstr - '0'; | |||
| } else { | } else { | |||
| 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((int)(unsigned char)(*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); | |||
| } | } | |||
| *o++ = (char)((nibble1 << 4) | nibble2); | *o++ = (char)((nibble1 << 4) | nibble2); | |||
| len++; | len++; | |||
| } | } | |||
| return len; | return len; | |||
| } | } | |||
| skipping to change at page 116, line 26 ¶ | skipping to change at page 116, line 26 ¶ | |||
| int hmaclen = 0; | int hmaclen = 0; | |||
| char *info = 0; | char *info = 0; | |||
| int infolen = 0, okmlen = 0; | int infolen = 0, okmlen = 0; | |||
| int randomcount = RANDOMCOUNT; | int randomcount = RANDOMCOUNT; | |||
| const char *hashfilename = 0; | const char *hashfilename = 0; | |||
| const char *hashFilename = 0; | const char *hashFilename = 0; | |||
| int extrabits = 0, numberExtrabits = 0; | int extrabits = 0, numberExtrabits = 0; | |||
| int strIsHex = 0; | int strIsHex = 0; | |||
| if ('A' != 0x41) { | if ('A' != 0x41) { | |||
| fprintf(stderr, "%s: ASCII is required for these tests\n", argv[0]); | fprintf(stderr, "%s: these tests require ASCII\n", argv[0]); | |||
| } | } | |||
| while ((i = getopt(argc, argv, | while ((i = getopt(argc, argv, | |||
| "6b:B:def:F:h:i:Hk:l:L:mpPr:R:s:S:t:wxX")) != -1) | "6b:B:def:F:h:i:Hk:l:L:mpPr:R:s:S:t:wxX")) != -1) | |||
| switch (i) { | switch (i) { | |||
| case 'b': extrabits = strtol(optarg, 0, 0); break; | case 'b': extrabits = strtol(optarg, 0, 0); break; | |||
| case 'B': numberExtrabits = atoi(optarg); break; | case 'B': numberExtrabits = atoi(optarg); break; | |||
| case 'd': runHkdfTests = 1; break; | case 'd': runHkdfTests = 1; break; | |||
| case 'e': checkErrors = 1; break; | case 'e': checkErrors = 1; break; | |||
| case 'f': hashfilename = optarg; break; | case 'f': hashfilename = optarg; break; | |||
| skipping to change at page 119, line 39 ¶ | skipping to change at page 119, line 39 ¶ | |||
| return 0; | return 0; | |||
| } | } | |||
| /* | /* | |||
| * Compare two strings, case independently. | * Compare two strings, case independently. | |||
| * Equivalent to strcasecmp() found on some systems. | * Equivalent to strcasecmp() found on some systems. | |||
| */ | */ | |||
| int scasecmp(const char *s1, const char *s2) | int scasecmp(const char *s1, const char *s2) | |||
| { | { | |||
| for (;;) { | for (;;) { | |||
| char u1 = tolower(*s1++); | char u1 = tolower((int)(unsigned char)(*s1++)); | |||
| char u2 = tolower(*s2++); | char u2 = tolower((int)(unsigned char)(*s2++)); | |||
| if (u1 != u2) | if (u1 != u2) | |||
| return u1 - u2; | return u1 - u2; | |||
| if (u1 == '\0') | if (u1 == '\0') | |||
| return 0; | return 0; | |||
| } | } | |||
| } | } | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| 9. IANA Considerations | 9. IANA Considerations | |||
| skipping to change at page 120, line 20 ¶ | skipping to change at page 120, line 20 ¶ | |||
| 10. Security Considerations | 10. Security Considerations | |||
| This document is intended to provide convenient open source access by | This document is intended to provide convenient open source access by | |||
| the Internet community to the United States of America Federal | the Internet community to the United States of America Federal | |||
| Information Processing Standard Secure Hash Algorithms (SHAs) [FIPS | Information Processing Standard Secure Hash Algorithms (SHAs) [FIPS | |||
| 180-2], HMACs based thereon, and HKDF. No independent assertion of | 180-2], HMACs based thereon, and HKDF. No independent assertion of | |||
| the security of these functions by the authors for any particular use | the security of these functions by the authors for any particular use | |||
| is intended. | is intended. | |||
| See [SHA1seccon] for a discussion of SHA-1 Security Considerations. | ||||
| 11. Acknowledgements | 11. Acknowledgements | |||
| Thanks for the corrections to [RFC4634] that were provided by Alfred | Thanks for the corrections to [RFC4634] that were provided by Alfred | |||
| Hoenes and Jan Andres and to Alfred's comments on the drafts hereof. | Hoenes and Jan Andres and to Alfred's comments on the drafts hereof. | |||
| Also to the following in alphabetic order, whose comments lead to | ||||
| improvements in the draft: James Carlson, Russ Housley, Tero Kivinen, | ||||
| Juergen Quittek, and Sean Turner. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| 12. References | 12. References | |||
| Normative and Informative References appear below. | Normative and Informative References appear below. | |||
| 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. | |||
| skipping to change at page 121, line 48 ¶ | skipping to change at page 121, line 48 ¶ | |||
| Internet X.509 Public Key Infrastructure Certificate and | Internet X.509 Public Key Infrastructure Certificate and | |||
| Certificate Revocation List (CRL) Profile", RFC 4055, June | Certificate Revocation List (CRL) Profile", RFC 4055, June | |||
| 2005. | 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. | |||
| [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. | |||
| [SHA1seccon] - T. Polk, L. Chen, S. Turner, and P. Hoffman, "Security | ||||
| Considerations for the SHA-0 and SHA-1 Message-Digest | ||||
| Algorithms", draft-turner-sha0-sha1-seccon-05.txt, work in | ||||
| progress, 3 February 2011. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| [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 | |||
| The following changes were made to RFC 4634 to produce this document: | The following changes were made to RFC 4634 to produce this document: | |||
| 1. Add code for HKDF and brief text about HKDF with pointer to | 1. Add code for HKDF and brief text about HKDF with pointer to | |||
| skipping to change at page 122, line 39 ¶ | skipping to change at page 123, line 39 ¶ | |||
| the test driver to detect attempts to run the test driver | the test driver to detect attempts to run the test driver | |||
| after compilation using some other character set instead of | after compilation using some other character set instead of | |||
| [US-ASCII]. | [US-ASCII]. | |||
| 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. Replace 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. Add references to [SHA1seccon]. | |||
| 6. Other assorted editorial improvements. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| Appendix Z: RFC Editor Note, Edit History | Appendix Z: RFC Editor Note, Edit History | |||
| RFC Editor Note: All occurrences of "RFC NNNN" should be edited to | RFC Editor Note: All occurrences of "RFC NNNN" should be edited to | |||
| replace "NNNN" with this documents RFC number. | replace "NNNN" with this documents RFC number. | |||
| RFC Editor: Please delete this Appendix Z on publication. | RFC Editor: Please delete this Appendix Z on publication. | |||
| skipping to change at page 124, line 7 ¶ | skipping to change at page 125, line 7 ¶ | |||
| Fix typos and nits. | Fix typos and nits. | |||
| Z.5 Changes from -04 to -05 | Z.5 Changes from -04 to -05 | |||
| Resolve AD Review comments: Re-order some Abstract and Introduction | Resolve AD Review comments: Re-order some Abstract and Introduction | |||
| material. Make the RFC Editor notes more prominent. | material. Make the RFC Editor notes more prominent. | |||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | |||
| Z.6 Changes from -05 to -06 | ||||
| Add comments to text that test driver assumes ASCII compilation. Add | ||||
| run time test for compilation with other character systems. | ||||
| Assume stdint.h is available but add stdint-example.h for use if it | ||||
| isn't. | ||||
| Z.7 Changes from -06 to -07 | ||||
| Remove wording from comments in code which could be interpreted to | ||||
| make assertions of cryptographic strength. Add grouping parenthesis | ||||
| at one point in text for clarity. Add three names to the | ||||
| Acknowledgements. | ||||
| Z.8 Changes fro -07 to -08 | ||||
| Add references to [SHA1seccon]. Add one person to acknowledgements | ||||
| list. Expand the HKDF acronym. | ||||
| INTERNET-DRAFT SHAs, HMAC-SHAs, and HKDF | ||||
| Author's Address | Author's Address | |||
| Donald Eastlake | Donald Eastlake | |||
| Huawei | Huawei | |||
| 155 Beaver Street | 155 Beaver Street | |||
| Milford, MA 01757 USA | Milford, MA 01757 USA | |||
| Telephone: +1-508-333-2270 | Telephone: +1-508-333-2270 | |||
| EMail: d3e3e3@gmail.com | EMail: d3e3e3@gmail.com | |||
| End of changes. 143 change blocks. | ||||
| 191 lines changed or deleted | 225 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/ | ||||