< 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/