summaryrefslogtreecommitdiff
path: root/contrib/bind9/doc/rfc
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/bind9/doc/rfc')
-rw-r--r--contrib/bind9/doc/rfc/index6
-rw-r--r--contrib/bind9/doc/rfc/rfc4398.txt955
-rw-r--r--contrib/bind9/doc/rfc/rfc4408.txt2691
-rw-r--r--contrib/bind9/doc/rfc/rfc4470.txt451
-rw-r--r--contrib/bind9/doc/rfc/rfc4634.txt6051
-rw-r--r--contrib/bind9/doc/rfc/rfc4641.txt1963
6 files changed, 12117 insertions, 0 deletions
diff --git a/contrib/bind9/doc/rfc/index b/contrib/bind9/doc/rfc/index
index 947827e59a84..990d4a90be04 100644
--- a/contrib/bind9/doc/rfc/index
+++ b/contrib/bind9/doc/rfc/index
@@ -105,4 +105,10 @@
4255: Using DNS to Securely Publish Secure Shell (SSH) Key Fingerprints
4343: Domain Name System (DNS) Case Insensitivity Clarification
4367: What's in a Name: False Assumptions about DNS Names
+4398: Storing Certificates in the Domain Name System (DNS)
4431: The DNSSEC Lookaside Validation (DLV) DNS Resource Record
+4408: Sender Policy Framework (SPF) for Authorizing Use of Domains
+ in E-Mail, Version 1
+4470: Minimally Covering NSEC Records and DNSSEC On-line Signing
+4634: US Secure Hash Algorithms (SHA and HMAC-SHA)
+4641: DNSSEC Operational Practices
diff --git a/contrib/bind9/doc/rfc/rfc4398.txt b/contrib/bind9/doc/rfc/rfc4398.txt
new file mode 100644
index 000000000000..6437436e6a96
--- /dev/null
+++ b/contrib/bind9/doc/rfc/rfc4398.txt
@@ -0,0 +1,955 @@
+
+
+
+
+
+
+Network Working Group S. Josefsson
+Request for Comments: 4398 March 2006
+Obsoletes: 2538
+Category: Standards Track
+
+
+ Storing Certificates in the Domain Name System (DNS)
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+Abstract
+
+ Cryptographic public keys are frequently published, and their
+ authenticity is demonstrated by certificates. A CERT resource record
+ (RR) is defined so that such certificates and related certificate
+ revocation lists can be stored in the Domain Name System (DNS).
+
+ This document obsoletes RFC 2538.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 1]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+Table of Contents
+
+ 1. Introduction ....................................................3
+ 2. The CERT Resource Record ........................................3
+ 2.1. Certificate Type Values ....................................4
+ 2.2. Text Representation of CERT RRs ............................6
+ 2.3. X.509 OIDs .................................................6
+ 3. Appropriate Owner Names for CERT RRs ............................7
+ 3.1. Content-Based X.509 CERT RR Names ..........................8
+ 3.2. Purpose-Based X.509 CERT RR Names ..........................9
+ 3.3. Content-Based OpenPGP CERT RR Names ........................9
+ 3.4. Purpose-Based OpenPGP CERT RR Names .......................10
+ 3.5. Owner Names for IPKIX, ISPKI, IPGP, and IACPKIX ...........10
+ 4. Performance Considerations .....................................11
+ 5. Contributors ...................................................11
+ 6. Acknowledgements ...............................................11
+ 7. Security Considerations ........................................12
+ 8. IANA Considerations ............................................12
+ 9. Changes since RFC 2538 .........................................13
+ 10. References ....................................................14
+ 10.1. Normative References .....................................14
+ 10.2. Informative References ...................................15
+ Appendix A. Copying Conditions ...................................16
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 2]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+1. Introduction
+
+ Public keys are frequently published in the form of a certificate,
+ and their authenticity is commonly demonstrated by certificates and
+ related certificate revocation lists (CRLs). A certificate is a
+ binding, through a cryptographic digital signature, of a public key,
+ a validity interval and/or conditions, and identity, authorization,
+ or other information. A certificate revocation list is a list of
+ certificates that are revoked, and of incidental information, all
+ signed by the signer (issuer) of the revoked certificates. Examples
+ are X.509 certificates/CRLs in the X.500 directory system or OpenPGP
+ certificates/revocations used by OpenPGP software.
+
+ Section 2 specifies a CERT resource record (RR) for the storage of
+ certificates in the Domain Name System [1] [2].
+
+ Section 3 discusses appropriate owner names for CERT RRs.
+
+ Sections 4, 7, and 8 cover performance, security, and IANA
+ considerations, respectively.
+
+ Section 9 explains the changes in this document compared to RFC 2538.
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [3].
+
+2. The CERT Resource Record
+
+ The CERT resource record (RR) has the structure given below. Its RR
+ type code is 37.
+
+ 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
+ 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | type | key tag |
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+ | algorithm | /
+ +---------------+ certificate or CRL /
+ / /
+ +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
+
+ The type field is the certificate type as defined in Section 2.1
+ below.
+
+ The key tag field is the 16-bit value computed for the key embedded
+ in the certificate, using the RRSIG Key Tag algorithm described in
+ Appendix B of [12]. This field is used as an efficiency measure to
+
+
+
+Josefsson Standards Track [Page 3]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ pick which CERT RRs may be applicable to a particular key. The key
+ tag can be calculated for the key in question, and then only CERT RRs
+ with the same key tag need to be examined. Note that two different
+ keys can have the same key tag. However, the key MUST be transformed
+ to the format it would have as the public key portion of a DNSKEY RR
+ before the key tag is computed. This is only possible if the key is
+ applicable to an algorithm and complies to limits (such as key size)
+ defined for DNS security. If it is not, the algorithm field MUST be
+ zero and the tag field is meaningless and SHOULD be zero.
+
+ The algorithm field has the same meaning as the algorithm field in
+ DNSKEY and RRSIG RRs [12], except that a zero algorithm field
+ indicates that the algorithm is unknown to a secure DNS, which may
+ simply be the result of the algorithm not having been standardized
+ for DNSSEC [11].
+
+2.1. Certificate Type Values
+
+ The following values are defined or reserved:
+
+ Value Mnemonic Certificate Type
+ ----- -------- ----------------
+ 0 Reserved
+ 1 PKIX X.509 as per PKIX
+ 2 SPKI SPKI certificate
+ 3 PGP OpenPGP packet
+ 4 IPKIX The URL of an X.509 data object
+ 5 ISPKI The URL of an SPKI certificate
+ 6 IPGP The fingerprint and URL of an OpenPGP packet
+ 7 ACPKIX Attribute Certificate
+ 8 IACPKIX The URL of an Attribute Certificate
+ 9-252 Available for IANA assignment
+ 253 URI URI private
+ 254 OID OID private
+ 255 Reserved
+ 256-65279 Available for IANA assignment
+ 65280-65534 Experimental
+ 65535 Reserved
+
+ These values represent the initial content of the IANA registry; see
+ Section 8.
+
+ The PKIX type is reserved to indicate an X.509 certificate conforming
+ to the profile defined by the IETF PKIX working group [8]. The
+ certificate section will start with a one-octet unsigned OID length
+ and then an X.500 OID indicating the nature of the remainder of the
+
+
+
+
+
+Josefsson Standards Track [Page 4]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ certificate section (see Section 2.3, below). (NOTE: X.509
+ certificates do not include their X.500 directory-type-designating
+ OID as a prefix.)
+
+ The SPKI and ISPKI types are reserved to indicate the SPKI
+ certificate format [15], for use when the SPKI documents are moved
+ from experimental status. The format for these two CERT RR types
+ will need to be specified later.
+
+ The PGP type indicates an OpenPGP packet as described in [5] and its
+ extensions and successors. This is used to transfer public key
+ material and revocation signatures. The data is binary and MUST NOT
+ be encoded into an ASCII armor. An implementation SHOULD process
+ transferable public keys as described in Section 10.1 of [5], but it
+ MAY handle additional OpenPGP packets.
+
+ The ACPKIX type indicates an Attribute Certificate format [9].
+
+ The IPKIX and IACPKIX types indicate a URL that will serve the
+ content that would have been in the "certificate, CRL, or URL" field
+ of the corresponding type (PKIX or ACPKIX, respectively).
+
+ The IPGP type contains both an OpenPGP fingerprint for the key in
+ question, as well as a URL. The certificate portion of the IPGP CERT
+ RR is defined as a one-octet fingerprint length, followed by the
+ OpenPGP fingerprint, followed by the URL. The OpenPGP fingerprint is
+ calculated as defined in RFC 2440 [5]. A zero-length fingerprint or
+ a zero-length URL are legal, and indicate URL-only IPGP data or
+ fingerprint-only IPGP data, respectively. A zero-length fingerprint
+ and a zero-length URL are meaningless and invalid.
+
+ The IPKIX, ISPKI, IPGP, and IACPKIX types are known as "indirect".
+ These types MUST be used when the content is too large to fit in the
+ CERT RR and MAY be used at the implementer's discretion. They SHOULD
+ NOT be used where the DNS message is 512 octets or smaller and could
+ thus be expected to fit a UDP packet.
+
+ The URI private type indicates a certificate format defined by an
+ absolute URI. The certificate portion of the CERT RR MUST begin with
+ a null-terminated URI [10], and the data after the null is the
+ private format certificate itself. The URI SHOULD be such that a
+ retrieval from it will lead to documentation on the format of the
+ certificate. Recognition of private certificate types need not be
+ based on URI equality but can use various forms of pattern matching
+ so that, for example, subtype or version information can also be
+ encoded into the URI.
+
+
+
+
+
+Josefsson Standards Track [Page 5]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ The OID private type indicates a private format certificate specified
+ by an ISO OID prefix. The certificate section will start with a
+ one-octet unsigned OID length and then a BER-encoded OID indicating
+ the nature of the remainder of the certificate section. This can be
+ an X.509 certificate format or some other format. X.509 certificates
+ that conform to the IETF PKIX profile SHOULD be indicated by the PKIX
+ type, not the OID private type. Recognition of private certificate
+ types need not be based on OID equality but can use various forms of
+ pattern matching such as OID prefix.
+
+2.2. Text Representation of CERT RRs
+
+ The RDATA portion of a CERT RR has the type field as an unsigned
+ decimal integer or as a mnemonic symbol as listed in Section 2.1,
+ above.
+
+ The key tag field is represented as an unsigned decimal integer.
+
+ The algorithm field is represented as an unsigned decimal integer or
+ a mnemonic symbol as listed in [12].
+
+ The certificate/CRL portion is represented in base 64 [16] and may be
+ divided into any number of white-space-separated substrings, down to
+ single base-64 digits, which are concatenated to obtain the full
+ signature. These substrings can span lines using the standard
+ parenthesis.
+
+ Note that the certificate/CRL portion may have internal sub-fields,
+ but these do not appear in the master file representation. For
+ example, with type 254, there will be an OID size, an OID, and then
+ the certificate/CRL proper. However, only a single logical base-64
+ string will appear in the text representation.
+
+2.3. X.509 OIDs
+
+ OIDs have been defined in connection with the X.500 directory for
+ user certificates, certification authority certificates, revocations
+ of certification authority, and revocations of user certificates.
+ The following table lists the OIDs, their BER encoding, and their
+ length-prefixed hex format for use in CERT RRs:
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 6]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ id-at-userCertificate
+ = { joint-iso-ccitt(2) ds(5) at(4) 36 }
+ == 0x 03 55 04 24
+ id-at-cACertificate
+ = { joint-iso-ccitt(2) ds(5) at(4) 37 }
+ == 0x 03 55 04 25
+ id-at-authorityRevocationList
+ = { joint-iso-ccitt(2) ds(5) at(4) 38 }
+ == 0x 03 55 04 26
+ id-at-certificateRevocationList
+ = { joint-iso-ccitt(2) ds(5) at(4) 39 }
+ == 0x 03 55 04 27
+
+3. Appropriate Owner Names for CERT RRs
+
+ It is recommended that certificate CERT RRs be stored under a domain
+ name related to their subject, i.e., the name of the entity intended
+ to control the private key corresponding to the public key being
+ certified. It is recommended that certificate revocation list CERT
+ RRs be stored under a domain name related to their issuer.
+
+ Following some of the guidelines below may result in DNS names with
+ characters that require DNS quoting as per Section 5.1 of RFC 1035
+ [2].
+
+ The choice of name under which CERT RRs are stored is important to
+ clients that perform CERT queries. In some situations, the clients
+ may not know all information about the CERT RR object it wishes to
+ retrieve. For example, a client may not know the subject name of an
+ X.509 certificate, or the email address of the owner of an OpenPGP
+ key. Further, the client might only know the hostname of a service
+ that uses X.509 certificates or the Key ID of an OpenPGP key.
+
+ Therefore, two owner name guidelines are defined: content-based owner
+ names and purpose-based owner names. A content-based owner name is
+ derived from the content of the CERT RR data; for example, the
+ Subject field in an X.509 certificate or the User ID field in OpenPGP
+ keys. A purpose-based owner name is a name that a client retrieving
+ CERT RRs ought to know already; for example, the host name of an
+ X.509 protected service or the Key ID of an OpenPGP key. The
+ content-based and purpose-based owner name may be the same; for
+ example, when a client looks up a key based on the From: address of
+ an incoming email.
+
+ Implementations SHOULD use the purpose-based owner name guidelines
+ described in this document and MAY use CNAME RRs at content-based
+ owner names (or other names), pointing to the purpose-based owner
+ name.
+
+
+
+Josefsson Standards Track [Page 7]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ Note that this section describes an application-based mapping from
+ the name space used in a certificate to the name space used by DNS.
+ The DNS does not infer any relationship amongst CERT resource records
+ based on similarities or differences of the DNS owner name(s) of CERT
+ resource records. For example, if multiple labels are used when
+ mapping from a CERT identifier to a domain name, then care must be
+ taken in understanding wildcard record synthesis.
+
+3.1. Content-Based X.509 CERT RR Names
+
+ Some X.509 versions, such as the PKIX profile of X.509 [8], permit
+ multiple names to be associated with subjects and issuers under
+ "Subject Alternative Name" and "Issuer Alternative Name". For
+ example, the PKIX profile has such Alternate Names with an ASN.1
+ specification as follows:
+
+ GeneralName ::= CHOICE {
+ otherName [0] OtherName,
+ rfc822Name [1] IA5String,
+ dNSName [2] IA5String,
+ x400Address [3] ORAddress,
+ directoryName [4] Name,
+ ediPartyName [5] EDIPartyName,
+ uniformResourceIdentifier [6] IA5String,
+ iPAddress [7] OCTET STRING,
+ registeredID [8] OBJECT IDENTIFIER }
+
+ The recommended locations of CERT storage are as follows, in priority
+ order:
+
+ 1. If a domain name is included in the identification in the
+ certificate or CRL, that ought to be used.
+ 2. If a domain name is not included but an IP address is included,
+ then the translation of that IP address into the appropriate
+ inverse domain name ought to be used.
+ 3. If neither of the above is used, but a URI containing a domain
+ name is present, that domain name ought to be used.
+ 4. If none of the above is included but a character string name is
+ included, then it ought to be treated as described below for
+ OpenPGP names.
+ 5. If none of the above apply, then the distinguished name (DN)
+ ought to be mapped into a domain name as specified in [4].
+
+ Example 1: An X.509v3 certificate is issued to /CN=John Doe /DC=Doe/
+ DC=com/DC=xy/O=Doe Inc/C=XY/ with Subject Alternative Names of (a)
+ string "John (the Man) Doe", (b) domain name john-doe.com, and (c)
+ URI <https://www.secure.john-doe.com:8080/>. The storage locations
+ recommended, in priority order, would be
+
+
+
+Josefsson Standards Track [Page 8]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ 1. john-doe.com,
+ 2. www.secure.john-doe.com, and
+ 3. Doe.com.xy.
+
+ Example 2: An X.509v3 certificate is issued to /CN=James Hacker/
+ L=Basingstoke/O=Widget Inc/C=GB/ with Subject Alternate names of (a)
+ domain name widget.foo.example, (b) IPv4 address 10.251.13.201, and
+ (c) string "James Hacker <hacker@mail.widget.foo.example>". The
+ storage locations recommended, in priority order, would be
+
+ 1. widget.foo.example,
+ 2. 201.13.251.10.in-addr.arpa, and
+ 3. hacker.mail.widget.foo.example.
+
+3.2. Purpose-Based X.509 CERT RR Names
+
+ Due to the difficulty for clients that do not already possess a
+ certificate to reconstruct the content-based owner name,
+ purpose-based owner names are recommended in this section.
+ Recommendations for purpose-based owner names vary per scenario. The
+ following table summarizes the purpose-based X.509 CERT RR owner name
+ guidelines for use with S/MIME [17], SSL/TLS [13], and IPsec [14]:
+
+ Scenario Owner name
+ ------------------ ----------------------------------------------
+ S/MIME Certificate Standard translation of an RFC 2822 email
+ address. Example: An S/MIME certificate for
+ "postmaster@example.org" will use a standard
+ hostname translation of the owner name,
+ "postmaster.example.org".
+
+ TLS Certificate Hostname of the TLS server.
+
+ IPsec Certificate Hostname of the IPsec machine and/or, for IPv4
+ or IPv6 addresses, the fully qualified domain
+ name in the appropriate reverse domain.
+
+ An alternate approach for IPsec is to store raw public keys [18].
+
+3.3. Content-Based OpenPGP CERT RR Names
+
+ OpenPGP signed keys (certificates) use a general character string
+ User ID [5]. However, it is recommended by OpenPGP that such names
+ include the RFC 2822 [7] email address of the party, as in "Leslie
+ Example <Leslie@host.example>". If such a format is used, the CERT
+ ought to be under the standard translation of the email address into
+
+
+
+
+
+Josefsson Standards Track [Page 9]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ a domain name, which would be leslie.host.example in this case. If
+ no RFC 2822 name can be extracted from the string name, no specific
+ domain name is recommended.
+
+ If a user has more than one email address, the CNAME type can be used
+ to reduce the amount of data stored in the DNS. For example:
+
+ $ORIGIN example.org.
+ smith IN CERT PGP 0 0 <OpenPGP binary>
+ john.smith IN CNAME smith
+ js IN CNAME smith
+
+3.4. Purpose-Based OpenPGP CERT RR Names
+
+ Applications that receive an OpenPGP packet containing encrypted or
+ signed data but do not know the email address of the sender will have
+ difficulties constructing the correct owner name and cannot use the
+ content-based owner name guidelines. However, these clients commonly
+ know the key fingerprint or the Key ID. The key ID is found in
+ OpenPGP packets, and the key fingerprint is commonly found in
+ auxiliary data that may be available. In this case, use of an owner
+ name identical to the key fingerprint and the key ID expressed in
+ hexadecimal [16] is recommended. For example:
+
+ $ORIGIN example.org.
+ 0424D4EE81A0E3D119C6F835EDA21E94B565716F IN CERT PGP ...
+ F835EDA21E94B565716F IN CERT PGP ...
+ B565716F IN CERT PGP ...
+
+ If the same key material is stored for several owner names, the use
+ of CNAME may help avoid data duplication. Note that CNAME is not
+ always applicable, because it maps one owner name to the other for
+ all purposes, which may be sub-optimal when two keys with the same
+ Key ID are stored.
+
+3.5. Owner Names for IPKIX, ISPKI, IPGP, and IACPKIX
+
+ These types are stored under the same owner names, both purpose- and
+ content-based, as the PKIX, SPKI, PGP, and ACPKIX types.
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 10]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+4. Performance Considerations
+
+ The Domain Name System (DNS) protocol was designed for small
+ transfers, typically below 512 octets. While larger transfers will
+ perform correctly and work is underway to make larger transfers more
+ efficient, it is still advisable at this time that every reasonable
+ effort be made to minimize the size of certificates stored within the
+ DNS. Steps that can be taken may include using the fewest possible
+ optional or extension fields and using short field values for
+ necessary variable-length fields.
+
+ The RDATA field in the DNS protocol may only hold data of size 65535
+ octets (64kb) or less. This means that each CERT RR MUST NOT contain
+ more than 64kb of payload, even if the corresponding certificate or
+ certificate revocation list is larger. This document addresses this
+ by defining "indirect" data types for each normal type.
+
+ Deploying CERT RRs to support digitally signed email changes the
+ access patterns of DNS lookups from per-domain to per-user. If
+ digitally signed email and a key/certificate lookup based on CERT RRs
+ are deployed on a wide scale, this may lead to an increased DNS load,
+ with potential performance and cache effectiveness consequences.
+ Whether or not this load increase will be noticeable is not known.
+
+5. Contributors
+
+ The majority of this document is copied verbatim from RFC 2538, by
+ Donald Eastlake 3rd and Olafur Gudmundsson.
+
+6. Acknowledgements
+
+ Thanks to David Shaw and Michael Graff for their contributions to
+ earlier works that motivated, and served as inspiration for, this
+ document.
+
+ This document was improved by suggestions and comments from Olivier
+ Dubuisson, Scott Hollenbeck, Russ Housley, Peter Koch, Olaf M.
+ Kolkman, Ben Laurie, Edward Lewis, John Loughney, Allison Mankin,
+ Douglas Otis, Marcos Sanz, Pekka Savola, Jason Sloderbeck, Samuel
+ Weiler, and Florian Weimer. No doubt the list is incomplete. We
+ apologize to anyone we left out.
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 11]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+7. Security Considerations
+
+ By definition, certificates contain their own authenticating
+ signatures. Thus, it is reasonable to store certificates in
+ non-secure DNS zones or to retrieve certificates from DNS with DNS
+ security checking not implemented or deferred for efficiency. The
+ results may be trusted if the certificate chain is verified back to a
+ known trusted key and this conforms with the user's security policy.
+
+ Alternatively, if certificates are retrieved from a secure DNS zone
+ with DNS security checking enabled and are verified by DNS security,
+ the key within the retrieved certificate may be trusted without
+ verifying the certificate chain if this conforms with the user's
+ security policy.
+
+ If an organization chooses to issue certificates for its employees,
+ placing CERT RRs in the DNS by owner name, and if DNSSEC (with NSEC)
+ is in use, it is possible for someone to enumerate all employees of
+ the organization. This is usually not considered desirable, for the
+ same reason that enterprise phone listings are not often publicly
+ published and are even marked confidential.
+
+ Using the URI type introduces another level of indirection that may
+ open a new vulnerability. One method of securing that indirection is
+ to include a hash of the certificate in the URI itself.
+
+ If DNSSEC is used, then the non-existence of a CERT RR and,
+ consequently, certificates or revocation lists can be securely
+ asserted. Without DNSSEC, this is not possible.
+
+8. IANA Considerations
+
+ The IANA has created a new registry for CERT RR: certificate types.
+ The initial contents of this registry is:
+
+ Decimal Type Meaning Reference
+ ------- ---- ------- ---------
+ 0 Reserved RFC 4398
+ 1 PKIX X.509 as per PKIX RFC 4398
+ 2 SPKI SPKI certificate RFC 4398
+ 3 PGP OpenPGP packet RFC 4398
+ 4 IPKIX The URL of an X.509 data object RFC 4398
+ 5 ISPKI The URL of an SPKI certificate RFC 4398
+ 6 IPGP The fingerprint and URL RFC 4398
+ of an OpenPGP packet
+ 7 ACPKIX Attribute Certificate RFC 4398
+ 8 IACPKIX The URL of an Attribute RFC 4398
+ Certificate
+
+
+
+Josefsson Standards Track [Page 12]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ 9-252 Available for IANA assignment
+ by IETF Standards action
+ 253 URI URI private RFC 4398
+ 254 OID OID private RFC 4398
+ 255 Reserved RFC 4398
+ 256-65279 Available for IANA assignment
+ by IETF Consensus
+ 65280-65534 Experimental RFC 4398
+ 65535 Reserved RFC 4398
+
+ Certificate types 0x0000 through 0x00FF and 0xFF00 through 0xFFFF can
+ only be assigned by an IETF standards action [6]. This document
+ assigns 0x0001 through 0x0008 and 0x00FD and 0x00FE. Certificate
+ types 0x0100 through 0xFEFF are assigned through IETF Consensus [6]
+ based on RFC documentation of the certificate type. The availability
+ of private types under 0x00FD and 0x00FE ought to satisfy most
+ requirements for proprietary or private types.
+
+ The CERT RR reuses the DNS Security Algorithm Numbers registry. In
+ particular, the CERT RR requires that algorithm number 0 remain
+ reserved, as described in Section 2. The IANA will reference the
+ CERT RR as a user of this registry and value 0, in particular.
+
+9. Changes since RFC 2538
+
+ 1. Editorial changes to conform with new document requirements,
+ including splitting reference section into two parts and
+ updating the references to point at latest versions, and to add
+ some additional references.
+ 2. Improve terminology. For example replace "PGP" with "OpenPGP",
+ to align with RFC 2440.
+ 3. In Section 2.1, clarify that OpenPGP public key data are binary,
+ not the ASCII armored format, and reference 10.1 in RFC 2440 on
+ how to deal with OpenPGP keys, and acknowledge that
+ implementations may handle additional packet types.
+ 4. Clarify that integers in the representation format are decimal.
+ 5. Replace KEY/SIG with DNSKEY/RRSIG etc, to align with DNSSECbis
+ terminology. Improve reference for Key Tag Algorithm
+ calculations.
+ 6. Add examples that suggest use of CNAME to reduce bandwidth.
+ 7. In Section 3, appended the last paragraphs that discuss
+ "content-based" vs "purpose-based" owner names. Add Section 3.2
+ for purpose-based X.509 CERT owner names, and Section 3.4 for
+ purpose-based OpenPGP CERT owner names.
+ 8. Added size considerations.
+ 9. The SPKI types has been reserved, until RFC 2692/2693 is moved
+ from the experimental status.
+ 10. Added indirect types IPKIX, ISPKI, IPGP, and IACPKIX.
+
+
+
+Josefsson Standards Track [Page 13]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+ 11. An IANA registry of CERT type values was created.
+
+10. References
+
+10.1. Normative References
+
+ [1] Mockapetris, P., "Domain names - concepts and facilities",
+ STD 13, RFC 1034, November 1987.
+
+ [2] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+ [3] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [4] Kille, S., Wahl, M., Grimstad, A., Huber, R., and S. Sataluri,
+ "Using Domains in LDAP/X.500 Distinguished Names", RFC 2247,
+ January 1998.
+
+ [5] Callas, J., Donnerhacke, L., Finney, H., and R. Thayer,
+ "OpenPGP Message Format", RFC 2440, November 1998.
+
+ [6] Narten, T. and H. Alvestrand, "Guidelines for Writing an IANA
+ Considerations Section in RFCs", BCP 26, RFC 2434,
+ October 1998.
+
+ [7] Resnick, P., "Internet Message Format", RFC 2822, April 2001.
+
+ [8] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet X.509
+ Public Key Infrastructure Certificate and Certificate
+ Revocation List (CRL) Profile", RFC 3280, April 2002.
+
+ [9] Farrell, S. and R. Housley, "An Internet Attribute Certificate
+ Profile for Authorization", RFC 3281, April 2002.
+
+ [10] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
+ Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986,
+ January 2005.
+
+ [11] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "DNS Security Introduction and Requirements", RFC 4033,
+ March 2005.
+
+ [12] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "Resource Records for the DNS Security Extensions", RFC 4034,
+ March 2005.
+
+
+
+
+
+Josefsson Standards Track [Page 14]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+10.2. Informative References
+
+ [13] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
+ RFC 2246, January 1999.
+
+ [14] Kent, S. and K. Seo, "Security Architecture for the Internet
+ Protocol", RFC 4301, December 2005.
+
+ [15] Ellison, C., Frantz, B., Lampson, B., Rivest, R., Thomas, B.,
+ and T. Ylonen, "SPKI Certificate Theory", RFC 2693,
+ September 1999.
+
+ [16] Josefsson, S., "The Base16, Base32, and Base64 Data Encodings",
+ RFC 3548, July 2003.
+
+ [17] Ramsdell, B., "Secure/Multipurpose Internet Mail Extensions
+ (S/MIME) Version 3.1 Message Specification", RFC 3851,
+ July 2004.
+
+ [18] Richardson, M., "A Method for Storing IPsec Keying Material in
+ DNS", RFC 4025, March 2005.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 15]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+Appendix A. Copying Conditions
+
+ Regarding the portion of this document that was written by Simon
+ Josefsson ("the author", for the remainder of this section), the
+ author makes no guarantees and is not responsible for any damage
+ resulting from its use. The author grants irrevocable permission to
+ anyone to use, modify, and distribute it in any way that does not
+ diminish the rights of anyone else to use, modify, and distribute it,
+ provided that redistributed derivative works do not contain
+ misleading author or version information. Derivative works need not
+ be licensed under similar terms.
+
+Author's Address
+
+ Simon Josefsson
+
+ EMail: simon@josefsson.org
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 16]
+
+RFC 4398 Storing Certificates in the DNS February 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Josefsson Standards Track [Page 17]
+
diff --git a/contrib/bind9/doc/rfc/rfc4408.txt b/contrib/bind9/doc/rfc/rfc4408.txt
new file mode 100644
index 000000000000..bc1b3f539cad
--- /dev/null
+++ b/contrib/bind9/doc/rfc/rfc4408.txt
@@ -0,0 +1,2691 @@
+
+
+
+
+
+
+Network Working Group M. Wong
+Request for Comments: 4408 W. Schlitt
+Category: Experimental April 2006
+
+
+ Sender Policy Framework (SPF) for
+ Authorizing Use of Domains in E-Mail, Version 1
+
+Status of This Memo
+
+ This memo defines an Experimental Protocol for the Internet
+ community. It does not specify an Internet standard of any kind.
+ Discussion and suggestions for improvement are requested.
+ Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+IESG Note
+
+ The following documents (RFC 4405, RFC 4406, RFC 4407, and RFC 4408)
+ are published simultaneously as Experimental RFCs, although there is
+ no general technical consensus and efforts to reconcile the two
+ approaches have failed. As such, these documents have not received
+ full IETF review and are published "AS-IS" to document the different
+ approaches as they were considered in the MARID working group.
+
+ The IESG takes no position about which approach is to be preferred
+ and cautions the reader that there are serious open issues for each
+ approach and concerns about using them in tandem. The IESG believes
+ that documenting the different approaches does less harm than not
+ documenting them.
+
+ Note that the Sender ID experiment may use DNS records that may have
+ been created for the current SPF experiment or earlier versions in
+ this set of experiments. Depending on the content of the record,
+ this may mean that Sender-ID heuristics would be applied incorrectly
+ to a message. Depending on the actions associated by the recipient
+ with those heuristics, the message may not be delivered or may be
+ discarded on receipt.
+
+ Participants relying on Sender ID experiment DNS records are warned
+ that they may lose valid messages in this set of circumstances.
+ aParticipants publishing SPF experiment DNS records should consider
+ the advice given in section 3.4 of RFC 4406 and may wish to publish
+ both v=spf1 and spf2.0 records to avoid the conflict.
+
+
+
+
+Wong & Schlitt Experimental [Page 1]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Participants in the Sender-ID experiment need to be aware that the
+ way Resent-* header fields are used will result in failure to receive
+ legitimate email when interacting with standards-compliant systems
+ (specifically automatic forwarders which comply with the standards by
+ not adding Resent-* headers, and systems which comply with RFC 822
+ but have not yet implemented RFC 2822 Resent-* semantics). It would
+ be inappropriate to advance Sender-ID on the standards track without
+ resolving this interoperability problem.
+
+ The community is invited to observe the success or failure of the two
+ approaches during the two years following publication, in order that
+ a community consensus can be reached in the future.
+
+Abstract
+
+ E-mail on the Internet can be forged in a number of ways. In
+ particular, existing protocols place no restriction on what a sending
+ host can use as the reverse-path of a message or the domain given on
+ the SMTP HELO/EHLO commands. This document describes version 1 of
+ the Sender Policy Framework (SPF) protocol, whereby a domain may
+ explicitly authorize the hosts that are allowed to use its domain
+ name, and a receiving host may check such authorization.
+
+Table of Contents
+
+ 1. Introduction ....................................................4
+ 1.1. Protocol Status ............................................4
+ 1.2. Terminology ................................................5
+ 2. Operation .......................................................5
+ 2.1. The HELO Identity ..........................................5
+ 2.2. The MAIL FROM Identity .....................................5
+ 2.3. Publishing Authorization ...................................6
+ 2.4. Checking Authorization .....................................6
+ 2.5. Interpreting the Result ....................................7
+ 2.5.1. None ................................................8
+ 2.5.2. Neutral .............................................8
+ 2.5.3. Pass ................................................8
+ 2.5.4. Fail ................................................8
+ 2.5.5. SoftFail ............................................9
+ 2.5.6. TempError ...........................................9
+ 2.5.7. PermError ...........................................9
+ 3. SPF Records .....................................................9
+ 3.1. Publishing ................................................10
+ 3.1.1. DNS Resource Record Types ..........................10
+ 3.1.2. Multiple DNS Records ...............................11
+ 3.1.3. Multiple Strings in a Single DNS record ............11
+ 3.1.4. Record Size ........................................11
+ 3.1.5. Wildcard Records ...................................11
+
+
+
+Wong & Schlitt Experimental [Page 2]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ 4. The check_host() Function ......................................12
+ 4.1. Arguments .................................................12
+ 4.2. Results ...................................................13
+ 4.3. Initial Processing ........................................13
+ 4.4. Record Lookup .............................................13
+ 4.5. Selecting Records .........................................13
+ 4.6. Record Evaluation .........................................14
+ 4.6.1. Term Evaluation ....................................14
+ 4.6.2. Mechanisms .........................................15
+ 4.6.3. Modifiers ..........................................15
+ 4.7. Default Result ............................................16
+ 4.8. Domain Specification ......................................16
+ 5. Mechanism Definitions ..........................................16
+ 5.1. "all" .....................................................17
+ 5.2. "include" .................................................18
+ 5.3. "a" .......................................................19
+ 5.4. "mx" ......................................................20
+ 5.5. "ptr" .....................................................20
+ 5.6. "ip4" and "ip6" ...........................................21
+ 5.7. "exists" ..................................................22
+ 6. Modifier Definitions ...........................................22
+ 6.1. redirect: Redirected Query ................................23
+ 6.2. exp: Explanation ..........................................23
+ 7. The Received-SPF Header Field ..................................25
+ 8. Macros .........................................................27
+ 8.1. Macro Definitions .........................................27
+ 8.2. Expansion Examples ........................................30
+ 9. Implications ...................................................31
+ 9.1. Sending Domains ...........................................31
+ 9.2. Mailing Lists .............................................32
+ 9.3. Forwarding Services and Aliases ...........................32
+ 9.4. Mail Services .............................................34
+ 9.5. MTA Relays ................................................34
+ 10. Security Considerations .......................................35
+ 10.1. Processing Limits ........................................35
+ 10.2. SPF-Authorized E-Mail May Contain Other False
+ Identities ...............................................37
+ 10.3. Spoofed DNS and IP Data ..................................37
+ 10.4. Cross-User Forgery .......................................37
+ 10.5. Untrusted Information Sources ............................38
+ 10.6. Privacy Exposure .........................................38
+ 11. Contributors and Acknowledgements .............................38
+ 12. IANA Considerations ...........................................39
+ 12.1. The SPF DNS Record Type ..................................39
+ 12.2. The Received-SPF Mail Header Field .......................39
+ 13. References ....................................................39
+ 13.1. Normative References .....................................39
+ 13.2. Informative References ...................................40
+
+
+
+Wong & Schlitt Experimental [Page 3]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Appendix A. Collected ABNF .......................................42
+ Appendix B. Extended Examples ....................................44
+ B.1. Simple Examples ..........................................44
+ B.2. Multiple Domain Example ..................................45
+ B.3. DNSBL Style Example ......................................46
+ B.4. Multiple Requirements Example ............................46
+
+1. Introduction
+
+ The current E-Mail infrastructure has the property that any host
+ injecting mail into the mail system can identify itself as any domain
+ name it wants. Hosts can do this at a variety of levels: in
+ particular, the session, the envelope, and the mail headers.
+ Although this feature is desirable in some circumstances, it is a
+ major obstacle to reducing Unsolicited Bulk E-Mail (UBE, aka spam).
+ Furthermore, many domain name holders are understandably concerned
+ about the ease with which other entities may make use of their domain
+ names, often with malicious intent.
+
+ This document defines a protocol by which domain owners may authorize
+ hosts to use their domain name in the "MAIL FROM" or "HELO" identity.
+ Compliant domain holders publish Sender Policy Framework (SPF)
+ records specifying which hosts are permitted to use their names, and
+ compliant mail receivers use the published SPF records to test the
+ authorization of sending Mail Transfer Agents (MTAs) using a given
+ "HELO" or "MAIL FROM" identity during a mail transaction.
+
+ An additional benefit to mail receivers is that after the use of an
+ identity is verified, local policy decisions about the mail can be
+ made based on the sender's domain, rather than the host's IP address.
+ This is advantageous because reputation of domain names is likely to
+ be more accurate than reputation of host IP addresses. Furthermore,
+ if a claimed identity fails verification, local policy can take
+ stronger action against such E-Mail, such as rejecting it.
+
+1.1. Protocol Status
+
+ SPF has been in development since the summer of 2003 and has seen
+ deployment beyond the developers beginning in December 2003. The
+ design of SPF slowly evolved until the spring of 2004 and has since
+ stabilized. There have been quite a number of forms of SPF, some
+ written up as documents, some submitted as Internet Drafts, and many
+ discussed and debated in development forums.
+
+ The goal of this document is to clearly document the protocol defined
+ by earlier draft specifications of SPF as used in existing
+ implementations. This conception of SPF is sometimes called "SPF
+ Classic". It is understood that particular implementations and
+
+
+
+Wong & Schlitt Experimental [Page 4]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ deployments may differ from, and build upon, this work. It is hoped
+ that we have nonetheless captured the common understanding of SPF
+ version 1.
+
+1.2. Terminology
+
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in [RFC2119].
+
+ This document is concerned with the portion of a mail message
+ commonly called "envelope sender", "return path", "reverse path",
+ "bounce address", "2821 FROM", or "MAIL FROM". Since these terms are
+ either not well defined or often used casually, this document defines
+ the "MAIL FROM" identity in Section 2.2. Note that other terms that
+ may superficially look like the common terms, such as "reverse-path",
+ are used only with the defined meanings from normative documents.
+
+2. Operation
+
+2.1. The HELO Identity
+
+ The "HELO" identity derives from either the SMTP HELO or EHLO command
+ (see [RFC2821]). These commands supply the SMTP client (sending
+ host) for the SMTP session. Note that requirements for the domain
+ presented in the EHLO or HELO command are not always clear to the
+ sending party, and SPF clients must be prepared for the "HELO"
+ identity to be malformed or an IP address literal. At the time of
+ this writing, many legitimate E-Mails are delivered with invalid HELO
+ domains.
+
+ It is RECOMMENDED that SPF clients not only check the "MAIL FROM"
+ identity, but also separately check the "HELO" identity by applying
+ the check_host() function (Section 4) to the "HELO" identity as the
+ <sender>.
+
+2.2. The MAIL FROM Identity
+
+ The "MAIL FROM" identity derives from the SMTP MAIL command (see
+ [RFC2821]). This command supplies the "reverse-path" for a message,
+ which generally consists of the sender mailbox, and is the mailbox to
+ which notification messages are to be sent if there are problems
+ delivering the message.
+
+ [RFC2821] allows the reverse-path to be null (see Section 4.5.5 in
+ RFC 2821). In this case, there is no explicit sender mailbox, and
+ such a message can be assumed to be a notification message from the
+ mail system itself. When the reverse-path is null, this document
+
+
+
+Wong & Schlitt Experimental [Page 5]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ defines the "MAIL FROM" identity to be the mailbox composed of the
+ localpart "postmaster" and the "HELO" identity (which may or may not
+ have been checked separately before).
+
+ SPF clients MUST check the "MAIL FROM" identity. SPF clients check
+ the "MAIL FROM" identity by applying the check_host() function to the
+ "MAIL FROM" identity as the <sender>.
+
+2.3. Publishing Authorization
+
+ An SPF-compliant domain MUST publish a valid SPF record as described
+ in Section 3. This record authorizes the use of the domain name in
+ the "HELO" and "MAIL FROM" identities by the MTAs it specifies.
+
+ If domain owners choose to publish SPF records, it is RECOMMENDED
+ that they end in "-all", or redirect to other records that do, so
+ that a definitive determination of authorization can be made.
+
+ Domain holders may publish SPF records that explicitly authorize no
+ hosts if mail should never originate using that domain.
+
+ When changing SPF records, care must be taken to ensure that there is
+ a transition period so that the old policy remains valid until all
+ legitimate E-Mail has been checked.
+
+2.4. Checking Authorization
+
+ A mail receiver can perform a set of SPF checks for each mail message
+ it receives. An SPF check tests the authorization of a client host
+ to emit mail with a given identity. Typically, such checks are done
+ by a receiving MTA, but can be performed elsewhere in the mail
+ processing chain so long as the required information is available and
+ reliable. At least the "MAIL FROM" identity MUST be checked, but it
+ is RECOMMENDED that the "HELO" identity also be checked beforehand.
+
+ Without explicit approval of the domain owner, checking other
+ identities against SPF version 1 records is NOT RECOMMENDED because
+ there are cases that are known to give incorrect results. For
+ example, almost all mailing lists rewrite the "MAIL FROM" identity
+ (see Section 9.2), but some do not change any other identities in the
+ message. The scenario described in Section 9.3, sub-section 1.2, is
+ another example. Documents that define other identities should
+ define the method for explicit approval.
+
+ It is possible that mail receivers will use the SPF check as part of
+ a larger set of tests on incoming mail. The results of other tests
+ may influence whether or not a particular SPF check is performed.
+ For example, finding the sending host's IP address on a local white
+
+
+
+Wong & Schlitt Experimental [Page 6]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ list may cause all other tests to be skipped and all mail from that
+ host to be accepted.
+
+ When a mail receiver decides to perform an SPF check, it MUST use a
+ correctly-implemented check_host() function (Section 4) evaluated
+ with the correct parameters. Although the test as a whole is
+ optional, once it has been decided to perform a test it must be
+ performed as specified so that the correct semantics are preserved
+ between publisher and receiver.
+
+ To make the test, the mail receiver MUST evaluate the check_host()
+ function with the arguments set as follows:
+
+ <ip> - the IP address of the SMTP client that is emitting the
+ mail, either IPv4 or IPv6.
+
+ <domain> - the domain portion of the "MAIL FROM" or "HELO" identity.
+
+ <sender> - the "MAIL FROM" or "HELO" identity.
+
+ Note that the <domain> argument may not be a well-formed domain name.
+ For example, if the reverse-path was null, then the EHLO/HELO domain
+ is used, with its associated problems (see Section 2.1). In these
+ cases, check_host() is defined in Section 4.3 to return a "None"
+ result.
+
+ Although invalid, malformed, or non-existent domains cause SPF checks
+ to return "None" because no SPF record can be found, it has long been
+ the policy of many MTAs to reject E-Mail from such domains,
+ especially in the case of invalid "MAIL FROM". In order to prevent
+ the circumvention of SPF records, rejecting E-Mail from invalid
+ domains should be considered.
+
+ Implementations must take care to correctly extract the <domain> from
+ the data given with the SMTP MAIL FROM command as many MTAs will
+ still accept such things as source routes (see [RFC2821], Appendix
+ C), the %-hack (see [RFC1123]), and bang paths (see [RFC1983]).
+ These archaic features have been maliciously used to bypass security
+ systems.
+
+2.5. Interpreting the Result
+
+ This section describes how software that performs the authorization
+ should interpret the results of the check_host() function. The
+ authorization check SHOULD be performed during the processing of the
+ SMTP transaction that sends the mail. This allows errors to be
+ returned directly to the sending MTA by way of SMTP replies.
+
+
+
+
+Wong & Schlitt Experimental [Page 7]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Performing the authorization after the SMTP transaction has finished
+ may cause problems, such as the following: (1) It may be difficult to
+ accurately extract the required information from potentially
+ deceptive headers; (2) legitimate E-Mail may fail because the
+ sender's policy may have since changed.
+
+ Generating non-delivery notifications to forged identities that have
+ failed the authorization check is generally abusive and against the
+ explicit wishes of the identity owner.
+
+2.5.1. None
+
+ A result of "None" means that no records were published by the domain
+ or that no checkable sender domain could be determined from the given
+ identity. The checking software cannot ascertain whether or not the
+ client host is authorized.
+
+2.5.2. Neutral
+
+ The domain owner has explicitly stated that he cannot or does not
+ want to assert whether or not the IP address is authorized. A
+ "Neutral" result MUST be treated exactly like the "None" result; the
+ distinction exists only for informational purposes. Treating
+ "Neutral" more harshly than "None" would discourage domain owners
+ from testing the use of SPF records (see Section 9.1).
+
+2.5.3. Pass
+
+ A "Pass" result means that the client is authorized to inject mail
+ with the given identity. The domain can now, in the sense of
+ reputation, be considered responsible for sending the message.
+ Further policy checks can now proceed with confidence in the
+ legitimate use of the identity.
+
+2.5.4. Fail
+
+ A "Fail" result is an explicit statement that the client is not
+ authorized to use the domain in the given identity. The checking
+ software can choose to mark the mail based on this or to reject the
+ mail outright.
+
+ If the checking software chooses to reject the mail during the SMTP
+ transaction, then it SHOULD use an SMTP reply code of 550 (see
+ [RFC2821]) and, if supported, the 5.7.1 Delivery Status Notification
+ (DSN) code (see [RFC3464]), in addition to an appropriate reply text.
+ The check_host() function may return either a default explanation
+ string or one from the domain that published the SPF records (see
+ Section 6.2). If the information does not originate with the
+
+
+
+Wong & Schlitt Experimental [Page 8]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ checking software, it should be made clear that the text is provided
+ by the sender's domain. For example:
+
+ 550-5.7.1 SPF MAIL FROM check failed:
+ 550-5.7.1 The domain example.com explains:
+ 550 5.7.1 Please see http://www.example.com/mailpolicy.html
+
+2.5.5. SoftFail
+
+ A "SoftFail" result should be treated as somewhere between a "Fail"
+ and a "Neutral". The domain believes the host is not authorized but
+ is not willing to make that strong of a statement. Receiving
+ software SHOULD NOT reject the message based solely on this result,
+ but MAY subject the message to closer scrutiny than normal.
+
+ The domain owner wants to discourage the use of this host and thus
+ desires limited feedback when a "SoftFail" result occurs. For
+ example, the recipient's Mail User Agent (MUA) could highlight the
+ "SoftFail" status, or the receiving MTA could give the sender a
+ message using a technique called "greylisting" whereby the MTA can
+ issue an SMTP reply code of 451 (4.3.0 DSN code) with a note the
+ first time the message is received, but accept it the second time.
+
+2.5.6. TempError
+
+ A "TempError" result means that the SPF client encountered a
+ transient error while performing the check. Checking software can
+ choose to accept or temporarily reject the message. If the message
+ is rejected during the SMTP transaction for this reason, the software
+ SHOULD use an SMTP reply code of 451 and, if supported, the 4.4.3 DSN
+ code.
+
+2.5.7. PermError
+
+ A "PermError" result means that the domain's published records could
+ not be correctly interpreted. This signals an error condition that
+ requires manual intervention to be resolved, as opposed to the
+ TempError result. Be aware that if the domain owner uses macros
+ (Section 8), it is possible that this result is due to the checked
+ identities having an unexpected format.
+
+3. SPF Records
+
+ An SPF record is a DNS Resource Record (RR) that declares which hosts
+ are, and are not, authorized to use a domain name for the "HELO" and
+ "MAIL FROM" identities. Loosely, the record partitions all hosts
+ into permitted and not-permitted sets (though some hosts might fall
+ into neither category).
+
+
+
+Wong & Schlitt Experimental [Page 9]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ The SPF record is a single string of text. An example record is the
+ following:
+
+ v=spf1 +mx a:colo.example.com/28 -all
+
+ This record has a version of "spf1" and three directives: "+mx",
+ "a:colo.example.com/28" (the + is implied), and "-all".
+
+3.1. Publishing
+
+ Domain owners wishing to be SPF compliant must publish SPF records
+ for the hosts that are used in the "MAIL FROM" and "HELO" identities.
+ The SPF records are placed in the DNS tree at the host name it
+ pertains to, not a subdomain under it, such as is done with SRV
+ records. This is the same whether the TXT or SPF RR type (see
+ Section 3.1.1) is used.
+
+ The example above in Section 3 might be published via these lines in
+ a domain zone file:
+
+ example.com. TXT "v=spf1 +mx a:colo.example.com/28 -all"
+ smtp-out.example.com. TXT "v=spf1 a -all"
+
+ When publishing via TXT records, beware of other TXT records
+ published there for other purposes. They may cause problems with
+ size limits (see Section 3.1.4).
+
+3.1.1. DNS Resource Record Types
+
+ This document defines a new DNS RR of type SPF, code 99. The format
+ of this type is identical to the TXT RR [RFC1035]. For either type,
+ the character content of the record is encoded as [US-ASCII].
+
+ It is recognized that the current practice (using a TXT record) is
+ not optimal, but it is necessary because there are a number of DNS
+ server and resolver implementations in common use that cannot handle
+ the new RR type. The two-record-type scheme provides a forward path
+ to the better solution of using an RR type reserved for this purpose.
+
+ An SPF-compliant domain name SHOULD have SPF records of both RR
+ types. A compliant domain name MUST have a record of at least one
+ type. If a domain has records of both types, they MUST have
+ identical content. For example, instead of publishing just one
+ record as in Section 3.1 above, it is better to publish:
+
+ example.com. IN TXT "v=spf1 +mx a:colo.example.com/28 -all"
+ example.com. IN SPF "v=spf1 +mx a:colo.example.com/28 -all"
+
+
+
+
+Wong & Schlitt Experimental [Page 10]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Example RRs in this document are shown with the TXT record type;
+ however, they could be published with the SPF type or with both
+ types.
+
+3.1.2. Multiple DNS Records
+
+ A domain name MUST NOT have multiple records that would cause an
+ authorization check to select more than one record. See Section 4.5
+ for the selection rules.
+
+3.1.3. Multiple Strings in a Single DNS record
+
+ As defined in [RFC1035] sections 3.3.14 and 3.3, a single text DNS
+ record (either TXT or SPF RR types) can be composed of more than one
+ string. If a published record contains multiple strings, then the
+ record MUST be treated as if those strings are concatenated together
+ without adding spaces. For example:
+
+ IN TXT "v=spf1 .... first" "second string..."
+
+ MUST be treated as equivalent to
+
+ IN TXT "v=spf1 .... firstsecond string..."
+
+ SPF or TXT records containing multiple strings are useful in
+ constructing records that would exceed the 255-byte maximum length of
+ a string within a single TXT or SPF RR record.
+
+3.1.4. Record Size
+
+ The published SPF record for a given domain name SHOULD remain small
+ enough that the results of a query for it will fit within 512 octets.
+ This will keep even older DNS implementations from falling over to
+ TCP. Since the answer size is dependent on many things outside the
+ scope of this document, it is only possible to give this guideline:
+ If the combined length of the DNS name and the text of all the
+ records of a given type (TXT or SPF) is under 450 characters, then
+ DNS answers should fit in UDP packets. Note that when computing the
+ sizes for queries of the TXT format, one must take into account any
+ other TXT records published at the domain name. Records that are too
+ long to fit in a single UDP packet MAY be silently ignored by SPF
+ clients.
+
+3.1.5. Wildcard Records
+
+ Use of wildcard records for publishing is not recommended. Care must
+ be taken if wildcard records are used. If a domain publishes
+ wildcard MX records, it may want to publish wildcard declarations,
+
+
+
+Wong & Schlitt Experimental [Page 11]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ subject to the same requirements and problems. In particular, the
+ declaration must be repeated for any host that has any RR records at
+ all, and for subdomains thereof. For example, the example given in
+ [RFC1034], Section 4.3.3, could be extended with the following:
+
+ X.COM. MX 10 A.X.COM
+ X.COM. TXT "v=spf1 a:A.X.COM -all"
+
+ *.X.COM. MX 10 A.X.COM
+ *.X.COM. TXT "v=spf1 a:A.X.COM -all"
+
+ A.X.COM. A 1.2.3.4
+ A.X.COM. MX 10 A.X.COM
+ A.X.COM. TXT "v=spf1 a:A.X.COM -all"
+
+ *.A.X.COM. MX 10 A.X.COM
+ *.A.X.COM. TXT "v=spf1 a:A.X.COM -all"
+
+ Notice that SPF records must be repeated twice for every name within
+ the domain: once for the name, and once with a wildcard to cover the
+ tree under the name.
+
+ Use of wildcards is discouraged in general as they cause every name
+ under the domain to exist and queries against arbitrary names will
+ never return RCODE 3 (Name Error).
+
+4. The check_host() Function
+
+ The check_host() function fetches SPF records, parses them, and
+ interprets them to determine whether a particular host is or is not
+ permitted to send mail with a given identity. Mail receivers that
+ perform this check MUST correctly evaluate the check_host() function
+ as described here.
+
+ Implementations MAY use a different algorithm than the canonical
+ algorithm defined here, so long as the results are the same in all
+ cases.
+
+4.1. Arguments
+
+ The check_host() function takes these arguments:
+
+ <ip> - the IP address of the SMTP client that is emitting the
+ mail, either IPv4 or IPv6.
+
+ <domain> - the domain that provides the sought-after authorization
+ information; initially, the domain portion of the "MAIL
+ FROM" or "HELO" identity.
+
+
+
+Wong & Schlitt Experimental [Page 12]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ <sender> - the "MAIL FROM" or "HELO" identity.
+
+ The domain portion of <sender> will usually be the same as the
+ <domain> argument when check_host() is initially evaluated. However,
+ this will generally not be true for recursive evaluations (see
+ Section 5.2 below).
+
+ Actual implementations of the check_host() function may need
+ additional arguments.
+
+4.2. Results
+
+ The function check_host() can return one of several results described
+ in Section 2.5. Based on the result, the action to be taken is
+ determined by the local policies of the receiver.
+
+4.3. Initial Processing
+
+ If the <domain> is malformed (label longer than 63 characters, zero-
+ length label not at the end, etc.) or is not a fully qualified domain
+ name, or if the DNS lookup returns "domain does not exist" (RCODE 3),
+ check_host() immediately returns the result "None".
+
+ If the <sender> has no localpart, substitute the string "postmaster"
+ for the localpart.
+
+4.4. Record Lookup
+
+ In accordance with how the records are published (see Section 3.1
+ above), a DNS query needs to be made for the <domain> name, querying
+ for either RR type TXT, SPF, or both. If both SPF and TXT RRs are
+ looked up, the queries MAY be done in parallel.
+
+ If all DNS lookups that are made return a server failure (RCODE 2),
+ or other error (RCODE other than 0 or 3), or time out, then
+ check_host() exits immediately with the result "TempError".
+
+4.5. Selecting Records
+
+ Records begin with a version section:
+
+ record = version terms *SP
+ version = "v=spf1"
+
+ Starting with the set of records that were returned by the lookup,
+ record selection proceeds in two steps:
+
+
+
+
+
+Wong & Schlitt Experimental [Page 13]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ 1. Records that do not begin with a version section of exactly
+ "v=spf1" are discarded. Note that the version section is
+ terminated either by an SP character or the end of the record. A
+ record with a version section of "v=spf10" does not match and must
+ be discarded.
+
+ 2. If any records of type SPF are in the set, then all records of
+ type TXT are discarded.
+
+ After the above steps, there should be exactly one record remaining
+ and evaluation can proceed. If there are two or more records
+ remaining, then check_host() exits immediately with the result of
+ "PermError".
+
+ If no matching records are returned, an SPF client MUST assume that
+ the domain makes no SPF declarations. SPF processing MUST stop and
+ return "None".
+
+4.6. Record Evaluation
+
+ After one SPF record has been selected, the check_host() function
+ parses and interprets it to find a result for the current test. If
+ there are any syntax errors, check_host() returns immediately with
+ the result "PermError".
+
+ Implementations MAY choose to parse the entire record first and
+ return "PermError" if the record is not syntactically well formed.
+ However, in all cases, any syntax errors anywhere in the record MUST
+ be detected.
+
+4.6.1. Term Evaluation
+
+ There are two types of terms: mechanisms and modifiers. A record
+ contains an ordered list of these as specified in the following
+ Augmented Backus-Naur Form (ABNF).
+
+ terms = *( 1*SP ( directive / modifier ) )
+
+ directive = [ qualifier ] mechanism
+ qualifier = "+" / "-" / "?" / "~"
+ mechanism = ( all / include
+ / A / MX / PTR / IP4 / IP6 / exists )
+ modifier = redirect / explanation / unknown-modifier
+ unknown-modifier = name "=" macro-string
+
+ name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
+
+ Most mechanisms allow a ":" or "/" character after the name.
+
+
+
+Wong & Schlitt Experimental [Page 14]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Modifiers always contain an equals ('=') character immediately after
+ the name, and before any ":" or "/" characters that may be part of
+ the macro-string.
+
+ Terms that do not contain any of "=", ":", or "/" are mechanisms, as
+ defined in Section 5.
+
+ As per the definition of the ABNF notation in [RFC4234], mechanism
+ and modifier names are case-insensitive.
+
+4.6.2. Mechanisms
+
+ Each mechanism is considered in turn from left to right. If there
+ are no more mechanisms, the result is specified in Section 4.7.
+
+ When a mechanism is evaluated, one of three things can happen: it can
+ match, not match, or throw an exception.
+
+ If it matches, processing ends and the qualifier value is returned as
+ the result of that record. If it does not match, processing
+ continues with the next mechanism. If it throws an exception,
+ mechanism processing ends and the exception value is returned.
+
+ The possible qualifiers, and the results they return are as follows:
+
+ "+" Pass
+ "-" Fail
+ "~" SoftFail
+ "?" Neutral
+
+ The qualifier is optional and defaults to "+".
+
+ When a mechanism matches and the qualifier is "-", then a "Fail"
+ result is returned and the explanation string is computed as
+ described in Section 6.2.
+
+ The specific mechanisms are described in Section 5.
+
+4.6.3. Modifiers
+
+ Modifiers are not mechanisms: they do not return match or not-match.
+ Instead they provide additional information. Although modifiers do
+ not directly affect the evaluation of the record, the "redirect"
+ modifier has an effect after all the mechanisms have been evaluated.
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 15]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+4.7. Default Result
+
+ If none of the mechanisms match and there is no "redirect" modifier,
+ then the check_host() returns a result of "Neutral", just as if
+ "?all" were specified as the last directive. If there is a
+ "redirect" modifier, check_host() proceeds as defined in Section 6.1.
+
+ Note that records SHOULD always use either a "redirect" modifier or
+ an "all" mechanism to explicitly terminate processing.
+
+ For example:
+
+ v=spf1 +mx -all
+ or
+ v=spf1 +mx redirect=_spf.example.com
+
+4.8. Domain Specification
+
+ Several of these mechanisms and modifiers have a <domain-spec>
+ section. The <domain-spec> string is macro expanded (see Section 8).
+ The resulting string is the common presentation form of a fully-
+ qualified DNS name: a series of labels separated by periods. This
+ domain is called the <target-name> in the rest of this document.
+
+ Note: The result of the macro expansion is not subject to any further
+ escaping. Hence, this facility cannot produce all characters that
+ are legal in a DNS label (e.g., the control characters). However,
+ this facility is powerful enough to express legal host names and
+ common utility labels (such as "_spf") that are used in DNS.
+
+ For several mechanisms, the <domain-spec> is optional. If it is not
+ provided, the <domain> is used as the <target-name>.
+
+5. Mechanism Definitions
+
+ This section defines two types of mechanisms.
+
+ Basic mechanisms contribute to the language framework. They do not
+ specify a particular type of authorization scheme.
+
+ all
+ include
+
+ Designated sender mechanisms are used to designate a set of <ip>
+ addresses as being permitted or not permitted to use the <domain> for
+ sending mail.
+
+
+
+
+
+Wong & Schlitt Experimental [Page 16]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ a
+ mx
+ ptr
+ ip4
+ ip6
+ exists
+
+ The following conventions apply to all mechanisms that perform a
+ comparison between <ip> and an IP address at any point:
+
+ If no CIDR-length is given in the directive, then <ip> and the IP
+ address are compared for equality. (Here, CIDR is Classless Inter-
+ Domain Routing.)
+
+ If a CIDR-length is specified, then only the specified number of
+ high-order bits of <ip> and the IP address are compared for equality.
+
+ When any mechanism fetches host addresses to compare with <ip>, when
+ <ip> is an IPv4 address, A records are fetched, when <ip> is an IPv6
+ address, AAAA records are fetched. Even if the SMTP connection is
+ via IPv6, an IPv4-mapped IPv6 IP address (see [RFC3513], Section
+ 2.5.5) MUST still be considered an IPv4 address.
+
+ Several mechanisms rely on information fetched from DNS. For these
+ DNS queries, except where noted, if the DNS server returns an error
+ (RCODE other than 0 or 3) or the query times out, the mechanism
+ throws the exception "TempError". If the server returns "domain does
+ not exist" (RCODE 3), then evaluation of the mechanism continues as
+ if the server returned no error (RCODE 0) and zero answer records.
+
+5.1. "all"
+
+ all = "all"
+
+ The "all" mechanism is a test that always matches. It is used as the
+ rightmost mechanism in a record to provide an explicit default.
+
+ For example:
+
+ v=spf1 a mx -all
+
+ Mechanisms after "all" will never be tested. Any "redirect" modifier
+ (Section 6.1) has no effect when there is an "all" mechanism.
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 17]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+5.2. "include"
+
+ include = "include" ":" domain-spec
+
+ The "include" mechanism triggers a recursive evaluation of
+ check_host(). The domain-spec is expanded as per Section 8. Then
+ check_host() is evaluated with the resulting string as the <domain>.
+ The <ip> and <sender> arguments remain the same as in the current
+ evaluation of check_host().
+
+ In hindsight, the name "include" was poorly chosen. Only the
+ evaluated result of the referenced SPF record is used, rather than
+ acting as if the referenced SPF record was literally included in the
+ first. For example, evaluating a "-all" directive in the referenced
+ record does not terminate the overall processing and does not
+ necessarily result in an overall "Fail". (Better names for this
+ mechanism would have been "if-pass", "on-pass", etc.)
+
+ The "include" mechanism makes it possible for one domain to designate
+ multiple administratively-independent domains. For example, a vanity
+ domain "example.net" might send mail using the servers of
+ administratively-independent domains example.com and example.org.
+
+ Example.net could say
+
+ IN TXT "v=spf1 include:example.com include:example.org -all"
+
+ This would direct check_host() to, in effect, check the records of
+ example.com and example.org for a "Pass" result. Only if the host
+ were not permitted for either of those domains would the result be
+ "Fail".
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 18]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Whether this mechanism matches, does not match, or throws an
+ exception depends on the result of the recursive evaluation of
+ check_host():
+
+ +---------------------------------+---------------------------------+
+ | A recursive check_host() result | Causes the "include" mechanism |
+ | of: | to: |
+ +---------------------------------+---------------------------------+
+ | Pass | match |
+ | | |
+ | Fail | not match |
+ | | |
+ | SoftFail | not match |
+ | | |
+ | Neutral | not match |
+ | | |
+ | TempError | throw TempError |
+ | | |
+ | PermError | throw PermError |
+ | | |
+ | None | throw PermError |
+ +---------------------------------+---------------------------------+
+
+ The "include" mechanism is intended for crossing administrative
+ boundaries. Although it is possible to use includes to consolidate
+ multiple domains that share the same set of designated hosts, domains
+ are encouraged to use redirects where possible, and to minimize the
+ number of includes within a single administrative domain. For
+ example, if example.com and example.org were managed by the same
+ entity, and if the permitted set of hosts for both domains was
+ "mx:example.com", it would be possible for example.org to specify
+ "include:example.com", but it would be preferable to specify
+ "redirect=example.com" or even "mx:example.com".
+
+5.3. "a"
+
+ This mechanism matches if <ip> is one of the <target-name>'s IP
+ addresses.
+
+ A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
+
+ An address lookup is done on the <target-name>. The <ip> is compared
+ to the returned address(es). If any address matches, the mechanism
+ matches.
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 19]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+5.4. "mx"
+
+ This mechanism matches if <ip> is one of the MX hosts for a domain
+ name.
+
+ MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
+
+ check_host() first performs an MX lookup on the <target-name>. Then
+ it performs an address lookup on each MX name returned. The <ip> is
+ compared to each returned IP address. To prevent Denial of Service
+ (DoS) attacks, more than 10 MX names MUST NOT be looked up during the
+ evaluation of an "mx" mechanism (see Section 10). If any address
+ matches, the mechanism matches.
+
+ Note regarding implicit MXs: If the <target-name> has no MX records,
+ check_host() MUST NOT pretend the target is its single MX, and MUST
+ NOT default to an A lookup on the <target-name> directly. This
+ behavior breaks with the legacy "implicit MX" rule. See [RFC2821],
+ Section 5. If such behavior is desired, the publisher should specify
+ an "a" directive.
+
+5.5. "ptr"
+
+ This mechanism tests whether the DNS reverse-mapping for <ip> exists
+ and correctly points to a domain name within a particular domain.
+
+ PTR = "ptr" [ ":" domain-spec ]
+
+ First, the <ip>'s name is looked up using this procedure: perform a
+ DNS reverse-mapping for <ip>, looking up the corresponding PTR record
+ in "in-addr.arpa." if the address is an IPv4 one and in "ip6.arpa."
+ if it is an IPv6 address. For each record returned, validate the
+ domain name by looking up its IP address. To prevent DoS attacks,
+ more than 10 PTR names MUST NOT be looked up during the evaluation of
+ a "ptr" mechanism (see Section 10). If <ip> is among the returned IP
+ addresses, then that domain name is validated. In pseudocode:
+
+ sending-domain_names := ptr_lookup(sending-host_IP); if more than 10
+ sending-domain_names are found, use at most 10. for each name in
+ (sending-domain_names) {
+ IP_addresses := a_lookup(name);
+ if the sending-domain_IP is one of the IP_addresses {
+ validated-sending-domain_names += name;
+ } }
+
+ Check all validated domain names to see if they end in the
+ <target-name> domain. If any do, this mechanism matches. If no
+ validated domain name can be found, or if none of the validated
+
+
+
+Wong & Schlitt Experimental [Page 20]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ domain names end in the <target-name>, this mechanism fails to match.
+ If a DNS error occurs while doing the PTR RR lookup, then this
+ mechanism fails to match. If a DNS error occurs while doing an A RR
+ lookup, then that domain name is skipped and the search continues.
+
+ Pseudocode:
+
+ for each name in (validated-sending-domain_names) {
+ if name ends in <domain-spec>, return match.
+ if name is <domain-spec>, return match.
+ }
+ return no-match.
+
+ This mechanism matches if the <target-name> is either an ancestor of
+ a validated domain name or if the <target-name> and a validated
+ domain name are the same. For example: "mail.example.com" is within
+ the domain "example.com", but "mail.bad-example.com" is not.
+
+ Note: Use of this mechanism is discouraged because it is slow, it is
+ not as reliable as other mechanisms in cases of DNS errors, and it
+ places a large burden on the arpa name servers. If used, proper PTR
+ records must be in place for the domain's hosts and the "ptr"
+ mechanism should be one of the last mechanisms checked.
+
+5.6. "ip4" and "ip6"
+
+ These mechanisms test whether <ip> is contained within a given IP
+ network.
+
+ IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
+ IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ]
+
+ ip4-cidr-length = "/" 1*DIGIT
+ ip6-cidr-length = "/" 1*DIGIT
+ dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
+
+ ip4-network = qnum "." qnum "." qnum "." qnum
+ qnum = DIGIT ; 0-9
+ / %x31-39 DIGIT ; 10-99
+ / "1" 2DIGIT ; 100-199
+ / "2" %x30-34 DIGIT ; 200-249
+ / "25" %x30-35 ; 250-255
+ ; as per conventional dotted quad notation. e.g., 192.0.2.0
+ ip6-network = <as per [RFC 3513], section 2.2>
+ ; e.g., 2001:DB8::CD30
+
+ The <ip> is compared to the given network. If CIDR-length high-order
+ bits match, the mechanism matches.
+
+
+
+Wong & Schlitt Experimental [Page 21]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ If ip4-cidr-length is omitted, it is taken to be "/32". If
+ ip6-cidr-length is omitted, it is taken to be "/128". It is not
+ permitted to omit parts of the IP address instead of using CIDR
+ notations. That is, use 192.0.2.0/24 instead of 192.0.2.
+
+5.7. "exists"
+
+ This mechanism is used to construct an arbitrary domain name that is
+ used for a DNS A record query. It allows for complicated schemes
+ involving arbitrary parts of the mail envelope to determine what is
+ permitted.
+
+ exists = "exists" ":" domain-spec
+
+ The domain-spec is expanded as per Section 8. The resulting domain
+ name is used for a DNS A RR lookup. If any A record is returned,
+ this mechanism matches. The lookup type is A even when the
+ connection type is IPv6.
+
+ Domains can use this mechanism to specify arbitrarily complex
+ queries. For example, suppose example.com publishes the record:
+
+ v=spf1 exists:%{ir}.%{l1r+-}._spf.%{d} -all
+
+ The <target-name> might expand to
+ "1.2.0.192.someuser._spf.example.com". This makes fine-grained
+ decisions possible at the level of the user and client IP address.
+
+ This mechanism enables queries that mimic the style of tests that
+ existing anti-spam DNS blacklists (DNSBL) use.
+
+6. Modifier Definitions
+
+ Modifiers are name/value pairs that provide additional information.
+ Modifiers always have an "=" separating the name and the value.
+
+ The modifiers defined in this document ("redirect" and "exp") MAY
+ appear anywhere in the record, but SHOULD appear at the end, after
+ all mechanisms. Ordering of these two modifiers does not matter.
+ These two modifiers MUST NOT appear in a record more than once each.
+ If they do, then check_host() exits with a result of "PermError".
+
+ Unrecognized modifiers MUST be ignored no matter where in a record,
+ or how often. This allows implementations of this document to
+ gracefully handle records with modifiers that are defined in other
+ specifications.
+
+
+
+
+
+Wong & Schlitt Experimental [Page 22]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+6.1. redirect: Redirected Query
+
+ If all mechanisms fail to match, and a "redirect" modifier is
+ present, then processing proceeds as follows:
+
+ redirect = "redirect" "=" domain-spec
+
+ The domain-spec portion of the redirect section is expanded as per
+ the macro rules in Section 8. Then check_host() is evaluated with
+ the resulting string as the <domain>. The <ip> and <sender>
+ arguments remain the same as current evaluation of check_host().
+
+ The result of this new evaluation of check_host() is then considered
+ the result of the current evaluation with the exception that if no
+ SPF record is found, or if the target-name is malformed, the result
+ is a "PermError" rather than "None".
+
+ Note that the newly-queried domain may itself specify redirect
+ processing.
+
+ This facility is intended for use by organizations that wish to apply
+ the same record to multiple domains. For example:
+
+ la.example.com. TXT "v=spf1 redirect=_spf.example.com"
+ ny.example.com. TXT "v=spf1 redirect=_spf.example.com"
+ sf.example.com. TXT "v=spf1 redirect=_spf.example.com"
+ _spf.example.com. TXT "v=spf1 mx:example.com -all"
+
+ In this example, mail from any of the three domains is described by
+ the same record. This can be an administrative advantage.
+
+ Note: In general, the domain "A" cannot reliably use a redirect to
+ another domain "B" not under the same administrative control. Since
+ the <sender> stays the same, there is no guarantee that the record at
+ domain "B" will correctly work for mailboxes in domain "A",
+ especially if domain "B" uses mechanisms involving localparts. An
+ "include" directive may be more appropriate.
+
+ For clarity, it is RECOMMENDED that any "redirect" modifier appear as
+ the very last term in a record.
+
+6.2. exp: Explanation
+
+ explanation = "exp" "=" domain-spec
+
+ If check_host() results in a "Fail" due to a mechanism match (such as
+ "-all"), and the "exp" modifier is present, then the explanation
+ string returned is computed as described below. If no "exp" modifier
+
+
+
+Wong & Schlitt Experimental [Page 23]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ is present, then either a default explanation string or an empty
+ explanation string may be returned.
+
+ The <domain-spec> is macro expanded (see Section 8) and becomes the
+ <target-name>. The DNS TXT record for the <target-name> is fetched.
+
+ If <domain-spec> is empty, or there are any DNS processing errors
+ (any RCODE other than 0), or if no records are returned, or if more
+ than one record is returned, or if there are syntax errors in the
+ explanation string, then proceed as if no exp modifier was given.
+
+ The fetched TXT record's strings are concatenated with no spaces, and
+ then treated as an <explain-string>, which is macro-expanded. This
+ final result is the explanation string. Implementations MAY limit
+ the length of the resulting explanation string to allow for other
+ protocol constraints and/or reasonable processing limits. Since the
+ explanation string is intended for an SMTP response and [RFC2821]
+ Section 2.4 says that responses are in [US-ASCII], the explanation
+ string is also limited to US-ASCII.
+
+ Software evaluating check_host() can use this string to communicate
+ information from the publishing domain in the form of a short message
+ or URL. Software SHOULD make it clear that the explanation string
+ comes from a third party. For example, it can prepend the macro
+ string "%{o} explains: " to the explanation, such as shown in Section
+ 2.5.4.
+
+ Suppose example.com has this record:
+
+ v=spf1 mx -all exp=explain._spf.%{d}
+
+ Here are some examples of possible explanation TXT records at
+ explain._spf.example.com:
+
+ "Mail from example.com should only be sent by its own servers."
+ -- a simple, constant message
+
+ "%{i} is not one of %{d}'s designated mail servers."
+ -- a message with a little more information, including the IP
+ address that failed the check
+
+ "See http://%{d}/why.html?s=%{S}&i=%{I}"
+ -- a complicated example that constructs a URL with the
+ arguments to check_host() so that a web page can be
+ generated with detailed, custom instructions
+
+ Note: During recursion into an "include" mechanism, an exp= modifier
+ from the <target-name> MUST NOT be used. In contrast, when executing
+
+
+
+Wong & Schlitt Experimental [Page 24]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ a "redirect" modifier, an exp= modifier from the original domain MUST
+ NOT be used.
+
+7. The Received-SPF Header Field
+
+ It is RECOMMENDED that SMTP receivers record the result of SPF
+ processing in the message header. If an SMTP receiver chooses to do
+ so, it SHOULD use the "Received-SPF" header field defined here for
+ each identity that was checked. This information is intended for the
+ recipient. (Information intended for the sender is described in
+ Section 6.2, Explanation.)
+
+ The Received-SPF header field is a trace field (see [RFC2822] Section
+ 3.6.7) and SHOULD be prepended to the existing header, above the
+ Received: field that is generated by the SMTP receiver. It MUST
+ appear above all other Received-SPF fields in the message. The
+ header field has the following format:
+
+ header-field = "Received-SPF:" [CFWS] result FWS [comment FWS]
+ [ key-value-list ] CRLF
+
+ result = "Pass" / "Fail" / "SoftFail" / "Neutral" /
+ "None" / "TempError" / "PermError"
+
+ key-value-list = key-value-pair *( ";" [CFWS] key-value-pair )
+ [";"]
+
+ key-value-pair = key [CFWS] "=" ( dot-atom / quoted-string )
+
+ key = "client-ip" / "envelope-from" / "helo" /
+ "problem" / "receiver" / "identity" /
+ mechanism / "x-" name / name
+
+ identity = "mailfrom" ; for the "MAIL FROM" identity
+ / "helo" ; for the "HELO" identity
+ / name ; other identities
+
+ dot-atom = <unquoted word as per [RFC2822]>
+ quoted-string = <quoted string as per [RFC2822]>
+ comment = <comment string as per [RFC2822]>
+ CFWS = <comment or folding white space as per [RFC2822]>
+ FWS = <folding white space as per [RFC2822]>
+ CRLF = <standard end-of-line token as per [RFC2822]>
+
+ The header field SHOULD include a "(...)" style <comment> after the
+ result, conveying supporting information for the result, such as
+ <ip>, <sender>, and <domain>.
+
+
+
+
+Wong & Schlitt Experimental [Page 25]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ The following key-value pairs are designed for later machine parsing.
+ SPF clients SHOULD give enough information so that the SPF results
+ can be verified. That is, at least "client-ip", "helo", and, if the
+ "MAIL FROM" identity was checked, "envelope-from".
+
+ client-ip the IP address of the SMTP client
+
+ envelope-from the envelope sender mailbox
+
+ helo the host name given in the HELO or EHLO command
+
+ mechanism the mechanism that matched (if no mechanisms matched,
+ substitute the word "default")
+
+ problem if an error was returned, details about the error
+
+ receiver the host name of the SPF client
+
+ identity the identity that was checked; see the <identity> ABNF
+ rule
+
+ Other keys may be defined by SPF clients. Until a new key name
+ becomes widely accepted, new key names should start with "x-".
+
+ SPF clients MUST make sure that the Received-SPF header field does
+ not contain invalid characters, is not excessively long, and does not
+ contain malicious data that has been provided by the sender.
+
+ Examples of various header styles that could be generated are the
+ following:
+
+ Received-SPF: Pass (mybox.example.org: domain of
+ myname@example.com designates 192.0.2.1 as permitted sender)
+ receiver=mybox.example.org; client-ip=192.0.2.1;
+ envelope-from=<myname@example.com>; helo=foo.example.com;
+
+ Received-SPF: Fail (mybox.example.org: domain of
+ myname@example.com does not designate
+ 192.0.2.1 as permitted sender)
+ identity=mailfrom; client-ip=192.0.2.1;
+ envelope-from=<myname@example.com>;
+
+
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 26]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+8. Macros
+
+8.1. Macro Definitions
+
+ Many mechanisms and modifiers perform macro expansion on part of the
+ term.
+
+ domain-spec = macro-string domain-end
+ domain-end = ( "." toplabel [ "." ] ) / macro-expand
+
+ toplabel = ( *alphanum ALPHA *alphanum ) /
+ ( 1*alphanum "-" *( alphanum / "-" ) alphanum )
+ ; LDH rule plus additional TLD restrictions
+ ; (see [RFC3696], Section 2)
+ alphanum = ALPHA / DIGIT
+
+ explain-string = *( macro-string / SP )
+
+ macro-string = *( macro-expand / macro-literal )
+ macro-expand = ( "%{" macro-letter transformers *delimiter "}" )
+ / "%%" / "%_" / "%-"
+ macro-literal = %x21-24 / %x26-7E
+ ; visible characters except "%"
+ macro-letter = "s" / "l" / "o" / "d" / "i" / "p" / "h" /
+ "c" / "r" / "t"
+ transformers = *DIGIT [ "r" ]
+ delimiter = "." / "-" / "+" / "," / "/" / "_" / "="
+
+ A literal "%" is expressed by "%%".
+
+ "%_" expands to a single " " space.
+ "%-" expands to a URL-encoded space, viz., "%20".
+
+ The following macro letters are expanded in term arguments:
+
+ s = <sender>
+ l = local-part of <sender>
+ o = domain of <sender>
+ d = <domain>
+ i = <ip>
+ p = the validated domain name of <ip>
+ v = the string "in-addr" if <ip> is ipv4, or "ip6" if <ip> is ipv6
+ h = HELO/EHLO domain
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 27]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ The following macro letters are allowed only in "exp" text:
+
+ c = SMTP client IP (easily readable format)
+ r = domain name of host performing the check
+ t = current timestamp
+
+ A '%' character not followed by a '{', '%', '-', or '_' character is
+ a syntax error. So
+
+ -exists:%(ir).sbl.spamhaus.example.org
+
+ is incorrect and will cause check_host() to return a "PermError".
+ Instead, say
+
+ -exists:%{ir}.sbl.spamhaus.example.org
+
+ Optional transformers are the following:
+
+ *DIGIT = zero or more digits
+ 'r' = reverse value, splitting on dots by default
+
+ If transformers or delimiters are provided, the replacement value for
+ a macro letter is split into parts. After performing any reversal
+ operation and/or removal of left-hand parts, the parts are rejoined
+ using "." and not the original splitting characters.
+
+ By default, strings are split on "." (dots). Note that no special
+ treatment is given to leading, trailing, or consecutive delimiters,
+ and so the list of parts may contain empty strings. Older
+ implementations of SPF prohibit trailing dots in domain names, so
+ trailing dots should not be published by domain owners, although they
+ must be accepted by implementations conforming to this document.
+ Macros may specify delimiter characters that are used instead of ".".
+
+ The 'r' transformer indicates a reversal operation: if the client IP
+ address were 192.0.2.1, the macro %{i} would expand to "192.0.2.1"
+ and the macro %{ir} would expand to "1.2.0.192".
+
+ The DIGIT transformer indicates the number of right-hand parts to
+ use, after optional reversal. If a DIGIT is specified, the value
+ MUST be nonzero. If no DIGITs are specified, or if the value
+ specifies more parts than are available, all the available parts are
+ used. If the DIGIT was 5, and only 3 parts were available, the macro
+ interpreter would pretend the DIGIT was 3. Implementations MUST
+ support at least a value of 128, as that is the maximum number of
+ labels in a domain name.
+
+
+
+
+
+Wong & Schlitt Experimental [Page 28]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ The "s" macro expands to the <sender> argument. It is an E-Mail
+ address with a localpart, an "@" character, and a domain. The "l"
+ macro expands to just the localpart. The "o" macro expands to just
+ the domain part. Note that these values remain the same during
+ recursive and chained evaluations due to "include" and/or "redirect".
+ Note also that if the original <sender> had no localpart, the
+ localpart was set to "postmaster" in initial processing (see Section
+ 4.3).
+
+ For IPv4 addresses, both the "i" and "c" macros expand to the
+ standard dotted-quad format.
+
+ For IPv6 addresses, the "i" macro expands to a dot-format address; it
+ is intended for use in %{ir}. The "c" macro may expand to any of the
+ hexadecimal colon-format addresses specified in [RFC3513], Section
+ 2.2. It is intended for humans to read.
+
+ The "p" macro expands to the validated domain name of <ip>. The
+ procedure for finding the validated domain name is defined in Section
+ 5.5. If the <domain> is present in the list of validated domains, it
+ SHOULD be used. Otherwise, if a subdomain of the <domain> is
+ present, it SHOULD be used. Otherwise, any name from the list may be
+ used. If there are no validated domain names or if a DNS error
+ occurs, the string "unknown" is used.
+
+ The "r" macro expands to the name of the receiving MTA. This SHOULD
+ be a fully qualified domain name, but if one does not exist (as when
+ the checking is done by a MUA) or if policy restrictions dictate
+ otherwise, the word "unknown" SHOULD be substituted. The domain name
+ may be different from the name found in the MX record that the client
+ MTA used to locate the receiving MTA.
+
+ The "t" macro expands to the decimal representation of the
+ approximate number of seconds since the Epoch (Midnight, January 1,
+ 1970, UTC). This is the same value as is returned by the POSIX
+ time() function in most standards-compliant libraries.
+
+ When the result of macro expansion is used in a domain name query, if
+ the expanded domain name exceeds 253 characters (the maximum length
+ of a domain name), the left side is truncated to fit, by removing
+ successive domain labels until the total length does not exceed 253
+ characters.
+
+ Uppercased macros expand exactly as their lowercased equivalents, and
+ are then URL escaped. URL escaping must be performed for characters
+ not in the "uric" set, which is defined in [RFC3986].
+
+
+
+
+
+Wong & Schlitt Experimental [Page 29]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Note: Care must be taken so that macro expansion for legitimate
+ E-Mail does not exceed the 63-character limit on DNS labels. The
+ localpart of E-Mail addresses, in particular, can have more than 63
+ characters between dots.
+
+ Note: Domains should avoid using the "s", "l", "o", or "h" macros in
+ conjunction with any mechanism directive. Although these macros are
+ powerful and allow per-user records to be published, they severely
+ limit the ability of implementations to cache results of check_host()
+ and they reduce the effectiveness of DNS caches.
+
+ Implementations should be aware that if no directive processed during
+ the evaluation of check_host() contains an "s", "l", "o", or "h"
+ macro, then the results of the evaluation can be cached on the basis
+ of <domain> and <ip> alone for as long as the shortest Time To Live
+ (TTL) of all the DNS records involved.
+
+8.2. Expansion Examples
+
+ The <sender> is strong-bad@email.example.com.
+ The IPv4 SMTP client IP is 192.0.2.3.
+ The IPv6 SMTP client IP is 2001:DB8::CB01.
+ The PTR domain name of the client IP is mx.example.org.
+
+ macro expansion
+ ------- ----------------------------
+ %{s} strong-bad@email.example.com
+ %{o} email.example.com
+ %{d} email.example.com
+ %{d4} email.example.com
+ %{d3} email.example.com
+ %{d2} example.com
+ %{d1} com
+ %{dr} com.example.email
+ %{d2r} example.email
+ %{l} strong-bad
+ %{l-} strong.bad
+ %{lr} strong-bad
+ %{lr-} bad.strong
+ %{l1r-} strong
+
+
+
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 30]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ macro-string expansion
+ --------------------------------------------------------------------
+ %{ir}.%{v}._spf.%{d2} 3.2.0.192.in-addr._spf.example.com
+ %{lr-}.lp._spf.%{d2} bad.strong.lp._spf.example.com
+
+ %{lr-}.lp.%{ir}.%{v}._spf.%{d2}
+ bad.strong.lp.3.2.0.192.in-addr._spf.example.com
+
+ %{ir}.%{v}.%{l1r-}.lp._spf.%{d2}
+ 3.2.0.192.in-addr.strong.lp._spf.example.com
+
+ %{d2}.trusted-domains.example.net
+ example.com.trusted-domains.example.net
+
+ IPv6:
+ %{ir}.%{v}._spf.%{d2} 1.0.B.C.0.0.0.0.
+ 0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.8.B.D.0.1.0.0.2.ip6._spf.example.com
+
+9. Implications
+
+ This section outlines the major implications that adoption of this
+ document will have on various entities involved in Internet E-Mail.
+ It is intended to make clear to the reader where this document
+ knowingly affects the operation of such entities. This section is
+ not a "how-to" manual, or a "best practices" document, and it is not
+ a comprehensive list of what such entities should do in light of this
+ document.
+
+ This section is non-normative.
+
+9.1. Sending Domains
+
+ Domains that wish to be compliant with this specification will need
+ to determine the list of hosts that they allow to use their domain
+ name in the "HELO" and "MAIL FROM" identities. It is recognized that
+ forming such a list is not just a simple technical exercise, but
+ involves policy decisions with both technical and administrative
+ considerations.
+
+ It can be helpful to publish records that include a "tracking
+ exists:" mechanism. By looking at the name server logs, a rough list
+ may then be generated. For example:
+
+ v=spf1 exists:_h.%{h}._l.%{l}._o.%{o}._i.%{i}._spf.%{d} ?all
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 31]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+9.2. Mailing Lists
+
+ Mailing lists must be aware of how they re-inject mail that is sent
+ to the list. Mailing lists MUST comply with the requirements in
+ [RFC2821], Section 3.10, and [RFC1123], Section 5.3.6, that say that
+ the reverse-path MUST be changed to be the mailbox of a person or
+ other entity who administers the list. Whereas the reasons for
+ changing the reverse-path are many and long-standing, SPF adds
+ enforcement to this requirement.
+
+ In practice, almost all mailing list software in use already complies
+ with this requirement. Mailing lists that do not comply may or may
+ not encounter problems depending on how access to the list is
+ restricted. Such lists that are entirely internal to a domain (only
+ people in the domain can send to or receive from the list) are not
+ affected.
+
+9.3. Forwarding Services and Aliases
+
+ Forwarding services take mail that is received at a mailbox and
+ direct it to some external mailbox. At the time of this writing, the
+ near-universal practice of such services is to use the original "MAIL
+ FROM" of a message when re-injecting it for delivery to the external
+ mailbox. [RFC1123] and [RFC2821] describe this action as an "alias"
+ rather than a "mail list". This means that the external mailbox's
+ MTA sees all such mail in a connection from a host of the forwarding
+ service, and so the "MAIL FROM" identity will not, in general, pass
+ authorization.
+
+ There are three places that techniques can be used to ameliorate this
+ problem.
+
+ 1. The beginning, when E-Mail is first sent.
+
+ 1. "Neutral" results could be given for IP addresses that may be
+ forwarders, instead of "Fail" results. For example:
+
+ "v=spf1 mx -exists:%{ir}.sbl.spamhaus.example.org ?all"
+
+ This would cause a lookup on an anti-spam DNS blacklist
+ (DNSBL) and cause a result of "Fail" only for E-Mail coming
+ from listed sources. All other E-Mail, including E-Mail sent
+ through forwarders, would receive a "Neutral" result. By
+ checking the DNSBL after the known good sources, problems with
+ incorrect listing on the DNSBL are greatly reduced.
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 32]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ 2. The "MAIL FROM" identity could have additional information in
+ the localpart that cryptographically identifies the mail as
+ coming from an authorized source. In this case, such an SPF
+ record could be used:
+
+ "v=spf1 mx exists:%{l}._spf_verify.%{d} -all"
+
+ Then, a specialized DNS server can be set up to serve the
+ _spf_verify subdomain that validates the localpart. Although
+ this requires an extra DNS lookup, this happens only when the
+ E-Mail would otherwise be rejected as not coming from a known
+ good source.
+
+ Note that due to the 63-character limit for domain labels,
+ this approach only works reliably if the localpart signature
+ scheme is guaranteed either to only produce localparts with a
+ maximum of 63 characters or to gracefully handle truncated
+ localparts.
+
+ 3. Similarly, a specialized DNS server could be set up that will
+ rate-limit the E-Mail coming from unexpected IP addresses.
+
+ "v=spf1 mx exists:%{ir}._spf_rate.%{d} -all"
+
+ 4. SPF allows the creation of per-user policies for special
+ cases. For example, the following SPF record and appropriate
+ wildcard DNS records can be used:
+
+ "v=spf1 mx redirect=%{l1r+}._at_.%{o}._spf.%{d}"
+
+ 2. The middle, when E-Mail is forwarded.
+
+ 1. Forwarding services can solve the problem by rewriting the
+ "MAIL FROM" to be in their own domain. This means that mail
+ bounced from the external mailbox will have to be re-bounced
+ by the forwarding service. Various schemes to do this exist
+ though they vary widely in complexity and resource
+ requirements on the part of the forwarding service.
+
+ 2. Several popular MTAs can be forced from "alias" semantics to
+ "mailing list" semantics by configuring an additional alias
+ with "owner-" prepended to the original alias name (e.g., an
+ alias of "friends: george@example.com, fred@example.org" would
+ need another alias of the form "owner-friends: localowner").
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 33]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ 3. The end, when E-Mail is received.
+
+ 1. If the owner of the external mailbox wishes to trust the
+ forwarding service, he can direct the external mailbox's MTA
+ to skip SPF tests when the client host belongs to the
+ forwarding service.
+
+ 2. Tests against other identities, such as the "HELO" identity,
+ may be used to override a failed test against the "MAIL FROM"
+ identity.
+
+ 3. For larger domains, it may not be possible to have a complete
+ or accurate list of forwarding services used by the owners of
+ the domain's mailboxes. In such cases, whitelists of
+ generally-recognized forwarding services could be employed.
+
+9.4. Mail Services
+
+ Service providers that offer mail services to third-party domains,
+ such as sending of bulk mail, may want to adjust their setup in light
+ of the authorization check described in this document. If the "MAIL
+ FROM" identity used for such E-Mail uses the domain of the service
+ provider, then the provider needs only to ensure that its sending
+ host is authorized by its own SPF record, if any.
+
+ If the "MAIL FROM" identity does not use the mail service provider's
+ domain, then extra care must be taken. The SPF record format has
+ several options for the third-party domain to authorize the service
+ provider's MTAs to send mail on its behalf. For mail service
+ providers, such as ISPs, that have a wide variety of customers using
+ the same MTA, steps should be taken to prevent cross-customer forgery
+ (see Section 10.4).
+
+9.5. MTA Relays
+
+ The authorization check generally precludes the use of arbitrary MTA
+ relays between sender and receiver of an E-Mail message.
+
+ Within an organization, MTA relays can be effectively deployed.
+ However, for purposes of this document, such relays are effectively
+ transparent. The SPF authorization check is a check between border
+ MTAs of different domains.
+
+ For mail senders, this means that published SPF records must
+ authorize any MTAs that actually send across the Internet. Usually,
+ these are just the border MTAs as internal MTAs simply forward mail
+ to these MTAs for delivery.
+
+
+
+
+Wong & Schlitt Experimental [Page 34]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ Mail receivers will generally want to perform the authorization check
+ at the border MTAs, specifically including all secondary MXs. This
+ allows mail that fails to be rejected during the SMTP session rather
+ than bounced. Internal MTAs then do not perform the authorization
+ test. To perform the authorization test other than at the border,
+ the host that first transferred the message to the organization must
+ be determined, which can be difficult to extract from the message
+ header. Testing other than at the border is not recommended.
+
+10. Security Considerations
+
+10.1. Processing Limits
+
+ As with most aspects of E-Mail, there are a number of ways that
+ malicious parties could use the protocol as an avenue for a
+ Denial-of-Service (DoS) attack. The processing limits outlined here
+ are designed to prevent attacks such as the following:
+
+ o A malicious party could create an SPF record with many references
+ to a victim's domain and send many E-Mails to different SPF
+ clients; those SPF clients would then create a DoS attack. In
+ effect, the SPF clients are being used to amplify the attacker's
+ bandwidth by using fewer bytes in the SMTP session than are used
+ by the DNS queries. Using SPF clients also allows the attacker to
+ hide the true source of the attack.
+
+ o Whereas implementations of check_host() are supposed to limit the
+ number of DNS lookups, malicious domains could publish records
+ that exceed these limits in an attempt to waste computation effort
+ at their targets when they send them mail. Malicious domains
+ could also design SPF records that cause particular
+ implementations to use excessive memory or CPU usage, or to
+ trigger bugs.
+
+ o Malicious parties could send a large volume of mail purporting to
+ come from the intended target to a wide variety of legitimate mail
+ hosts. These legitimate machines would then present a DNS load on
+ the target as they fetched the relevant records.
+
+ Of these, the case of a third party referenced in the SPF record is
+ the easiest for a DoS attack to effectively exploit. As a result,
+ limits that may seem reasonable for an individual mail server can
+ still allow an unreasonable amount of bandwidth amplification.
+ Therefore, the processing limits need to be quite low.
+
+ SPF implementations MUST limit the number of mechanisms and modifiers
+ that do DNS lookups to at most 10 per SPF check, including any
+ lookups caused by the use of the "include" mechanism or the
+
+
+
+Wong & Schlitt Experimental [Page 35]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ "redirect" modifier. If this number is exceeded during a check, a
+ PermError MUST be returned. The "include", "a", "mx", "ptr", and
+ "exists" mechanisms as well as the "redirect" modifier do count
+ against this limit. The "all", "ip4", and "ip6" mechanisms do not
+ require DNS lookups and therefore do not count against this limit.
+ The "exp" modifier does not count against this limit because the DNS
+ lookup to fetch the explanation string occurs after the SPF record
+ has been evaluated.
+
+ When evaluating the "mx" and "ptr" mechanisms, or the %{p} macro,
+ there MUST be a limit of no more than 10 MX or PTR RRs looked up and
+ checked.
+
+ SPF implementations SHOULD limit the total amount of data obtained
+ from the DNS queries. For example, when DNS over TCP or EDNS0 are
+ available, there may need to be an explicit limit to how much data
+ will be accepted to prevent excessive bandwidth usage or memory usage
+ and DoS attacks.
+
+ MTAs or other processors MAY also impose a limit on the maximum
+ amount of elapsed time to evaluate check_host(). Such a limit SHOULD
+ allow at least 20 seconds. If such a limit is exceeded, the result
+ of authorization SHOULD be "TempError".
+
+ Domains publishing records SHOULD try to keep the number of "include"
+ mechanisms and chained "redirect" modifiers to a minimum. Domains
+ SHOULD also try to minimize the amount of other DNS information
+ needed to evaluate a record. This can be done by choosing directives
+ that require less DNS information and placing lower-cost mechanisms
+ earlier in the SPF record.
+
+ For example, consider a domain set up as follows:
+
+ example.com. IN MX 10 mx.example.com.
+ mx.example.com. IN A 192.0.2.1
+ a.example.com. IN TXT "v=spf1 mx:example.com -all"
+ b.example.com. IN TXT "v=spf1 a:mx.example.com -all"
+ c.example.com. IN TXT "v=spf1 ip4:192.0.2.1 -all"
+
+ Evaluating check_host() for the domain "a.example.com" requires the
+ MX records for "example.com", and then the A records for the listed
+ hosts. Evaluating for "b.example.com" requires only the A records.
+ Evaluating for "c.example.com" requires none.
+
+ However, there may be administrative considerations: using "a" over
+ "ip4" allows hosts to be renumbered easily. Using "mx" over "a"
+ allows the set of mail hosts to be changed easily.
+
+
+
+
+Wong & Schlitt Experimental [Page 36]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+10.2. SPF-Authorized E-Mail May Contain Other False Identities
+
+ The "MAIL FROM" and "HELO" identity authorizations must not be
+ construed to provide more assurance than they do. It is entirely
+ possible for a malicious sender to inject a message using his own
+ domain in the identities used by SPF, to have that domain's SPF
+ record authorize the sending host, and yet the message can easily
+ list other identities in its header. Unless the user or the MUA
+ takes care to note that the authorized identity does not match the
+ other more commonly-presented identities (such as the From: header
+ field), the user may be lulled into a false sense of security.
+
+10.3. Spoofed DNS and IP Data
+
+ There are two aspects of this protocol that malicious parties could
+ exploit to undermine the validity of the check_host() function:
+
+ o The evaluation of check_host() relies heavily on DNS. A malicious
+ attacker could attack the DNS infrastructure and cause
+ check_host() to see spoofed DNS data, and then return incorrect
+ results. This could include returning "Pass" for an <ip> value
+ where the actual domain's record would evaluate to "Fail". See
+ [RFC3833] for a description of DNS weaknesses.
+
+ o The client IP address, <ip>, is assumed to be correct. A
+ malicious attacker could spoof TCP sequence numbers to make mail
+ appear to come from a permitted host for a domain that the
+ attacker is impersonating.
+
+10.4. Cross-User Forgery
+
+ By definition, SPF policies just map domain names to sets of
+ authorized MTAs, not whole E-Mail addresses to sets of authorized
+ users. Although the "l" macro (Section 8) provides a limited way to
+ define individual sets of authorized MTAs for specific E-Mail
+ addresses, it is generally impossible to verify, through SPF, the use
+ of specific E-Mail addresses by individual users of the same MTA.
+
+ It is up to mail services and their MTAs to directly prevent
+ cross-user forgery: based on SMTP AUTH ([RFC2554]), users should be
+ restricted to using only those E-Mail addresses that are actually
+ under their control (see [RFC4409], Section 6.1). Another means to
+ verify the identity of individual users is message cryptography such
+ as PGP ([RFC2440]) or S/MIME ([RFC3851]).
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 37]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+10.5. Untrusted Information Sources
+
+ SPF uses information supplied by third parties, such as the "HELO"
+ domain name, the "MAIL FROM" address, and SPF records. This
+ information is then passed to the receiver in the Received-SPF: trace
+ fields and possibly returned to the client MTA in the form of an SMTP
+ rejection message. This information must be checked for invalid
+ characters and excessively long lines.
+
+ When the authorization check fails, an explanation string may be
+ included in the reject response. Both the sender and the rejecting
+ receiver need to be aware that the explanation was determined by the
+ publisher of the SPF record checked and, in general, not the
+ receiver. The explanation may contain malicious URLs, or it may be
+ offensive or misleading.
+
+ This is probably less of a concern than it may initially seem since
+ such messages are returned to the sender, and the explanation strings
+ come from the sender policy published by the domain in the identity
+ claimed by that very sender. As long as the DSN is not redirected to
+ someone other than the actual sender, the only people who see
+ malicious explanation strings are people whose messages claim to be
+ from domains that publish such strings in their SPF records. In
+ practice, DSNs can be misdirected, such as when an MTA accepts an
+ E-Mail and then later generates a DSN to a forged address, or when an
+ E-Mail forwarder does not direct the DSN back to the original sender.
+
+10.6. Privacy Exposure
+
+ Checking SPF records causes DNS queries to be sent to the domain
+ owner. These DNS queries, especially if they are caused by the
+ "exists" mechanism, can contain information about who is sending
+ E-Mail and likely to which MTA the E-Mail is being sent. This can
+ introduce some privacy concerns, which may be more or less of an
+ issue depending on local laws and the relationship between the domain
+ owner and the person sending the E-Mail.
+
+11. Contributors and Acknowledgements
+
+ This document is largely based on the work of Meng Weng Wong and Mark
+ Lentczner. Although, as this section acknowledges, many people have
+ contributed to this document, a very large portion of the writing and
+ editing are due to Meng and Mark.
+
+ This design owes a debt of parentage to [RMX] by Hadmut Danisch and
+ to [DMP] by Gordon Fecyk. The idea of using a DNS record to check
+ the legitimacy of an E-Mail address traces its ancestry further back
+ through messages on the namedroppers mailing list by Paul Vixie
+
+
+
+Wong & Schlitt Experimental [Page 38]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ [Vixie] (based on suggestion by Jim Miller) and by David Green
+ [Green].
+
+ Philip Gladstone contributed the concept of macros to the
+ specification, multiplying the expressiveness of the language and
+ making per-user and per-IP lookups possible.
+
+ The authors would also like to thank the literally hundreds of
+ individuals who have participated in the development of this design.
+ They are far too numerous to name, but they include the following:
+
+ The folks on the spf-discuss mailing list.
+ The folks on the SPAM-L mailing list.
+ The folks on the IRTF ASRG mailing list.
+ The folks on the IETF MARID mailing list.
+ The folks on #perl.
+
+12. IANA Considerations
+
+12.1. The SPF DNS Record Type
+
+ The IANA has assigned a new Resource Record Type and Qtype from the
+ DNS Parameters Registry for the SPF RR type with code 99.
+
+12.2. The Received-SPF Mail Header Field
+
+ Per [RFC3864], the "Received-SPF:" header field is added to the IANA
+ Permanent Message Header Field Registry. The following is the
+ registration template:
+
+ Header field name: Received-SPF
+ Applicable protocol: mail ([RFC2822])
+ Status: Experimental
+ Author/Change controller: IETF
+ Specification document(s): RFC 4408
+ Related information:
+ Requesting SPF Council review of any proposed changes and
+ additions to this field are recommended. For information about
+ the SPF Council see http://www.openspf.org/Council
+
+13. References
+
+13.1. Normative References
+
+ [RFC1035] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+
+
+
+
+Wong & Schlitt Experimental [Page 39]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ [RFC1123] Braden, R., "Requirements for Internet Hosts - Application
+ and Support", STD 3, RFC 1123, October 1989.
+
+ [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate
+ Requirement Levels", BCP 14, RFC 2119, March 1997.
+
+ [RFC2821] Klensin, J., "Simple Mail Transfer Protocol", RFC 2821,
+ April 2001.
+
+ [RFC2822] Resnick, P., "Internet Message Format", RFC 2822, April
+ 2001.
+
+ [RFC3464] Moore, K. and G. Vaudreuil, "An Extensible Message Format
+ for Delivery Status Notifications", RFC 3464, January
+ 2003.
+
+ [RFC3513] Hinden, R. and S. Deering, "Internet Protocol Version 6
+ (IPv6) Addressing Architecture", RFC 3513, April 2003.
+
+ [RFC3864] Klyne, G., Nottingham, M., and J. Mogul, "Registration
+ Procedures for Message Header Fields", BCP 90, RFC 3864,
+ September 2004.
+
+ [RFC3986] Berners-Lee, T., Fielding, R., and L. Masinter, "Uniform
+ Resource Identifier (URI): Generic Syntax", STD 66, RFC
+ 3986, January 2005.
+
+ [RFC4234] Crocker, D. and P. Overell, "Augmented BNF for Syntax
+ Specifications: ABNF", RFC 4234, October 2005.
+
+ [US-ASCII] American National Standards Institute (formerly United
+ States of America Standards Institute), "USA Code for
+ Information Interchange, X3.4", 1968.
+
+ ANSI X3.4-1968 has been replaced by newer versions with slight
+ modifications, but the 1968 version remains definitive for
+ the Internet.
+
+13.2 Informative References
+
+ [RFC1034] Mockapetris, P., "Domain names - concepts and facilities",
+ STD 13, RFC 1034, November 1987.
+
+ [RFC1983] Malkin, G., "Internet Users' Glossary", RFC 1983, August
+ 1996.
+
+ [RFC2440] Callas, J., Donnerhacke, L., Finney, H., and R. Thayer,
+ "OpenPGP Message Format", RFC 2440, November 1998.
+
+
+
+Wong & Schlitt Experimental [Page 40]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ [RFC2554] Myers, J., "SMTP Service Extension for Authentication",
+ RFC 2554, March 1999.
+
+ [RFC3696] Klensin, J., "Application Techniques for Checking and
+ Transformation of Names", RFC 3696, February 2004.
+
+ [RFC3833] Atkins, D. and R. Austein, "Threat Analysis of the Domain
+ Name System (DNS)", RFC 3833, August 2004.
+
+ [RFC3851] Ramsdell, B., "Secure/Multipurpose Internet Mail
+ Extensions (S/MIME) Version 3.1 Message Specification",
+ RFC 3851, July 2004.
+
+ [RFC4409] Gellens, R. and J. Klensin, "Message Submission for Mail",
+ RFC 4409, April 2006.
+
+ [RMX] Danish, H., "The RMX DNS RR Type for light weight sender
+ authentication", Work In Progress
+
+ [DMP] Fecyk, G., "Designated Mailers Protocol", Work In Progress
+
+ [Vixie] Vixie, P., "Repudiating MAIL FROM", 2002.
+
+ [Green] Green, D., "Domain-Authorized SMTP Mail", 2002.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 41]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+Appendix A. Collected ABNF
+
+ This section is normative and any discrepancies with the ABNF
+ fragments in the preceding text are to be resolved in favor of this
+ grammar.
+
+ See [RFC4234] for ABNF notation. Please note that as per this ABNF
+ definition, literal text strings (those in quotes) are case-
+ insensitive. Hence, "mx" matches "mx", "MX", "mX", and "Mx".
+
+ record = version terms *SP
+ version = "v=spf1"
+
+ terms = *( 1*SP ( directive / modifier ) )
+
+ directive = [ qualifier ] mechanism
+ qualifier = "+" / "-" / "?" / "~"
+ mechanism = ( all / include
+ / A / MX / PTR / IP4 / IP6 / exists )
+
+ all = "all"
+ include = "include" ":" domain-spec
+ A = "a" [ ":" domain-spec ] [ dual-cidr-length ]
+ MX = "mx" [ ":" domain-spec ] [ dual-cidr-length ]
+ PTR = "ptr" [ ":" domain-spec ]
+ IP4 = "ip4" ":" ip4-network [ ip4-cidr-length ]
+ IP6 = "ip6" ":" ip6-network [ ip6-cidr-length ]
+ exists = "exists" ":" domain-spec
+
+ modifier = redirect / explanation / unknown-modifier
+ redirect = "redirect" "=" domain-spec
+ explanation = "exp" "=" domain-spec
+ unknown-modifier = name "=" macro-string
+
+ ip4-cidr-length = "/" 1*DIGIT
+ ip6-cidr-length = "/" 1*DIGIT
+ dual-cidr-length = [ ip4-cidr-length ] [ "/" ip6-cidr-length ]
+
+ ip4-network = qnum "." qnum "." qnum "." qnum
+ qnum = DIGIT ; 0-9
+ / %x31-39 DIGIT ; 10-99
+ / "1" 2DIGIT ; 100-199
+ / "2" %x30-34 DIGIT ; 200-249
+ / "25" %x30-35 ; 250-255
+ ; conventional dotted quad notation. e.g., 192.0.2.0
+ ip6-network = <as per [RFC 3513], section 2.2>
+ ; e.g., 2001:DB8::CD30
+
+
+
+
+Wong & Schlitt Experimental [Page 42]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ domain-spec = macro-string domain-end
+ domain-end = ( "." toplabel [ "." ] ) / macro-expand
+ toplabel = ( *alphanum ALPHA *alphanum ) /
+ ( 1*alphanum "-" *( alphanum / "-" ) alphanum )
+ ; LDH rule plus additional TLD restrictions
+ ; (see [RFC3696], Section 2)
+
+ alphanum = ALPHA / DIGIT
+
+ explain-string = *( macro-string / SP )
+
+ macro-string = *( macro-expand / macro-literal )
+ macro-expand = ( "%{" macro-letter transformers *delimiter "}" )
+ / "%%" / "%_" / "%-"
+ macro-literal = %x21-24 / %x26-7E
+ ; visible characters except "%"
+ macro-letter = "s" / "l" / "o" / "d" / "i" / "p" / "h" /
+ "c" / "r" / "t"
+ transformers = *DIGIT [ "r" ]
+ delimiter = "." / "-" / "+" / "," / "/" / "_" / "="
+
+ name = ALPHA *( ALPHA / DIGIT / "-" / "_" / "." )
+
+ header-field = "Received-SPF:" [CFWS] result FWS [comment FWS]
+ [ key-value-list ] CRLF
+
+ result = "Pass" / "Fail" / "SoftFail" / "Neutral" /
+ "None" / "TempError" / "PermError"
+
+ key-value-list = key-value-pair *( ";" [CFWS] key-value-pair )
+ [";"]
+
+ key-value-pair = key [CFWS] "=" ( dot-atom / quoted-string )
+
+ key = "client-ip" / "envelope-from" / "helo" /
+ "problem" / "receiver" / "identity" /
+ mechanism / "x-" name / name
+
+ identity = "mailfrom" ; for the "MAIL FROM" identity
+ / "helo" ; for the "HELO" identity
+ / name ; other identities
+
+ dot-atom = <unquoted word as per [RFC2822]>
+ quoted-string = <quoted string as per [RFC2822]>
+ comment = <comment string as per [RFC2822]>
+ CFWS = <comment or folding white space as per [RFC2822]>
+ FWS = <folding white space as per [RFC2822]>
+ CRLF = <standard end-of-line token as per [RFC2822]>
+
+
+
+Wong & Schlitt Experimental [Page 43]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+Appendix B. Extended Examples
+
+ These examples are based on the following DNS setup:
+
+ ; A domain with two mail servers, two hosts
+ ; and two servers at the domain name
+ $ORIGIN example.com.
+ @ MX 10 mail-a
+ MX 20 mail-b
+ A 192.0.2.10
+ A 192.0.2.11
+ amy A 192.0.2.65
+ bob A 192.0.2.66
+ mail-a A 192.0.2.129
+ mail-b A 192.0.2.130
+ www CNAME example.com.
+
+ ; A related domain
+ $ORIGIN example.org.
+ @ MX 10 mail-c
+ mail-c A 192.0.2.140
+
+ ; The reverse IP for those addresses
+ $ORIGIN 2.0.192.in-addr.arpa.
+ 10 PTR example.com.
+ 11 PTR example.com.
+ 65 PTR amy.example.com.
+ 66 PTR bob.example.com.
+ 129 PTR mail-a.example.com.
+ 130 PTR mail-b.example.com.
+ 140 PTR mail-c.example.org.
+
+ ; A rogue reverse IP domain that claims to be
+ ; something it's not
+ $ORIGIN 0.0.10.in-addr.arpa.
+ 4 PTR bob.example.com.
+
+B.1. Simple Examples
+
+ These examples show various possible published records for
+ example.com and which values if <ip> would cause check_host() to
+ return "Pass". Note that <domain> is "example.com".
+
+ v=spf1 +all
+ -- any <ip> passes
+
+ v=spf1 a -all
+ -- hosts 192.0.2.10 and 192.0.2.11 pass
+
+
+
+Wong & Schlitt Experimental [Page 44]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+ v=spf1 a:example.org -all
+ -- no sending hosts pass since example.org has no A records
+
+ v=spf1 mx -all
+ -- sending hosts 192.0.2.129 and 192.0.2.130 pass
+
+ v=spf1 mx:example.org -all
+ -- sending host 192.0.2.140 passes
+
+ v=spf1 mx mx:example.org -all
+ -- sending hosts 192.0.2.129, 192.0.2.130, and 192.0.2.140 pass
+
+ v=spf1 mx/30 mx:example.org/30 -all
+ -- any sending host in 192.0.2.128/30 or 192.0.2.140/30 passes
+
+ v=spf1 ptr -all
+ -- sending host 192.0.2.65 passes (reverse DNS is valid and is in
+ example.com)
+ -- sending host 192.0.2.140 fails (reverse DNS is valid, but not
+ in example.com)
+ -- sending host 10.0.0.4 fails (reverse IP is not valid)
+
+ v=spf1 ip4:192.0.2.128/28 -all
+ -- sending host 192.0.2.65 fails
+ -- sending host 192.0.2.129 passes
+
+B.2. Multiple Domain Example
+
+ These examples show the effect of related records:
+
+ example.org: "v=spf1 include:example.com include:example.net -all"
+
+ This record would be used if mail from example.org actually came
+ through servers at example.com and example.net. Example.org's
+ designated servers are the union of example.com's and example.net's
+ designated servers.
+
+ la.example.org: "v=spf1 redirect=example.org"
+ ny.example.org: "v=spf1 redirect=example.org"
+ sf.example.org: "v=spf1 redirect=example.org"
+
+ These records allow a set of domains that all use the same mail
+ system to make use of that mail system's record. In this way, only
+ the mail system's record needs to be updated when the mail setup
+ changes. These domains' records never have to change.
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 45]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+B.3. DNSBL Style Example
+
+ Imagine that, in addition to the domain records listed above, there
+ are these:
+
+ $ORIGIN _spf.example.com. mary.mobile-users A
+ 127.0.0.2 fred.mobile-users A 127.0.0.2
+ 15.15.168.192.joel.remote-users A 127.0.0.2
+ 16.15.168.192.joel.remote-users A 127.0.0.2
+
+ The following records describe users at example.com who mail from
+ arbitrary servers, or who mail from personal servers.
+
+ example.com:
+
+ v=spf1 mx
+ include:mobile-users._spf.%{d}
+ include:remote-users._spf.%{d}
+ -all
+
+ mobile-users._spf.example.com:
+
+ v=spf1 exists:%{l1r+}.%{d}
+
+ remote-users._spf.example.com:
+
+ v=spf1 exists:%{ir}.%{l1r+}.%{d}
+
+B.4. Multiple Requirements Example
+
+ Say that your sender policy requires both that the IP address is
+ within a certain range and that the reverse DNS for the IP matches.
+ This can be done several ways, including the following:
+
+ example.com. SPF ( "v=spf1 "
+ "-include:ip4._spf.%{d} "
+ "-include:ptr._spf.%{d} "
+ "+all" )
+ ip4._spf.example.com. SPF "v=spf1 -ip4:192.0.2.0/24 +all"
+ ptr._spf.example.com. SPF "v=spf1 -ptr +all"
+
+ This example shows how the "-include" mechanism can be useful, how an
+ SPF record that ends in "+all" can be very restrictive, and the use
+ of De Morgan's Law.
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 46]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+Authors' Addresses
+
+ Meng Weng Wong
+ Singapore
+
+ EMail: mengwong+spf@pobox.com
+
+
+ Wayne Schlitt
+ 4615 Meredeth #9
+ Lincoln Nebraska, NE 68506
+ United States of America
+
+ EMail: wayne@schlitt.net
+ URI: http://www.schlitt.net/spf/
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 47]
+
+RFC 4408 Sender Policy Framework (SPF) April 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Wong & Schlitt Experimental [Page 48]
+
diff --git a/contrib/bind9/doc/rfc/rfc4470.txt b/contrib/bind9/doc/rfc/rfc4470.txt
new file mode 100644
index 000000000000..ac12d65c44c1
--- /dev/null
+++ b/contrib/bind9/doc/rfc/rfc4470.txt
@@ -0,0 +1,451 @@
+
+
+
+
+
+
+Network Working Group S. Weiler
+Request for Comments: 4470 SPARTA, Inc.
+Updates: 4035, 4034 J. Ihren
+Category: Standards Track Autonomica AB
+ April 2006
+
+
+ Minimally Covering NSEC Records and DNSSEC On-line Signing
+
+
+Status of This Memo
+
+ This document specifies an Internet standards track protocol for the
+ Internet community, and requests discussion and suggestions for
+ improvements. Please refer to the current edition of the "Internet
+ Official Protocol Standards" (STD 1) for the standardization state
+ and status of this protocol. Distribution of this memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+Abstract
+
+ This document describes how to construct DNSSEC NSEC resource records
+ that cover a smaller range of names than called for by RFC 4034. By
+ generating and signing these records on demand, authoritative name
+ servers can effectively stop the disclosure of zone contents
+ otherwise made possible by walking the chain of NSEC records in a
+ signed zone.
+
+Table of Contents
+
+ 1. Introduction ....................................................1
+ 2. Applicability of This Technique .................................2
+ 3. Minimally Covering NSEC Records .................................2
+ 4. Better Epsilon Functions ........................................4
+ 5. Security Considerations .........................................5
+ 6. Acknowledgements ................................................6
+ 7. Normative References ............................................6
+
+1. Introduction
+
+ With DNSSEC [1], an NSEC record lists the next instantiated name in
+ its zone, proving that no names exist in the "span" between the
+ NSEC's owner name and the name in the "next name" field. In this
+ document, an NSEC record is said to "cover" the names between its
+ owner name and next name.
+
+
+
+Weiler & Ihren Standards Track [Page 1]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+ Through repeated queries that return NSEC records, it is possible to
+ retrieve all of the names in the zone, a process commonly called
+ "walking" the zone. Some zone owners have policies forbidding zone
+ transfers by arbitrary clients; this side effect of the NSEC
+ architecture subverts those policies.
+
+ This document presents a way to prevent zone walking by constructing
+ NSEC records that cover fewer names. These records can make zone
+ walking take approximately as many queries as simply asking for all
+ possible names in a zone, making zone walking impractical. Some of
+ these records must be created and signed on demand, which requires
+ on-line private keys. Anyone contemplating use of this technique is
+ strongly encouraged to review the discussion of the risks of on-line
+ signing in Section 5.
+
+1.2. Keywords
+
+ The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
+ "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
+ document are to be interpreted as described in RFC 2119 [4].
+
+2. Applicability of This Technique
+
+ The technique presented here may be useful to a zone owner that wants
+ to use DNSSEC, is concerned about exposure of its zone contents via
+ zone walking, and is willing to bear the costs of on-line signing.
+
+ As discussed in Section 5, on-line signing has several security
+ risks, including an increased likelihood of private keys being
+ disclosed and an increased risk of denial of service attack. Anyone
+ contemplating use of this technique is strongly encouraged to review
+ the discussion of the risks of on-line signing in Section 5.
+
+ Furthermore, at the time this document was published, the DNSEXT
+ working group was actively working on a mechanism to prevent zone
+ walking that does not require on-line signing (tentatively called
+ NSEC3). The new mechanism is likely to expose slightly more
+ information about the zone than this technique (e.g., the number of
+ instantiated names), but it may be preferable to this technique.
+
+3. Minimally Covering NSEC Records
+
+ This mechanism involves changes to NSEC records for instantiated
+ names, which can still be generated and signed in advance, as well as
+ the on-demand generation and signing of new NSEC records whenever a
+ name must be proven not to exist.
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 2]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+ In the "next name" field of instantiated names' NSEC records, rather
+ than list the next instantiated name in the zone, list any name that
+ falls lexically after the NSEC's owner name and before the next
+ instantiated name in the zone, according to the ordering function in
+ RFC 4034 [2] Section 6.1. This relaxes the requirement in Section
+ 4.1.1 of RFC 4034 that the "next name" field contains the next owner
+ name in the zone. This change is expected to be fully compatible
+ with all existing DNSSEC validators. These NSEC records are returned
+ whenever proving something specifically about the owner name (e.g.,
+ that no resource records of a given type appear at that name).
+
+ Whenever an NSEC record is needed to prove the non-existence of a
+ name, a new NSEC record is dynamically produced and signed. The new
+ NSEC record has an owner name lexically before the QNAME but
+ lexically following any existing name and a "next name" lexically
+ following the QNAME but before any existing name.
+
+ The generated NSEC record's type bitmap MUST have the RRSIG and NSEC
+ bits set and SHOULD NOT have any other bits set. This relaxes the
+ requirement in Section 2.3 of RFC4035 that NSEC RRs not appear at
+ names that did not exist before the zone was signed.
+
+ The functions to generate the lexically following and proceeding
+ names need not be perfect or consistent, but the generated NSEC
+ records must not cover any existing names. Furthermore, this
+ technique works best when the generated NSEC records cover as few
+ names as possible. In this document, the functions that generate the
+ nearby names are called "epsilon" functions, a reference to the
+ mathematical convention of using the greek letter epsilon to
+ represent small deviations.
+
+ An NSEC record denying the existence of a wildcard may be generated
+ in the same way. Since the NSEC record covering a non-existent
+ wildcard is likely to be used in response to many queries,
+ authoritative name servers using the techniques described here may
+ want to pregenerate or cache that record and its corresponding RRSIG.
+
+ For example, a query for an A record at the non-instantiated name
+ example.com might produce the following two NSEC records, the first
+ denying the existence of the name example.com and the second denying
+ the existence of a wildcard:
+
+ exampld.com 3600 IN NSEC example-.com ( RRSIG NSEC )
+
+ \).com 3600 IN NSEC +.com ( RRSIG NSEC )
+
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 3]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+ Before answering a query with these records, an authoritative server
+ must test for the existence of names between these endpoints. If the
+ generated NSEC would cover existing names (e.g., exampldd.com or
+ *bizarre.example.com), a better epsilon function may be used or the
+ covered name closest to the QNAME could be used as the NSEC owner
+ name or next name, as appropriate. If an existing name is used as
+ the NSEC owner name, that name's real NSEC record MUST be returned.
+ Using the same example, assuming an exampldd.com delegation exists,
+ this record might be returned from the parent:
+
+ exampldd.com 3600 IN NSEC example-.com ( NS DS RRSIG NSEC )
+
+ Like every authoritative record in the zone, each generated NSEC
+ record MUST have corresponding RRSIGs generated using each algorithm
+ (but not necessarily each DNSKEY) in the zone's DNSKEY RRset, as
+ described in RFC 4035 [3] Section 2.2. To minimize the number of
+ signatures that must be generated, a zone may wish to limit the
+ number of algorithms in its DNSKEY RRset.
+
+4. Better Epsilon Functions
+
+ Section 6.1 of RFC 4034 defines a strict ordering of DNS names.
+ Working backward from that definition, it should be possible to
+ define epsilon functions that generate the immediately following and
+ preceding names, respectively. This document does not define such
+ functions. Instead, this section presents functions that come
+ reasonably close to the perfect ones. As described above, an
+ authoritative server should still ensure than no generated NSEC
+ covers any existing name.
+
+ To increment a name, add a leading label with a single null (zero-
+ value) octet.
+
+ To decrement a name, decrement the last character of the leftmost
+ label, then fill that label to a length of 63 octets with octets of
+ value 255. To decrement a null (zero-value) octet, remove the octet
+ -- if an empty label is left, remove the label. Defining this
+ function numerically: fill the leftmost label to its maximum length
+ with zeros (numeric, not ASCII zeros) and subtract one.
+
+ In response to a query for the non-existent name foo.example.com,
+ these functions produce NSEC records of the following:
+
+
+
+
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 4]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+ fon\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255.example.com 3600 IN NSEC \000.foo.example.com ( NSEC RRSIG )
+
+ \)\255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255\255\255\255\255\255\255\255\255\255\255\255\255\255
+ \255\255.example.com 3600 IN NSEC \000.*.example.com ( NSEC RRSIG )
+
+ The first of these NSEC RRs proves that no exact match for
+ foo.example.com exists, and the second proves that there is no
+ wildcard in example.com.
+
+ Both of these functions are imperfect: they do not take into account
+ constraints on number of labels in a name nor total length of a name.
+ As noted in the previous section, though, this technique does not
+ depend on the use of perfect epsilon functions: it is sufficient to
+ test whether any instantiated names fall into the span covered by the
+ generated NSEC and, if so, substitute those instantiated owner names
+ for the NSEC owner name or next name, as appropriate.
+
+5. Security Considerations
+
+ This approach requires on-demand generation of RRSIG records. This
+ creates several new vulnerabilities.
+
+ First, on-demand signing requires that a zone's authoritative servers
+ have access to its private keys. Storing private keys on well-known
+ Internet-accessible servers may make them more vulnerable to
+ unintended disclosure.
+
+ Second, since generation of digital signatures tends to be
+ computationally demanding, the requirement for on-demand signing
+ makes authoritative servers vulnerable to a denial of service attack.
+
+ Last, if the epsilon functions are predictable, on-demand signing may
+ enable a chosen-plaintext attack on a zone's private keys. Zones
+ using this approach should attempt to use cryptographic algorithms
+ that are resistant to chosen-plaintext attacks. It is worth noting
+ that although DNSSEC has a "mandatory to implement" algorithm, that
+ is a requirement on resolvers and validators -- there is no
+ requirement that a zone be signed with any given algorithm.
+
+ The success of using minimally covering NSEC records to prevent zone
+ walking depends greatly on the quality of the epsilon functions
+
+
+
+Weiler & Ihren Standards Track [Page 5]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+ chosen. An increment function that chooses a name obviously derived
+ from the next instantiated name may be easily reverse engineered,
+ destroying the value of this technique. An increment function that
+ always returns a name close to the next instantiated name is likewise
+ a poor choice. Good choices of epsilon functions are the ones that
+ produce the immediately following and preceding names, respectively,
+ though zone administrators may wish to use less perfect functions
+ that return more human-friendly names than the functions described in
+ Section 4 above.
+
+ Another obvious but misguided concern is the danger from synthesized
+ NSEC records being replayed. It is possible for an attacker to
+ replay an old but still validly signed NSEC record after a new name
+ has been added in the span covered by that NSEC, incorrectly proving
+ that there is no record at that name. This danger exists with DNSSEC
+ as defined in [3]. The techniques described here actually decrease
+ the danger, since the span covered by any NSEC record is smaller than
+ before. Choosing better epsilon functions will further reduce this
+ danger.
+
+6. Acknowledgements
+
+ Many individuals contributed to this design. They include, in
+ addition to the authors of this document, Olaf Kolkman, Ed Lewis,
+ Peter Koch, Matt Larson, David Blacka, Suzanne Woolf, Jaap Akkerhuis,
+ Jakob Schlyter, Bill Manning, and Joao Damas.
+
+ In addition, the editors would like to thank Ed Lewis, Scott Rose,
+ and David Blacka for their careful review of the document.
+
+7. Normative References
+
+ [1] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "DNS Security Introduction and Requirements", RFC 4033, March
+ 2005.
+
+ [2] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "Resource Records for the DNS Security Extensions", RFC 4034,
+ March 2005.
+
+ [3] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "Protocol Modifications for the DNS Security Extensions", RFC
+ 4035, March 2005.
+
+ [4] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 6]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+Authors' Addresses
+
+ Samuel Weiler
+ SPARTA, Inc.
+ 7075 Samuel Morse Drive
+ Columbia, Maryland 21046
+ US
+
+ EMail: weiler@tislabs.com
+
+
+ Johan Ihren
+ Autonomica AB
+ Bellmansgatan 30
+ Stockholm SE-118 47
+ Sweden
+
+ EMail: johani@autonomica.se
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 7]
+
+RFC 4470 NSEC Epsilon April 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Weiler & Ihren Standards Track [Page 8]
+
diff --git a/contrib/bind9/doc/rfc/rfc4634.txt b/contrib/bind9/doc/rfc/rfc4634.txt
new file mode 100644
index 000000000000..b672df8a4455
--- /dev/null
+++ b/contrib/bind9/doc/rfc/rfc4634.txt
@@ -0,0 +1,6051 @@
+
+
+
+
+
+
+Network Working Group D. Eastlake 3rd
+Request for Comments: 4634 Motorola Labs
+Updates: 3174 T. Hansen
+Category: Informational AT&T Labs
+ July 2006
+
+
+ US Secure Hash Algorithms (SHA and HMAC-SHA)
+
+Status of This Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+Abstract
+
+ The United States of America has adopted a suite of Secure Hash
+ Algorithms (SHAs), including four beyond SHA-1, as part of a Federal
+ Information Processing Standard (FIPS), specifically SHA-224 (RFC
+ 3874), SHA-256, SHA-384, and SHA-512. The purpose of this document
+ is to make source code performing these hash functions conveniently
+ available to the Internet community. The sample code supports input
+ strings of arbitrary bit length. SHA-1's sample code from RFC 3174
+ has also been updated to handle input strings of arbitrary bit
+ length. Most of the text herein was adapted by the authors from FIPS
+ 180-2.
+
+ Code to perform SHA-based HMACs, with arbitrary bit length text, is
+ also included.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 1]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+Table of Contents
+
+ 1. Overview of Contents ............................................3
+ 1.1. License ....................................................4
+ 2. Notation for Bit Strings and Integers ...........................4
+ 3. Operations on Words .............................................5
+ 4. Message Padding and Parsing .....................................6
+ 4.1. SHA-224 and SHA-256 ........................................7
+ 4.2. SHA-384 and SHA-512 ........................................8
+ 5. Functions and Constants Used ....................................9
+ 5.1. SHA-224 and SHA-256 ........................................9
+ 5.2. SHA-384 and SHA-512 .......................................10
+ 6. Computing the Message Digest ...................................11
+ 6.1. SHA-224 and SHA-256 Initialization ........................11
+ 6.2. SHA-224 and SHA-256 Processing ............................11
+ 6.3. SHA-384 and SHA-512 Initialization ........................13
+ 6.4. SHA-384 and SHA-512 Processing ............................14
+ 7. SHA-Based HMACs ................................................15
+ 8. C Code for SHAs ................................................15
+ 8.1. The .h File ...............................................18
+ 8.2. The SHA Code ..............................................24
+ 8.2.1. sha1.c .............................................24
+ 8.2.2. sha224-256.c .......................................33
+ 8.2.3. sha384-512.c .......................................45
+ 8.2.4. usha.c .............................................67
+ 8.2.5. sha-private.h ......................................72
+ 8.3. The HMAC Code .............................................73
+ 8.4. The Test Driver ...........................................78
+ 9. Security Considerations .......................................106
+ 10. Normative References .........................................106
+ 11. Informative References .......................................106
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 2]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+1. Overview of Contents
+
+ NOTE: Much of the text below is taken from [FIPS180-2] and assertions
+ therein of the security of the algorithms described are made by the
+ US Government, the author of [FIPS180-2], and not by the authors of
+ this document.
+
+ The text below specifies Secure Hash Algorithms, SHA-224 [RFC3874],
+ SHA-256, SHA-384, and SHA-512, for computing a condensed
+ 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 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. The message digests range in length from 224 to 512 bits,
+ depending on the algorithm. Secure hash algorithms are typically
+ used with other cryptographic algorithms, such as digital signature
+ algorithms and keyed hash authentication codes, or in the generation
+ of random numbers [RFC4086].
+
+ The four algorithms specified in this document are called secure
+ because it is computationally infeasible to (1) find a message that
+ corresponds to a given message digest, or (2) find two different
+ messages that produce the same message digest. Any change to a
+ message in transit will, with very high probability, result in a
+ different message digest. This will result in a verification failure
+ when the secure hash algorithm is used with a digital signature
+ algorithm or a keyed-hash message authentication algorithm.
+
+ The code provided herein supports input strings of arbitrary bit
+ length. SHA-1's sample code from [RFC3174] has also been updated to
+ handle input strings of arbitrary bit length. See Section 1.1 for
+ license information for this code.
+
+ Section 2 below defines the terminology and functions used as
+ building blocks to form these algorithms. Section 3 describes the
+ fundamental operations on words from which these algorithms are
+ built. Section 4 describes how messages are padded up to an integral
+ multiple of the required block size and then parsed into blocks.
+ Section 5 defines the constants and the composite functions used to
+ specify these algorithms. Section 6 gives the actual specification
+ for the SHA-224, SHA-256, SHA-384, and SHA-512 functions. Section 7
+ provides pointers to the specification of HMAC keyed message
+ authentication codes based on the SHA algorithms. Section 8 gives
+ sample code for the SHA algorithms and Section 9 code for SHA-based
+ HMACs. The SHA-based HMACs will accept arbitrary bit length text.
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 3]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+1.1. License
+
+ Permission is granted for all uses, commercial and non-commercial, of
+ the sample code found in Section 8. Royalty free license to use,
+ copy, modify and distribute the software found in Section 8 is
+ granted, provided that this document is identified in all material
+ mentioning or referencing this software, and provided that
+ redistributed derivative works do not contain misleading author or
+ version information.
+
+ The authors make no representations concerning either the
+ merchantability of this software or the suitability of this software
+ for any particular purpose. It is provided "as is" without express
+ or implied warranty of any kind.
+
+2. Notation for Bit Strings and Integers
+
+ The following terminology related to bit strings and integers will be
+ used:
+
+ a. A hex digit is an element of the set {0, 1, ... , 9, A, ... ,
+ F}. A hex digit is the representation of a 4-bit string.
+ Examples: 7 = 0111, A = 1010.
+
+ b. A word equals a 32-bit or 64-bit string, which may be
+ represented 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 equivalent as described in (a) above. Example:
+
+ 1010 0001 0000 0011 1111 1110 0010 0011 = A103FE23.
+
+ Throughout this document, the "big-endian" convention is used
+ when expressing both 32-bit and 64-bit words, so that within
+ each word the most significant bit is shown in the left-most bit
+ position.
+
+ 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
+ as a 32-bit word. The least significant four bits of the
+ integer are represented by the right-most hex digit of the word
+ representation. Example: the integer 291 = 2^8+2^5+2^1+2^0 =
+ 256+32+2+1 is represented by the hex word 00000123.
+
+ The same holds true for an integer between 0 and 2^64-1
+ inclusive, which may be represented as a 64-bit word.
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 4]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ If Z is an integer, 0 <= z < 2^64, then z = (2^32)x + y where 0
+ <= x < 2^32 and 0 <= y < 2^32. Since x and y can be represented
+ as words X and Y, respectively, z can be represented as the pair
+ of words (X,Y).
+
+ d. block = 512-bit or 1024-bit string. A block (e.g., B) may be
+ represented as a sequence of 32-bit or 64-bit words.
+
+3. Operations on Words
+
+ The following logical operators will be applied to words in all four
+ hash operations specified herein. SHA-224 and SHA-256 operate on
+ 32-bit words, while SHA-384 and SHA-512 operate on 64-bit words.
+
+ In the operations below, x<<n is obtained as follows: discard the
+ left-most n bits of x and then pad the result with n zeroed bits on
+ the right (the result will still be the same number of bits).
+
+ a. Bitwise logical word operations
+
+ X AND Y = bitwise logical "and" 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.
+
+ NOT X = bitwise logical "complement" of X.
+
+ Example:
+ 01101100101110011101001001111011
+ XOR 01100101110000010110100110110111
+ --------------------------------
+ = 00001001011110001011101111001100
+
+ 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 < 2^w. For positive integers n and m, let
+
+ n mod m
+
+ be the remainder upon dividing n by m. Compute
+
+ z = (x + y) mod 2^w.
+
+ Then 0 <= z < 2^w. Convert z to a word, Z, and define Z = X +
+ Y.
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 5]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ c. The right shift operation SHR^n(x), where x is a w-bit word and
+ n is an integer with 0 <= n < w, is defined by
+
+ SHR^n(x) = x>>n
+
+ 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
+ defined by
+
+ ROTR^n(x) = (x>>n) OR (x<<(w-n))
+
+ 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 by
+
+ ROTL^n(X) = (x<<n) OR (x>>w-n)
+
+ Note the following equivalence relationships, where w is fixed
+ in each relationship:
+
+ ROTL^n(x) = ROTR^(w-x)(x)
+
+ ROTR^n(x) = ROTL^(w-n)(x)
+
+4. Message Padding and Parsing
+
+ The hash functions specified herein are used to compute a message
+ digest for a message or data file that is provided as input. The
+ message or data file should be considered to be a bit string. The
+ length of the message is the number of bits in the message (the empty
+ message has length 0). If the number of bits in a message is a
+ multiple of 8, for compactness we can represent the message in hex.
+ The purpose of message padding is to make the total length of a
+ padded message a multiple of 512 for SHA-224 and SHA-256 or a
+ multiple of 1024 for SHA-384 and SHA-512.
+
+ The following specifies how this padding shall be performed. As a
+ summary, a "1" followed by a number of "0"s followed by a 64-bit or
+ 128-bit integer are appended to the end of the message to produce a
+ padded message of length 512*n or 1024*n. The minimum number of "0"s
+ necessary to meet this criterion is used. The appended integer is
+ the length of the original message. The padded message is then
+ processed by the hash function as n 512-bit or 1024-bit blocks.
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 6]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+4.1. SHA-224 and SHA-256
+
+ 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:
+
+ a. "1" is appended. Example: if the original message is
+ "01010000", this is padded to "010100001".
+
+ b. K "0"s are appended where K is the smallest, non-negative
+ solution to the equation
+
+ L + 1 + K = 448 (mod 512)
+
+ 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
+ multiple of 512 bits.
+
+ Example: Suppose the original message is the bit string
+
+ 01100001 01100010 01100011 01100100 01100101
+
+ After step (a), this gives
+
+ 01100001 01100010 01100011 01100100 01100101 1
+
+ Since L = 40, the number of bits in the above is 41 and K = 407
+ "0"s are appended, making the total now 448. This gives the
+ following in hex:
+
+ 61626364 65800000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000
+
+ The 64-bit representation of L = 40 is hex 00000000 00000028.
+ Hence the final padded message is the following hex:
+
+ 61626364 65800000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000028
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 7]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+4.2. SHA-384 and SHA-512
+
+ 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:
+
+ a. "1" is appended. Example: if the original message is
+ "01010000", this is padded to "010100001".
+
+ b. K "0"s are appended where K is the smallest, non-negative
+ solution to the equation
+
+ L + 1 + K = 896 (mod 1024)
+
+ 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 multiple of 1024 bits.
+
+ Example: Suppose the original message is the bit string
+
+ 01100001 01100010 01100011 01100100 01100101
+
+ After step (a) this gives
+
+ 01100001 01100010 01100011 01100100 01100101 1
+
+ Since L = 40, the number of bits in the above is 41 and K = 855
+ "0"s are appended, making the total now 896. This gives the
+ following in hex:
+
+ 61626364 65800000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+
+ The 128-bit representation of L = 40 is hex 00000000 00000000
+ 00000000 00000028. Hence the final padded message is the
+ following hex:
+
+ 61626364 65800000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 8]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000000
+ 00000000 00000000 00000000 00000028
+
+5. Functions and Constants Used
+
+ The following subsections give the six logical functions and the
+ table of constants used in each of the hash functions.
+
+5.1. SHA-224 and SHA-256
+
+ SHA-224 and SHA-256 use six logical functions, where each function
+ operates on 32-bit words, which are represented as x, y, and z. The
+ result of each function is a new 32-bit word.
+
+ CH( x, y, z) = (x AND y) XOR ( (NOT x) AND z)
+
+ MAJ( x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+
+ BSIG0(x) = ROTR^2(x) XOR ROTR^13(x) XOR ROTR^22(x)
+
+ BSIG1(x) = ROTR^6(x) XOR ROTR^11(x) XOR ROTR^25(x)
+
+ SSIG0(x) = ROTR^7(x) XOR ROTR^18(x) XOR SHR^3(x)
+
+ SSIG1(x) = ROTR^17(x) XOR ROTR^19(x) XOR SHR^10(x)
+
+ SHA-224 and SHA-256 use the same sequence of sixty-four constant
+ 32-bit words, K0, K1, ..., K63. These words represent the first
+ thirty-two bits of the fractional parts of the cube roots of the
+ first sixty-four prime numbers. In hex, these constant words are as
+ follows (from left to right):
+
+ 428a2f98 71374491 b5c0fbcf e9b5dba5
+ 3956c25b 59f111f1 923f82a4 ab1c5ed5
+ d807aa98 12835b01 243185be 550c7dc3
+ 72be5d74 80deb1fe 9bdc06a7 c19bf174
+ e49b69c1 efbe4786 0fc19dc6 240ca1cc
+ 2de92c6f 4a7484aa 5cb0a9dc 76f988da
+ 983e5152 a831c66d b00327c8 bf597fc7
+ c6e00bf3 d5a79147 06ca6351 14292967
+ 27b70a85 2e1b2138 4d2c6dfc 53380d13
+ 650a7354 766a0abb 81c2c92e 92722c85
+ a2bfe8a1 a81a664b c24b8b70 c76c51a3
+ d192e819 d6990624 f40e3585 106aa070
+ 19a4c116 1e376c08 2748774c 34b0bcb5
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 9]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ 391c0cb3 4ed8aa4a 5b9cca4f 682e6ff3
+ 748f82ee 78a5636f 84c87814 8cc70208
+ 90befffa a4506ceb bef9a3f7 c67178f2
+
+5.2. SHA-384 and SHA-512
+
+ SHA-384 and SHA-512 each use six logical functions, where each
+ function operates on 64-bit words, which are represented as x, y, and
+ z. The result of each function is a new 64-bit word.
+
+ CH( x, y, z) = (x AND y) XOR ( (NOT x) AND z)
+
+ MAJ( x, y, z) = (x AND y) XOR (x AND z) XOR (y AND z)
+
+ BSIG0(x) = ROTR^28(x) XOR ROTR^34(x) XOR ROTR^39(x)
+
+ BSIG1(x) = ROTR^14(x) XOR ROTR^18(x) XOR ROTR^41(x)
+
+ SSIG0(x) = ROTR^1(x) XOR ROTR^8(x) XOR SHR^7(x)
+
+ SSIG1(x) = ROTR^19(x) XOR ROTR^61(x) XOR SHR^6(x)
+
+ SHA-384 and SHA-512 use the same sequence of eighty constant 64-bit
+ words, K0, K1, ... K79. These words represent the first sixty-four
+ bits of the fractional parts of the cube roots of the first eighty
+ prime numbers. In hex, these constant words are as follows (from
+ left to right):
+
+ 428a2f98d728ae22 7137449123ef65cd b5c0fbcfec4d3b2f e9b5dba58189dbbc
+ 3956c25bf348b538 59f111f1b605d019 923f82a4af194f9b ab1c5ed5da6d8118
+ d807aa98a3030242 12835b0145706fbe 243185be4ee4b28c 550c7dc3d5ffb4e2
+ 72be5d74f27b896f 80deb1fe3b1696b1 9bdc06a725c71235 c19bf174cf692694
+ e49b69c19ef14ad2 efbe4786384f25e3 0fc19dc68b8cd5b5 240ca1cc77ac9c65
+ 2de92c6f592b0275 4a7484aa6ea6e483 5cb0a9dcbd41fbd4 76f988da831153b5
+ 983e5152ee66dfab a831c66d2db43210 b00327c898fb213f bf597fc7beef0ee4
+ c6e00bf33da88fc2 d5a79147930aa725 06ca6351e003826f 142929670a0e6e70
+ 27b70a8546d22ffc 2e1b21385c26c926 4d2c6dfc5ac42aed 53380d139d95b3df
+ 650a73548baf63de 766a0abb3c77b2a8 81c2c92e47edaee6 92722c851482353b
+ a2bfe8a14cf10364 a81a664bbc423001 c24b8b70d0f89791 c76c51a30654be30
+ d192e819d6ef5218 d69906245565a910 f40e35855771202a 106aa07032bbd1b8
+ 19a4c116b8d2d0c8 1e376c085141ab53 2748774cdf8eeb99 34b0bcb5e19b48a8
+ 391c0cb3c5c95a63 4ed8aa4ae3418acb 5b9cca4f7763e373 682e6ff3d6b2b8a3
+ 748f82ee5defb2fc 78a5636f43172f60 84c87814a1f0ab72 8cc702081a6439ec
+ 90befffa23631e28 a4506cebde82bde9 bef9a3f7b2c67915 c67178f2e372532b
+ ca273eceea26619c d186b8c721c0c207 eada7dd6cde0eb1e f57d4f7fee6ed178
+ 06f067aa72176fba 0a637dc5a2c898a6 113f9804bef90dae 1b710b35131c471b
+ 28db77f523047d84 32caab7b40c72493 3c9ebe0a15c9bebc 431d67c49c100d4c
+ 4cc5d4becb3e42b6 597f299cfc657e2a 5fcb6fab3ad6faec 6c44198c4a475817
+
+
+
+Eastlake 3rd & Hansen Informational [Page 10]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+6. Computing the Message Digest
+
+ The output of each of the secure hash functions, after being applied
+ to a message of N blocks, is the hash quantity H(N). For SHA-224 and
+ SHA-256, H(i) can be considered to be eight 32-bit words, H(i)0,
+ H(i)1, ... H(i)7. For SHA-384 and SHA-512, it can be considered to
+ be eight 64-bit words, H(i)0, H(i)1, ..., H(i)7.
+
+ As described below, the hash words are initialized, modified as each
+ message block is processed, and finally concatenated after processing
+ the last block to yield the output. For SHA-256 and SHA-512, all of
+ the H(N) variables are concatenated while the SHA-224 and SHA-384
+ hashes are produced by omitting some from the final concatenation.
+
+6.1. SHA-224 and SHA-256 Initialization
+
+ For SHA-224, the initial hash value, H(0), consists of the following
+ 32-bit words in hex:
+
+ H(0)0 = c1059ed8
+ H(0)1 = 367cd507
+ H(0)2 = 3070dd17
+ H(0)3 = f70e5939
+ H(0)4 = ffc00b31
+ H(0)5 = 68581511
+ H(0)6 = 64f98fa7
+ H(0)7 = befa4fa4
+
+ For SHA-256, the initial hash value, H(0), consists of the following
+ eight 32-bit words, in hex. These words were obtained by taking the
+ first thirty-two bits of the fractional parts of the square roots of
+ the first eight prime numbers.
+
+ H(0)0 = 6a09e667
+ H(0)1 = bb67ae85
+ H(0)2 = 3c6ef372
+ H(0)3 = a54ff53a
+ H(0)4 = 510e527f
+ H(0)5 = 9b05688c
+ H(0)6 = 1f83d9ab
+ H(0)7 = 5be0cd19
+
+6.2. SHA-224 and SHA-256 Processing
+
+ SHA-224 and SHA-256 perform identical processing on messages blocks
+ and differ only in how H(0) is initialized and how they produce their
+ final output. They may be used to hash a message, M, having a length
+ of L bits, where 0 <= L < 2^64. The algorithm uses (1) a message
+
+
+
+Eastlake 3rd & Hansen Informational [Page 11]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ schedule of sixty-four 32-bit words, (2) eight working variables of
+ 32 bits each, and (3) a hash value of eight 32-bit words.
+
+ The words of the message schedule are labeled W0, W1, ..., W63. The
+ eight working variables are labeled a, b, c, d, e, f, g, and h. The
+ words of the hash value are labeled H(i)0, H(i)1, ..., H(i)7, which
+ will hold the initial hash value, H(0), replaced by each successive
+ intermediate hash value (after each message block is processed),
+ H(i), and ending with the final hash value, H(N), after all N blocks
+ are processed. They also use two temporary words, T1 and T2.
+
+ The input message is padded as described in Section 4.1 above then
+ parsed into 512-bit blocks, which are considered to be composed of 16
+ 32-bit words M(i)0, M(i)1, ..., M(i)15. The following computations
+ are then performed for each of the N message blocks. All addition is
+ performed modulo 2^32.
+
+ For i = 1 to N
+
+ 1. Prepare the message schedule W:
+ For t = 0 to 15
+ Wt = M(i)t
+ For t = 16 to 63
+ Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(t-15) + W(t-16)
+
+ 2. Initialize the working variables:
+ a = H(i-1)0
+ b = H(i-1)1
+ c = H(i-1)2
+ d = H(i-1)3
+ e = H(i-1)4
+ f = H(i-1)5
+ g = H(i-1)6
+ h = H(i-1)7
+
+ 3. Perform the main hash computation:
+ For t = 0 to 63
+ T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt
+ T2 = BSIG0(a) + MAJ(a,b,c)
+ h = g
+ g = f
+ f = e
+ e = d + T1
+ d = c
+ c = b
+ b = a
+ a = T1 + T2
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 12]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ 4. Compute the intermediate hash value H(i):
+ H(i)0 = a + H(i-1)0
+ H(i)1 = b + H(i-1)1
+ H(i)2 = c + H(i-1)2
+ H(i)3 = d + H(i-1)3
+ H(i)4 = e + H(i-1)4
+ H(i)5 = f + H(i-1)5
+ H(i)6 = g + H(i-1)6
+ H(i)7 = h + H(i-1)7
+
+ After the above computations have been sequentially performed for all
+ of the blocks in the message, the final output is calculated. For
+ SHA-256, this is the concatenation of all of H(N)0, H(N)1, through
+ H(N)7. For SHA-224, this is the concatenation of H(N)0, H(N)1,
+ through H(N)6.
+
+6.3. SHA-384 and SHA-512 Initialization
+
+ For SHA-384, the initial hash value, H(0), consists of the following
+ eight 64-bit words, in hex. These words were obtained by taking the
+ first sixty-four bits of the fractional parts of the square roots of
+ the ninth through sixteenth prime numbers.
+
+ H(0)0 = cbbb9d5dc1059ed8
+ H(0)1 = 629a292a367cd507
+ H(0)2 = 9159015a3070dd17
+ H(0)3 = 152fecd8f70e5939
+ H(0)4 = 67332667ffc00b31
+ H(0)5 = 8eb44a8768581511
+ H(0)6 = db0c2e0d64f98fa7
+ H(0)7 = 47b5481dbefa4fa4
+
+ For SHA-512, the initial hash value, H(0), consists of the following
+ eight 64-bit words, in hex. These words were obtained by taking the
+ first sixty-four bits of the fractional parts of the square roots of
+ the first eight prime numbers.
+
+ H(0)0 = 6a09e667f3bcc908
+ H(0)1 = bb67ae8584caa73b
+ H(0)2 = 3c6ef372fe94f82b
+ H(0)3 = a54ff53a5f1d36f1
+ H(0)4 = 510e527fade682d1
+ H(0)5 = 9b05688c2b3e6c1f
+ H(0)6 = 1f83d9abfb41bd6b
+ H(0)7 = 5be0cd19137e2179
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 13]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+6.4. SHA-384 and SHA-512 Processing
+
+ SHA-384 and SHA-512 perform identical processing on message blocks
+ and differ only in how H(0) is initialized and how they produce their
+ final output. They may be used to hash a message, M, having a length
+ of L bits, where 0 <= L < 2^128. The algorithm uses (1) a message
+ schedule of eighty 64-bit words, (2) eight working variables of 64
+ bits each, and (3) a hash value of eight 64-bit words.
+
+ The words of the message schedule are labeled W0, W1, ..., W79. The
+ eight working variables are labeled a, b, c, d, e, f, g, and h. The
+ words of the hash value are labeled H(i)0, H(i)1, ..., H(i)7, which
+ will hold the initial hash value, H(0), replaced by each successive
+ intermediate hash value (after each message block is processed),
+ H(i), and ending with the final hash value, H(N) after all N blocks
+ are processed.
+
+ The input message is padded as described in Section 4.2 above, then
+ parsed into 1024-bit blocks, which are considered to be composed of
+ 16 64-bit words M(i)0, M(i)1, ..., M(i)15. The following
+ computations are then performed for each of the N message blocks.
+ All addition is performed modulo 2^64.
+
+ For i = 1 to N
+
+ 1. Prepare the message schedule W:
+ For t = 0 to 15
+ Wt = M(i)t
+ For t = 16 to 79
+ Wt = SSIG1(W(t-2)) + W(t-7) + SSIG0(t-15) + W(t-16)
+
+ 2. Initialize the working variables:
+ a = H(i-1)0
+ b = H(i-1)1
+ c = H(i-1)2
+ d = H(i-1)3
+ e = H(i-1)4
+ f = H(i-1)5
+ g = H(i-1)6
+ h = H(i-1)7
+
+ 3. Perform the main hash computation:
+ For t = 0 to 79
+ T1 = h + BSIG1(e) + CH(e,f,g) + Kt + Wt
+ T2 = BSIG0(a) + MAJ(a,b,c)
+ h = g
+ g = f
+ f = e
+
+
+
+Eastlake 3rd & Hansen Informational [Page 14]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ e = d + T1
+ d = c
+ c = b
+ b = a
+ a = T1 + T2
+
+ 4. Compute the intermediate hash value H(i):
+ H(i)0 = a + H(i-1)0
+ H(i)1 = b + H(i-1)1
+ H(i)2 = c + H(i-1)2
+ H(i)3 = d + H(i-1)3
+ H(i)4 = e + H(i-1)4
+ H(i)5 = f + H(i-1)5
+ H(i)6 = g + H(i-1)6
+ H(i)7 = h + H(i-1)7
+
+ After the above computations have been sequentially performed for all
+ of the blocks in the message, the final output is calculated. For
+ SHA-512, this is the concatenation of all of H(N)0, H(N)1, through
+ H(N)7. For SHA-384, this is the concatenation of H(N)0, H(N)1,
+ through H(N)5.
+
+7. SHA-Based HMACs
+
+ HMAC is a method for computing a keyed MAC (message authentication
+ code) using a hash function as described in [RFC2104]. It uses a key
+ to mix in with the input text to produce the final hash.
+
+ Sample code is also provided, in Section 8.3 below, to perform HMAC
+ based on any of the SHA algorithms described herein. The sample code
+ found in [RFC2104] was written in terms of a specified text size.
+ Since SHA is defined in terms of an arbitrary number of bits, the
+ sample HMAC code has been written to allow the text input to HMAC to
+ have an arbitrary number of octets and bits. A fixed-length
+ interface is also provided.
+
+8. C Code for SHAs
+
+ Below is a demonstration implementation of these secure hash
+ functions in C. Section 8.1 contains the header file sha.h, which
+ declares all constants, structures, and functions used by the sha and
+ hmac functions. Section 8.2 contains the C code for sha1.c,
+ sha224-256.c, sha384-512.c, and usha.c along with sha-private.h,
+ which provides some declarations common to all the sha functions.
+ Section 8.3 contains the C code for the hmac functions. Section 8.4
+ contains a test driver to exercise the code.
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 15]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ For each of the digest length $$$, there is the following set of
+ constants, a structure, and functions:
+
+ Constants:
+ SHA$$$HashSize number of octets in the hash
+ SHA$$$HashSizeBits number of bits in the hash
+ SHA$$$_Message_Block_Size
+ number of octets used in the intermediate
+ message blocks
+ shaSuccess = 0 constant returned by each function on success
+ shaNull = 1 constant returned by each function when
+ presented with a null pointer parameter
+ shaInputTooLong = 2 constant returned by each function when the
+ input data is too long
+ shaStateError constant returned by each function when
+ SHA$$$Input is called after SHA$$$FinalBits or
+ SHA$$$Result.
+
+ Structure:
+ typedef SHA$$$Context
+ an opaque structure holding the complete state
+ for producing the hash
+
+ Functions:
+ int SHA$$$Reset(SHA$$$Context *);
+ Reset the hash context state
+ int SHA$$$Input(SHA$$$Context *, const uint8_t *octets,
+ unsigned int bytecount);
+ Incorporate bytecount octets into the hash.
+ int SHA$$$FinalBits(SHA$$$Context *, const uint8_t octet,
+ unsigned int bitcount);
+ Incorporate bitcount bits into the hash. The bits are in
+ the upper portion of the octet. SHA$$$Input() cannot be
+ called after this.
+ int SHA$$$Result(SHA$$$Context *,
+ uint8_t Message_Digest[SHA$$$HashSize]);
+ Do the final calculations on the hash and copy the value
+ into Message_Digest.
+
+ In addition, functions with the prefix USHA are provided that take a
+ SHAversion value (SHA$$$) to select the SHA function suite. They add
+ the following constants, structure, and functions:
+
+ Constants:
+ shaBadParam constant returned by USHA functions when
+ presented with a bad SHAversion (SHA$$$)
+ parameter
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 16]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ SHA$$$ SHAversion enumeration values, used by usha
+ and hmac functions to select the SHA function
+ suite
+
+ Structure:
+ typedef USHAContext
+ an opaque structure holding the complete state
+ for producing the hash
+
+ Functions:
+ int USHAReset(USHAContext *, SHAversion whichSha);
+ Reset the hash context state.
+ int USHAInput(USHAContext *,
+ const uint8_t *bytes, unsigned int bytecount);
+ Incorporate bytecount octets into the hash.
+ int USHAFinalBits(USHAContext *,
+ const uint8_t bits, unsigned int bitcount);
+ Incorporate bitcount bits into the hash.
+ int USHAResult(USHAContext *,
+ uint8_t Message_Digest[USHAMaxHashSize]);
+ Do the final calculations on the hash and copy the value
+ into Message_Digest. Octets in Message_Digest beyond
+ USHAHashSize(whichSha) are left untouched.
+ int USHAHashSize(enum SHAversion whichSha);
+ The number of octets in the given hash.
+ int USHAHashSizeBits(enum SHAversion whichSha);
+ The number of bits in the given hash.
+ int USHABlockSize(enum SHAversion whichSha);
+ The internal block size for the given hash.
+
+ The hmac functions follow the same pattern to allow any length of
+ text input to be used.
+
+ Structure:
+ typedef HMACContext an opaque structure holding the complete state
+ for producing the hash
+
+ Functions:
+ int hmacReset(HMACContext *ctx, enum SHAversion whichSha,
+ const unsigned char *key, int key_len);
+ Reset the hash context state.
+ int hmacInput(HMACContext *ctx, const unsigned char *text,
+ int text_len);
+ Incorporate text_len octets into the hash.
+ int hmacFinalBits(HMACContext *ctx, const uint8_t bits,
+ unsigned int bitcount);
+ Incorporate bitcount bits into the hash.
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 17]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ int hmacResult(HMACContext *ctx,
+ uint8_t Message_Digest[USHAMaxHashSize]);
+ Do the final calculations on the hash and copy the value
+ into Message_Digest. Octets in Message_Digest beyond
+ USHAHashSize(whichSha) are left untouched.
+
+ In addition, a combined interface is provided, similar to that shown
+ in RFC 2104, that allows a fixed-length text input to be used.
+
+ int hmac(SHAversion whichSha,
+ const unsigned char *text, int text_len,
+ const unsigned char *key, int key_len,
+ uint8_t Message_Digest[USHAMaxHashSize]);
+ Calculate the given digest for the given text and key, and
+ return the resulting hash. Octets in Message_Digest beyond
+ USHAHashSize(whichSha) are left untouched.
+
+8.1. The .h File
+
+/**************************** sha.h ****************************/
+/******************* See RFC 4634 for details ******************/
+#ifndef _SHA_H_
+#define _SHA_H_
+
+/*
+ * Description:
+ * This file implements the Secure Hash Signature Standard
+ * algorithms as defined in the National Institute of Standards
+ * and Technology Federal Information Processing Standards
+ * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+ * published on August 1, 2002, and the FIPS PUB 180-2 Change
+ * Notice published on February 28, 2004.
+ *
+ * A combined document showing all algorithms is available at
+ * http://csrc.nist.gov/publications/fips/
+ * fips180-2/fips180-2withchangenotice.pdf
+ *
+ * The five hashes are defined in these sizes:
+ * SHA-1 20 byte / 160 bit
+ * SHA-224 28 byte / 224 bit
+ * SHA-256 32 byte / 256 bit
+ * SHA-384 48 byte / 384 bit
+ * SHA-512 64 byte / 512 bit
+ */
+
+#include <stdint.h>
+/*
+ * If you do not have the ISO standard stdint.h header file, then you
+
+
+
+Eastlake 3rd & Hansen Informational [Page 18]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * must typedef the following:
+ * name meaning
+ * uint64_t unsigned 64 bit integer
+ * uint32_t unsigned 32 bit integer
+ * uint8_t unsigned 8 bit integer (i.e., unsigned char)
+ * int_least16_t integer of >= 16 bits
+ *
+ */
+
+#ifndef _SHA_enum_
+#define _SHA_enum_
+/*
+ * All SHA functions return one of these values.
+ */
+enum {
+ shaSuccess = 0,
+ shaNull, /* Null pointer parameter */
+ shaInputTooLong, /* input data too long */
+ shaStateError, /* called Input after FinalBits or Result */
+ shaBadParam /* passed a bad parameter */
+};
+#endif /* _SHA_enum_ */
+
+/*
+ * These constants hold size information for each of the SHA
+ * hashing operations
+ */
+enum {
+ SHA1_Message_Block_Size = 64, SHA224_Message_Block_Size = 64,
+ SHA256_Message_Block_Size = 64, SHA384_Message_Block_Size = 128,
+ SHA512_Message_Block_Size = 128,
+ USHA_Max_Message_Block_Size = SHA512_Message_Block_Size,
+
+ SHA1HashSize = 20, SHA224HashSize = 28, SHA256HashSize = 32,
+ SHA384HashSize = 48, SHA512HashSize = 64,
+ USHAMaxHashSize = SHA512HashSize,
+
+ SHA1HashSizeBits = 160, SHA224HashSizeBits = 224,
+ SHA256HashSizeBits = 256, SHA384HashSizeBits = 384,
+ SHA512HashSizeBits = 512, USHAMaxHashSizeBits = SHA512HashSizeBits
+};
+
+/*
+ * These constants are used in the USHA (unified sha) functions.
+ */
+typedef enum SHAversion {
+ SHA1, SHA224, SHA256, SHA384, SHA512
+} SHAversion;
+
+
+
+Eastlake 3rd & Hansen Informational [Page 19]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * This structure will hold context information for the SHA-1
+ * hashing operation.
+ */
+typedef struct SHA1Context {
+ uint32_t Intermediate_Hash[SHA1HashSize/4]; /* Message Digest */
+
+ uint32_t Length_Low; /* Message length in bits */
+ uint32_t Length_High; /* Message length in bits */
+
+ int_least16_t Message_Block_Index; /* Message_Block array index */
+ /* 512-bit message blocks */
+ uint8_t Message_Block[SHA1_Message_Block_Size];
+
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the digest corrupted? */
+} SHA1Context;
+
+/*
+ * This structure will hold context information for the SHA-256
+ * hashing operation.
+ */
+typedef struct SHA256Context {
+ uint32_t Intermediate_Hash[SHA256HashSize/4]; /* Message Digest */
+
+ uint32_t Length_Low; /* Message length in bits */
+ uint32_t Length_High; /* Message length in bits */
+
+ int_least16_t Message_Block_Index; /* Message_Block array index */
+ /* 512-bit message blocks */
+ uint8_t Message_Block[SHA256_Message_Block_Size];
+
+ int Computed; /* Is the digest computed? */
+ int Corrupted; /* Is the digest corrupted? */
+} SHA256Context;
+
+/*
+ * This structure will hold context information for the SHA-512
+ * hashing operation.
+ */
+typedef struct SHA512Context {
+#ifdef USE_32BIT_ONLY
+ uint32_t Intermediate_Hash[SHA512HashSize/4]; /* Message Digest */
+ uint32_t Length[4]; /* Message length in bits */
+#else /* !USE_32BIT_ONLY */
+ uint64_t Intermediate_Hash[SHA512HashSize/8]; /* Message Digest */
+ uint64_t Length_Low, Length_High; /* Message length in bits */
+#endif /* USE_32BIT_ONLY */
+
+
+
+Eastlake 3rd & Hansen Informational [Page 20]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ int_least16_t Message_Block_Index; /* Message_Block array index */
+ /* 1024-bit message blocks */
+ uint8_t Message_Block[SHA512_Message_Block_Size];
+
+ int Computed; /* Is the digest computed?*/
+ int Corrupted; /* Is the digest corrupted? */
+} SHA512Context;
+
+/*
+ * This structure will hold context information for the SHA-224
+ * hashing operation. It uses the SHA-256 structure for computation.
+ */
+typedef struct SHA256Context SHA224Context;
+
+/*
+ * This structure will hold context information for the SHA-384
+ * hashing operation. It uses the SHA-512 structure for computation.
+ */
+typedef struct SHA512Context SHA384Context;
+
+/*
+ * This structure holds context information for all SHA
+ * hashing operations.
+ */
+typedef struct USHAContext {
+ int whichSha; /* which SHA is being used */
+ union {
+ SHA1Context sha1Context;
+ SHA224Context sha224Context; SHA256Context sha256Context;
+ SHA384Context sha384Context; SHA512Context sha512Context;
+ } ctx;
+} USHAContext;
+
+/*
+ * This structure will hold context information for the HMAC
+ * keyed hashing operation.
+ */
+typedef struct HMACContext {
+ int whichSha; /* which SHA is being used */
+ int hashSize; /* hash size of SHA being used */
+ int blockSize; /* block size of SHA being used */
+ USHAContext shaContext; /* SHA context */
+ unsigned char k_opad[USHA_Max_Message_Block_Size];
+ /* outer padding - key XORd with opad */
+} HMACContext;
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 21]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * Function Prototypes
+ */
+
+/* SHA-1 */
+extern int SHA1Reset(SHA1Context *);
+extern int SHA1Input(SHA1Context *, const uint8_t *bytes,
+ unsigned int bytecount);
+extern int SHA1FinalBits(SHA1Context *, const uint8_t bits,
+ unsigned int bitcount);
+extern int SHA1Result(SHA1Context *,
+ uint8_t Message_Digest[SHA1HashSize]);
+
+/* SHA-224 */
+extern int SHA224Reset(SHA224Context *);
+extern int SHA224Input(SHA224Context *, const uint8_t *bytes,
+ unsigned int bytecount);
+extern int SHA224FinalBits(SHA224Context *, const uint8_t bits,
+ unsigned int bitcount);
+extern int SHA224Result(SHA224Context *,
+ uint8_t Message_Digest[SHA224HashSize]);
+
+/* SHA-256 */
+extern int SHA256Reset(SHA256Context *);
+extern int SHA256Input(SHA256Context *, const uint8_t *bytes,
+ unsigned int bytecount);
+extern int SHA256FinalBits(SHA256Context *, const uint8_t bits,
+ unsigned int bitcount);
+extern int SHA256Result(SHA256Context *,
+ uint8_t Message_Digest[SHA256HashSize]);
+
+/* SHA-384 */
+extern int SHA384Reset(SHA384Context *);
+extern int SHA384Input(SHA384Context *, const uint8_t *bytes,
+ unsigned int bytecount);
+extern int SHA384FinalBits(SHA384Context *, const uint8_t bits,
+ unsigned int bitcount);
+extern int SHA384Result(SHA384Context *,
+ uint8_t Message_Digest[SHA384HashSize]);
+
+/* SHA-512 */
+extern int SHA512Reset(SHA512Context *);
+extern int SHA512Input(SHA512Context *, const uint8_t *bytes,
+ unsigned int bytecount);
+extern int SHA512FinalBits(SHA512Context *, const uint8_t bits,
+ unsigned int bitcount);
+extern int SHA512Result(SHA512Context *,
+ uint8_t Message_Digest[SHA512HashSize]);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 22]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/* Unified SHA functions, chosen by whichSha */
+extern int USHAReset(USHAContext *, SHAversion whichSha);
+extern int USHAInput(USHAContext *,
+ const uint8_t *bytes, unsigned int bytecount);
+extern int USHAFinalBits(USHAContext *,
+ const uint8_t bits, unsigned int bitcount);
+extern int USHAResult(USHAContext *,
+ uint8_t Message_Digest[USHAMaxHashSize]);
+extern int USHABlockSize(enum SHAversion whichSha);
+extern int USHAHashSize(enum SHAversion whichSha);
+extern int USHAHashSizeBits(enum SHAversion whichSha);
+
+/*
+ * HMAC Keyed-Hashing for Message Authentication, RFC2104,
+ * for all SHAs.
+ * This interface allows a fixed-length text input to be used.
+ */
+extern int hmac(SHAversion whichSha, /* which SHA algorithm to use */
+ const unsigned char *text, /* pointer to data stream */
+ int text_len, /* length of data stream */
+ const unsigned char *key, /* pointer to authentication key */
+ int key_len, /* length of authentication key */
+ uint8_t digest[USHAMaxHashSize]); /* caller digest to fill in */
+
+/*
+ * HMAC Keyed-Hashing for Message Authentication, RFC2104,
+ * for all SHAs.
+ * This interface allows any length of text input to be used.
+ */
+extern int hmacReset(HMACContext *ctx, enum SHAversion whichSha,
+ const unsigned char *key, int key_len);
+extern int hmacInput(HMACContext *ctx, const unsigned char *text,
+ int text_len);
+
+extern int hmacFinalBits(HMACContext *ctx, const uint8_t bits,
+ unsigned int bitcount);
+extern int hmacResult(HMACContext *ctx,
+ uint8_t digest[USHAMaxHashSize]);
+
+#endif /* _SHA_H_ */
+
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 23]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+8.2. The SHA Code
+
+ This code is primarily intended as expository and could be optimized
+ further. For example, the assignment rotations through the variables
+ a, b, ..., h could be treated as a cycle and the loop unrolled,
+ rather than doing the explicit copying.
+
+ Note that there are alternative representations of the Ch() and Maj()
+ functions controlled by an ifdef.
+
+8.2.1. sha1.c
+
+/**************************** sha1.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+ * Description:
+ * This file implements the Secure Hash Signature Standard
+ * algorithms as defined in the National Institute of Standards
+ * and Technology Federal Information Processing Standards
+ * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+ * published on August 1, 2002, and the FIPS PUB 180-2 Change
+ * Notice published on February 28, 2004.
+ *
+ * A combined document showing all algorithms is available at
+ * http://csrc.nist.gov/publications/fips/
+ * fips180-2/fips180-2withchangenotice.pdf
+ *
+ * The SHA-1 algorithm produces a 160-bit message digest for a
+ * given data stream. It should take about 2**n steps to find a
+ * 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.
+ *
+ * Portability Issues:
+ * SHA-1 is defined in terms of 32-bit "words". This code
+ * uses <stdint.h> (included via "sha.h") to define 32 and 8
+ * bit unsigned integer types. If your C compiler does not
+ * support 32 bit unsigned integers, this code is not
+ * appropriate.
+ *
+ * Caveats:
+ * SHA-1 is designed to work with messages less than 2^64 bits
+ * long. This implementation uses SHA1Input() to hash the bits
+ * that are a multiple of the size of an 8-bit character, and then
+ * uses SHA1FinalBits() to hash the final few bits of the input.
+ */
+
+
+
+Eastlake 3rd & Hansen Informational [Page 24]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+#include "sha.h"
+#include "sha-private.h"
+
+/*
+ * Define the SHA1 circular left shift macro
+ */
+#define SHA1_ROTL(bits,word) \
+ (((word) << (bits)) | ((word) >> (32-(bits))))
+
+/*
+ * add "length" to the length
+ */
+static uint32_t addTemp;
+#define SHA1AddLength(context, length) \
+ (addTemp = (context)->Length_Low, \
+ (context)->Corrupted = \
+ (((context)->Length_Low += (length)) < addTemp) && \
+ (++(context)->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte);
+static void SHA1PadMessage(SHA1Context *, uint8_t Pad_Byte);
+static void SHA1ProcessMessageBlock(SHA1Context *);
+
+/*
+ * SHA1Reset
+ *
+ * Description:
+ * This function will initialize the SHA1Context in preparation
+ * for computing a new SHA1 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Reset(SHA1Context *context)
+{
+ if (!context)
+ return shaNull;
+
+ context->Length_Low = 0;
+ context->Length_High = 0;
+ context->Message_Block_Index = 0;
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 25]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ /* Initial Hash Values: FIPS-180-2 section 5.3.1 */
+ context->Intermediate_Hash[0] = 0x67452301;
+ context->Intermediate_Hash[1] = 0xEFCDAB89;
+ context->Intermediate_Hash[2] = 0x98BADCFE;
+ context->Intermediate_Hash[3] = 0x10325476;
+ context->Intermediate_Hash[4] = 0xC3D2E1F0;
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Input(SHA1Context *context,
+ const uint8_t *message_array, unsigned length)
+{
+ if (!length)
+ return shaSuccess;
+
+ if (!context || !message_array)
+ return shaNull;
+
+ if (context->Computed) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+
+
+
+Eastlake 3rd & Hansen Informational [Page 26]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ return context->Corrupted;
+
+ while (length-- && !context->Corrupted) {
+ context->Message_Block[context->Message_Block_Index++] =
+ (*message_array & 0xFF);
+
+ if (!SHA1AddLength(context, 8) &&
+ (context->Message_Block_Index == SHA1_Message_Block_Size))
+ SHA1ProcessMessageBlock(context);
+
+ message_array++;
+ }
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1FinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA1FinalBits(SHA1Context *context, const uint8_t message_bits,
+ unsigned int length)
+{
+ uint8_t masks[8] = {
+ /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+ /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+ /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+ /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+ };
+ uint8_t markbit[8] = {
+ /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+ /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+ /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 27]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+ };
+
+ if (!length)
+ return shaSuccess;
+
+ if (!context)
+ return shaNull;
+
+ if (context->Computed || (length >= 8) || (length == 0)) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ SHA1AddLength(context, length);
+ SHA1Finalize(context,
+ (uint8_t) ((message_bits & masks[length]) | markbit[length]));
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1Result
+ *
+ * Description:
+ * This function will return the 160-bit message digest into the
+ * Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 19th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA-1 hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA1Result(SHA1Context *context,
+ uint8_t Message_Digest[SHA1HashSize])
+{
+ int i;
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 28]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ if (!context || !Message_Digest)
+ return shaNull;
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ if (!context->Computed)
+ SHA1Finalize(context, 0x80);
+
+ for (i = 0; i < SHA1HashSize; ++i)
+ Message_Digest[i] = (uint8_t) (context->Intermediate_Hash[i>>2]
+ >> 8 * ( 3 - ( i & 0x03 ) ));
+
+ return shaSuccess;
+}
+
+/*
+ * SHA1Finalize
+ *
+ * Description:
+ * This helper function finishes off the digest calculations.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+static void SHA1Finalize(SHA1Context *context, uint8_t Pad_Byte)
+{
+ int i;
+ SHA1PadMessage(context, Pad_Byte);
+ /* message may be sensitive, clear it out */
+ for (i = 0; i < SHA1_Message_Block_Size; ++i)
+ context->Message_Block[i] = 0;
+ context->Length_Low = 0; /* and clear length */
+ context->Length_High = 0;
+ context->Computed = 1;
+}
+
+/*
+
+
+
+Eastlake 3rd & Hansen Informational [Page 29]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * SHA1PadMessage
+ *
+ * Description:
+ * According to the standard, the message must be padded to an
+ * even 512 bits. The first padding bit must be a '1'. The last
+ * 64 bits represent the length of the original message. All bits
+ * in between should be 0. This helper function will pad the
+ * message according to those rules by filling the Message_Block
+ * array accordingly. When it returns, it can be assumed that the
+ * message digest has been computed.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to pad
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * Nothing.
+ */
+static void SHA1PadMessage(SHA1Context *context, uint8_t Pad_Byte)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ if (context->Message_Block_Index >= (SHA1_Message_Block_Size - 8)) {
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+ while (context->Message_Block_Index < SHA1_Message_Block_Size)
+ context->Message_Block[context->Message_Block_Index++] = 0;
+
+ SHA1ProcessMessageBlock(context);
+ } else
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+
+ while (context->Message_Block_Index < (SHA1_Message_Block_Size - 8))
+ context->Message_Block[context->Message_Block_Index++] = 0;
+
+ /*
+ * Store the message length as the last 8 octets
+ */
+ context->Message_Block[56] = (uint8_t) (context->Length_High >> 24);
+ context->Message_Block[57] = (uint8_t) (context->Length_High >> 16);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 30]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ context->Message_Block[58] = (uint8_t) (context->Length_High >> 8);
+ context->Message_Block[59] = (uint8_t) (context->Length_High);
+ context->Message_Block[60] = (uint8_t) (context->Length_Low >> 24);
+ context->Message_Block[61] = (uint8_t) (context->Length_Low >> 16);
+ context->Message_Block[62] = (uint8_t) (context->Length_Low >> 8);
+ context->Message_Block[63] = (uint8_t) (context->Length_Low);
+
+ SHA1ProcessMessageBlock(context);
+}
+
+/*
+ * SHA1ProcessMessageBlock
+ *
+ * Description:
+ * This helper function will process the next 512 bits of the
+ * message stored in the Message_Block array.
+ *
+ * Parameters:
+ * None.
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the
+ * names used in the publication.
+ */
+static void SHA1ProcessMessageBlock(SHA1Context *context)
+{
+ /* Constants defined in FIPS-180-2, section 4.2.1 */
+ const uint32_t K[4] = {
+ 0x5A827999, 0x6ED9EBA1, 0x8F1BBCDC, 0xCA62C1D6
+ };
+ int t; /* Loop counter */
+ uint32_t temp; /* Temporary word value */
+ uint32_t W[80]; /* Word sequence */
+ uint32_t A, B, C, D, E; /* Word buffers */
+
+ /*
+ * Initialize the first 16 words in the array W
+ */
+ 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 + 1]) << 16;
+ W[t] |= ((uint32_t)context->Message_Block[t * 4 + 2]) << 8;
+ W[t] |= ((uint32_t)context->Message_Block[t * 4 + 3]);
+ }
+
+
+
+Eastlake 3rd & Hansen Informational [Page 31]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ for (t = 16; t < 80; t++)
+ W[t] = SHA1_ROTL(1, W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+
+ for (t = 0; t < 20; t++) {
+ temp = SHA1_ROTL(5,A) + SHA_Ch(B, C, D) + E + W[t] + K[0];
+ E = D;
+ D = C;
+ C = SHA1_ROTL(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 20; t < 40; t++) {
+ temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[1];
+ E = D;
+ D = C;
+ C = SHA1_ROTL(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 40; t < 60; t++) {
+ temp = SHA1_ROTL(5,A) + SHA_Maj(B, C, D) + E + W[t] + K[2];
+ E = D;
+ D = C;
+ C = SHA1_ROTL(30,B);
+ B = A;
+ A = temp;
+ }
+
+ for (t = 60; t < 80; t++) {
+ temp = SHA1_ROTL(5,A) + SHA_Parity(B, C, D) + E + W[t] + K[3];
+ E = D;
+ D = C;
+ C = SHA1_ROTL(30,B);
+ B = A;
+ A = temp;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+
+
+
+Eastlake 3rd & Hansen Informational [Page 32]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+
+ context->Message_Block_Index = 0;
+}
+
+8.2.2. sha224-256.c
+
+/*************************** sha224-256.c ***************************/
+/********************* See RFC 4634 for details *********************/
+/*
+ * Description:
+ * This file implements the Secure Hash Signature Standard
+ * algorithms as defined in the National Institute of Standards
+ * and Technology Federal Information Processing Standards
+ * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+ * published on August 1, 2002, and the FIPS PUB 180-2 Change
+ * Notice published on February 28, 2004.
+ *
+ * A combined document showing all algorithms is available at
+ * http://csrc.nist.gov/publications/fips/
+ * fips180-2/fips180-2withchangenotice.pdf
+ *
+ * The SHA-224 and SHA-256 algorithms produce 224-bit and 256-bit
+ * 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
+ * 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.
+ *
+ * Portability Issues:
+ * SHA-224 and SHA-256 are defined in terms of 32-bit "words".
+ * This code uses <stdint.h> (included via "sha.h") to define 32
+ * and 8 bit unsigned integer types. If your C compiler does not
+ * support 32 bit unsigned integers, this code is not
+ * appropriate.
+ *
+ * Caveats:
+ * SHA-224 and SHA-256 are designed to work with messages less
+ * than 2^64 bits long. This implementation uses SHA224/256Input()
+ * to hash the bits that are a multiple of the size of an 8-bit
+ * character, and then uses SHA224/256FinalBits() to hash the
+ * final few bits of the input.
+ */
+
+#include "sha.h"
+#include "sha-private.h"
+
+
+
+Eastlake 3rd & Hansen Informational [Page 33]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/* Define the SHA shift, rotate left and rotate right macro */
+#define SHA256_SHR(bits,word) ((word) >> (bits))
+#define SHA256_ROTL(bits,word) \
+ (((word) << (bits)) | ((word) >> (32-(bits))))
+#define SHA256_ROTR(bits,word) \
+ (((word) >> (bits)) | ((word) << (32-(bits))))
+
+/* Define the SHA SIGMA and sigma macros */
+#define SHA256_SIGMA0(word) \
+ (SHA256_ROTR( 2,word) ^ SHA256_ROTR(13,word) ^ SHA256_ROTR(22,word))
+#define SHA256_SIGMA1(word) \
+ (SHA256_ROTR( 6,word) ^ SHA256_ROTR(11,word) ^ SHA256_ROTR(25,word))
+#define SHA256_sigma0(word) \
+ (SHA256_ROTR( 7,word) ^ SHA256_ROTR(18,word) ^ SHA256_SHR( 3,word))
+#define SHA256_sigma1(word) \
+ (SHA256_ROTR(17,word) ^ SHA256_ROTR(19,word) ^ SHA256_SHR(10,word))
+
+/*
+ * add "length" to the length
+ */
+static uint32_t addTemp;
+#define SHA224_256AddLength(context, length) \
+ (addTemp = (context)->Length_Low, (context)->Corrupted = \
+ (((context)->Length_Low += (length)) < addTemp) && \
+ (++(context)->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA224_256Finalize(SHA256Context *context,
+ uint8_t Pad_Byte);
+static void SHA224_256PadMessage(SHA256Context *context,
+ uint8_t Pad_Byte);
+static void SHA224_256ProcessMessageBlock(SHA256Context *context);
+static int SHA224_256Reset(SHA256Context *context, uint32_t *H0);
+static int SHA224_256ResultN(SHA256Context *context,
+ uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 Change Notice 1 */
+static uint32_t SHA224_H0[SHA256HashSize/4] = {
+ 0xC1059ED8, 0x367CD507, 0x3070DD17, 0xF70E5939,
+ 0xFFC00B31, 0x68581511, 0x64F98FA7, 0xBEFA4FA4
+};
+
+/* Initial Hash Values: FIPS-180-2 section 5.3.2 */
+static uint32_t SHA256_H0[SHA256HashSize/4] = {
+ 0x6A09E667, 0xBB67AE85, 0x3C6EF372, 0xA54FF53A,
+ 0x510E527F, 0x9B05688C, 0x1F83D9AB, 0x5BE0CD19
+};
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 34]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * SHA224Reset
+ *
+ * Description:
+ * This function will initialize the SHA384Context in preparation
+ * for computing a new SHA224 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA224Reset(SHA224Context *context)
+{
+ return SHA224_256Reset(context, SHA224_H0);
+}
+
+/*
+ * SHA224Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA224Input(SHA224Context *context, const uint8_t *message_array,
+ unsigned int length)
+{
+ return SHA256Input(context, message_array, length);
+}
+
+/*
+ * SHA224FinalBits
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 35]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA224FinalBits( SHA224Context *context,
+ const uint8_t message_bits, unsigned int length)
+{
+ return SHA256FinalBits(context, message_bits, length);
+}
+
+/*
+ * SHA224Result
+ *
+ * Description:
+ * This function will return the 224-bit message
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 28th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA224Result(SHA224Context *context,
+ uint8_t Message_Digest[SHA224HashSize])
+{
+ return SHA224_256ResultN(context, Message_Digest, SHA224HashSize);
+}
+
+/*
+ * SHA256Reset
+
+
+
+Eastlake 3rd & Hansen Informational [Page 36]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ * Description:
+ * This function will initialize the SHA256Context in preparation
+ * for computing a new SHA256 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA256Reset(SHA256Context *context)
+{
+ return SHA224_256Reset(context, SHA256_H0);
+}
+
+/*
+ * SHA256Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA256Input(SHA256Context *context, const uint8_t *message_array,
+ unsigned int length)
+{
+ if (!length)
+ return shaSuccess;
+
+ if (!context || !message_array)
+ return shaNull;
+
+ if (context->Computed) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+
+
+
+Eastlake 3rd & Hansen Informational [Page 37]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ }
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ while (length-- && !context->Corrupted) {
+ context->Message_Block[context->Message_Block_Index++] =
+ (*message_array & 0xFF);
+
+ if (!SHA224_256AddLength(context, 8) &&
+ (context->Message_Block_Index == SHA256_Message_Block_Size))
+ SHA224_256ProcessMessageBlock(context);
+
+ message_array++;
+ }
+
+ return shaSuccess;
+
+}
+
+/*
+ * SHA256FinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA256FinalBits(SHA256Context *context,
+ const uint8_t message_bits, unsigned int length)
+{
+ uint8_t masks[8] = {
+ /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+ /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+ /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+ /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+ };
+
+
+
+Eastlake 3rd & Hansen Informational [Page 38]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ uint8_t markbit[8] = {
+ /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+ /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+ /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+ /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+ };
+
+ if (!length)
+ return shaSuccess;
+
+ if (!context)
+ return shaNull;
+
+ if ((context->Computed) || (length >= 8) || (length == 0)) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ SHA224_256AddLength(context, length);
+ SHA224_256Finalize(context, (uint8_t)
+ ((message_bits & masks[length]) | markbit[length]));
+
+ return shaSuccess;
+}
+
+/*
+ * SHA256Result
+ *
+ * Description:
+ * This function will return the 256-bit message
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 32nd element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int SHA256Result(SHA256Context *context, uint8_t Message_Digest[])
+{
+
+
+
+Eastlake 3rd & Hansen Informational [Page 39]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ return SHA224_256ResultN(context, Message_Digest, SHA256HashSize);
+}
+
+/*
+ * SHA224_256Finalize
+ *
+ * Description:
+ * This helper function finishes off the digest calculations.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+static void SHA224_256Finalize(SHA256Context *context,
+ uint8_t Pad_Byte)
+{
+ int i;
+ SHA224_256PadMessage(context, Pad_Byte);
+ /* message may be sensitive, so clear it out */
+ for (i = 0; i < SHA256_Message_Block_Size; ++i)
+ context->Message_Block[i] = 0;
+ context->Length_Low = 0; /* and clear length */
+ context->Length_High = 0;
+ context->Computed = 1;
+}
+
+/*
+ * SHA224_256PadMessage
+ *
+ * Description:
+ * According to the standard, the message must be padded to an
+ * even 512 bits. The first padding bit must be a '1'. The
+ * last 64 bits represent the length of the original message.
+ * All bits in between should be 0. This helper function will pad
+ * the message according to those rules by filling the
+ * Message_Block array accordingly. When it returns, it can be
+ * assumed that the message digest has been computed.
+ *
+ * Parameters:
+ * context: [in/out]
+
+
+
+Eastlake 3rd & Hansen Informational [Page 40]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * The context to pad
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * Nothing.
+ */
+static void SHA224_256PadMessage(SHA256Context *context,
+ uint8_t Pad_Byte)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ if (context->Message_Block_Index >= (SHA256_Message_Block_Size-8)) {
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+ while (context->Message_Block_Index < SHA256_Message_Block_Size)
+ context->Message_Block[context->Message_Block_Index++] = 0;
+ SHA224_256ProcessMessageBlock(context);
+ } else
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+
+ while (context->Message_Block_Index < (SHA256_Message_Block_Size-8))
+ context->Message_Block[context->Message_Block_Index++] = 0;
+
+ /*
+ * Store the message length as the last 8 octets
+ */
+ context->Message_Block[56] = (uint8_t)(context->Length_High >> 24);
+ context->Message_Block[57] = (uint8_t)(context->Length_High >> 16);
+ context->Message_Block[58] = (uint8_t)(context->Length_High >> 8);
+ context->Message_Block[59] = (uint8_t)(context->Length_High);
+ context->Message_Block[60] = (uint8_t)(context->Length_Low >> 24);
+ context->Message_Block[61] = (uint8_t)(context->Length_Low >> 16);
+ context->Message_Block[62] = (uint8_t)(context->Length_Low >> 8);
+ context->Message_Block[63] = (uint8_t)(context->Length_Low);
+
+ SHA224_256ProcessMessageBlock(context);
+}
+
+/*
+ * SHA224_256ProcessMessageBlock
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 41]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Description:
+ * This function will process the next 512 bits of the message
+ * stored in the Message_Block array.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the
+ * names used in the publication.
+ */
+static void SHA224_256ProcessMessageBlock(SHA256Context *context)
+{
+ /* Constants defined in FIPS-180-2, section 4.2.2 */
+ static const uint32_t K[64] = {
+ 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b,
+ 0x59f111f1, 0x923f82a4, 0xab1c5ed5, 0xd807aa98, 0x12835b01,
+ 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7,
+ 0xc19bf174, 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
+ 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, 0x983e5152,
+ 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147,
+ 0x06ca6351, 0x14292967, 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc,
+ 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
+ 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819,
+ 0xd6990624, 0xf40e3585, 0x106aa070, 0x19a4c116, 0x1e376c08,
+ 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f,
+ 0x682e6ff3, 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
+ 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
+ };
+ int t, t4; /* Loop counter */
+ uint32_t temp1, temp2; /* Temporary word value */
+ uint32_t W[64]; /* Word sequence */
+ uint32_t A, B, C, D, E, F, G, H; /* Word buffers */
+
+ /*
+ * Initialize the first 16 words in the array W
+ */
+ for (t = t4 = 0; t < 16; t++, t4 += 4)
+ W[t] = (((uint32_t)context->Message_Block[t4]) << 24) |
+ (((uint32_t)context->Message_Block[t4 + 1]) << 16) |
+ (((uint32_t)context->Message_Block[t4 + 2]) << 8) |
+ (((uint32_t)context->Message_Block[t4 + 3]));
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 42]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ for (t = 16; t < 64; t++)
+ W[t] = SHA256_sigma1(W[t-2]) + W[t-7] +
+ SHA256_sigma0(W[t-15]) + W[t-16];
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+ F = context->Intermediate_Hash[5];
+ G = context->Intermediate_Hash[6];
+ H = context->Intermediate_Hash[7];
+
+ for (t = 0; t < 64; t++) {
+ temp1 = H + SHA256_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
+ temp2 = SHA256_SIGMA0(A) + SHA_Maj(A,B,C);
+ H = G;
+ G = F;
+ F = E;
+ E = D + temp1;
+ D = C;
+ C = B;
+ B = A;
+ A = temp1 + temp2;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+ context->Intermediate_Hash[5] += F;
+ context->Intermediate_Hash[6] += G;
+ context->Intermediate_Hash[7] += H;
+
+ context->Message_Block_Index = 0;
+}
+
+/*
+ * SHA224_256Reset
+ *
+ * Description:
+ * This helper function will initialize the SHA256Context in
+ * preparation for computing a new SHA256 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 43]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * H0
+ * The initial hash value to use.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+static int SHA224_256Reset(SHA256Context *context, uint32_t *H0)
+{
+ if (!context)
+ return shaNull;
+
+ context->Length_Low = 0;
+ context->Length_High = 0;
+ context->Message_Block_Index = 0;
+
+ context->Intermediate_Hash[0] = H0[0];
+ context->Intermediate_Hash[1] = H0[1];
+ context->Intermediate_Hash[2] = H0[2];
+ context->Intermediate_Hash[3] = H0[3];
+ context->Intermediate_Hash[4] = H0[4];
+ context->Intermediate_Hash[5] = H0[5];
+ context->Intermediate_Hash[6] = H0[6];
+ context->Intermediate_Hash[7] = H0[7];
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return shaSuccess;
+}
+
+/*
+ * SHA224_256ResultN
+ *
+ * Description:
+ * This helper function will return the 224-bit or 256-bit message
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 28th/32nd element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ * HashSize: [in]
+ * The size of the hash, either 28 or 32.
+ *
+ * Returns:
+
+
+
+Eastlake 3rd & Hansen Informational [Page 44]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * sha Error Code.
+ */
+static int SHA224_256ResultN(SHA256Context *context,
+ uint8_t Message_Digest[], int HashSize)
+{
+ int i;
+
+ if (!context || !Message_Digest)
+ return shaNull;
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ if (!context->Computed)
+ SHA224_256Finalize(context, 0x80);
+
+ for (i = 0; i < HashSize; ++i)
+ Message_Digest[i] = (uint8_t)
+ (context->Intermediate_Hash[i>>2] >> 8 * ( 3 - ( i & 0x03 ) ));
+
+ return shaSuccess;
+}
+
+8.2.3. sha384-512.c
+
+/*************************** sha384-512.c ***************************/
+/********************* See RFC 4634 for details *********************/
+/*
+ * Description:
+ * This file implements the Secure Hash Signature Standard
+ * algorithms as defined in the National Institute of Standards
+ * and Technology Federal Information Processing Standards
+ * Publication (FIPS PUB) 180-1 published on April 17, 1995, 180-2
+ * published on August 1, 2002, and the FIPS PUB 180-2 Change
+ * Notice published on February 28, 2004.
+ *
+ * A combined document showing all algorithms is available at
+ * http://csrc.nist.gov/publications/fips/
+ * fips180-2/fips180-2withchangenotice.pdf
+ *
+ * The SHA-384 and SHA-512 algorithms produce 384-bit and 512-bit
+ * 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
+ * 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.
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 45]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Portability Issues:
+ * SHA-384 and SHA-512 are defined in terms of 64-bit "words",
+ * but if USE_32BIT_ONLY is #defined, this code is implemented in
+ * terms of 32-bit "words". This code uses <stdint.h> (included
+ * via "sha.h") to define the 64, 32 and 8 bit unsigned integer
+ * types. If your C compiler does not support 64 bit unsigned
+ * integers, and you do not #define USE_32BIT_ONLY, this code is
+ * not appropriate.
+ *
+ * Caveats:
+ * SHA-384 and SHA-512 are designed to work with messages less
+ * than 2^128 bits long. This implementation uses
+ * SHA384/512Input() to hash the bits that are a multiple of the
+ * size of an 8-bit character, and then uses SHA384/256FinalBits()
+ * to hash the final few bits of the input.
+ *
+ */
+
+#include "sha.h"
+#include "sha-private.h"
+
+#ifdef USE_32BIT_ONLY
+/*
+ * Define 64-bit arithmetic in terms of 32-bit arithmetic.
+ * Each 64-bit number is represented in a 2-word array.
+ * All macros are defined such that the result is the last parameter.
+ */
+
+/*
+ * Define shift, rotate left and rotate right functions
+ */
+#define SHA512_SHR(bits, word, ret) ( \
+ /* (((uint64_t)((word))) >> (bits)) */ \
+ (ret)[0] = (((bits) < 32) && ((bits) >= 0)) ? \
+ ((word)[0] >> (bits)) : 0, \
+ (ret)[1] = ((bits) > 32) ? ((word)[0] >> ((bits) - 32)) : \
+ ((bits) == 32) ? (word)[0] : \
+ ((bits) >= 0) ? \
+ (((word)[0] << (32 - (bits))) | \
+ ((word)[1] >> (bits))) : 0 )
+
+#define SHA512_SHL(bits, word, ret) ( \
+ /* (((uint64_t)(word)) << (bits)) */ \
+ (ret)[0] = ((bits) > 32) ? ((word)[1] << ((bits) - 32)) : \
+ ((bits) == 32) ? (word)[1] : \
+ ((bits) >= 0) ? \
+ (((word)[0] << (bits)) | \
+ ((word)[1] >> (32 - (bits)))) : \
+
+
+
+Eastlake 3rd & Hansen Informational [Page 46]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ 0, \
+ (ret)[1] = (((bits) < 32) && ((bits) >= 0)) ? \
+ ((word)[1] << (bits)) : 0 )
+
+/*
+ * Define 64-bit OR
+ */
+#define SHA512_OR(word1, word2, ret) ( \
+ (ret)[0] = (word1)[0] | (word2)[0], \
+ (ret)[1] = (word1)[1] | (word2)[1] )
+
+/*
+ * Define 64-bit XOR
+ */
+#define SHA512_XOR(word1, word2, ret) ( \
+ (ret)[0] = (word1)[0] ^ (word2)[0], \
+ (ret)[1] = (word1)[1] ^ (word2)[1] )
+
+/*
+ * Define 64-bit AND
+ */
+#define SHA512_AND(word1, word2, ret) ( \
+ (ret)[0] = (word1)[0] & (word2)[0], \
+ (ret)[1] = (word1)[1] & (word2)[1] )
+
+/*
+ * Define 64-bit TILDA
+ */
+#define SHA512_TILDA(word, ret) \
+ ( (ret)[0] = ~(word)[0], (ret)[1] = ~(word)[1] )
+
+/*
+ * Define 64-bit ADD
+ */
+#define SHA512_ADD(word1, word2, ret) ( \
+ (ret)[1] = (word1)[1], (ret)[1] += (word2)[1], \
+ (ret)[0] = (word1)[0] + (word2)[0] + ((ret)[1] < (word1)[1]) )
+
+/*
+ * Add the 4word value in word2 to word1.
+ */
+static uint32_t ADDTO4_temp, ADDTO4_temp2;
+#define SHA512_ADDTO4(word1, word2) ( \
+ ADDTO4_temp = (word1)[3], \
+ (word1)[3] += (word2)[3], \
+ ADDTO4_temp2 = (word1)[2], \
+ (word1)[2] += (word2)[2] + ((word1)[3] < ADDTO4_temp), \
+ ADDTO4_temp = (word1)[1], \
+
+
+
+Eastlake 3rd & Hansen Informational [Page 47]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ (word1)[1] += (word2)[1] + ((word1)[2] < ADDTO4_temp2), \
+ (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO4_temp) )
+
+/*
+ * Add the 2word value in word2 to word1.
+ */
+static uint32_t ADDTO2_temp;
+#define SHA512_ADDTO2(word1, word2) ( \
+ ADDTO2_temp = (word1)[1], \
+ (word1)[1] += (word2)[1], \
+ (word1)[0] += (word2)[0] + ((word1)[1] < ADDTO2_temp) )
+
+/*
+ * SHA rotate ((word >> bits) | (word << (64-bits)))
+ */
+static uint32_t ROTR_temp1[2], ROTR_temp2[2];
+#define SHA512_ROTR(bits, word, ret) ( \
+ SHA512_SHR((bits), (word), ROTR_temp1), \
+ SHA512_SHL(64-(bits), (word), ROTR_temp2), \
+ SHA512_OR(ROTR_temp1, ROTR_temp2, (ret)) )
+
+/*
+ * Define the SHA SIGMA and sigma macros
+ * SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word)
+ */
+static uint32_t SIGMA0_temp1[2], SIGMA0_temp2[2],
+ SIGMA0_temp3[2], SIGMA0_temp4[2];
+#define SHA512_SIGMA0(word, ret) ( \
+ SHA512_ROTR(28, (word), SIGMA0_temp1), \
+ SHA512_ROTR(34, (word), SIGMA0_temp2), \
+ SHA512_ROTR(39, (word), SIGMA0_temp3), \
+ SHA512_XOR(SIGMA0_temp2, SIGMA0_temp3, SIGMA0_temp4), \
+ SHA512_XOR(SIGMA0_temp1, SIGMA0_temp4, (ret)) )
+
+/*
+ * SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word)
+ */
+static uint32_t SIGMA1_temp1[2], SIGMA1_temp2[2],
+ SIGMA1_temp3[2], SIGMA1_temp4[2];
+#define SHA512_SIGMA1(word, ret) ( \
+ SHA512_ROTR(14, (word), SIGMA1_temp1), \
+ SHA512_ROTR(18, (word), SIGMA1_temp2), \
+ SHA512_ROTR(41, (word), SIGMA1_temp3), \
+ SHA512_XOR(SIGMA1_temp2, SIGMA1_temp3, SIGMA1_temp4), \
+ SHA512_XOR(SIGMA1_temp1, SIGMA1_temp4, (ret)) )
+
+/*
+ * (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word))
+
+
+
+Eastlake 3rd & Hansen Informational [Page 48]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ */
+static uint32_t sigma0_temp1[2], sigma0_temp2[2],
+ sigma0_temp3[2], sigma0_temp4[2];
+#define SHA512_sigma0(word, ret) ( \
+ SHA512_ROTR( 1, (word), sigma0_temp1), \
+ SHA512_ROTR( 8, (word), sigma0_temp2), \
+ SHA512_SHR( 7, (word), sigma0_temp3), \
+ SHA512_XOR(sigma0_temp2, sigma0_temp3, sigma0_temp4), \
+ SHA512_XOR(sigma0_temp1, sigma0_temp4, (ret)) )
+
+/*
+ * (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word))
+ */
+static uint32_t sigma1_temp1[2], sigma1_temp2[2],
+ sigma1_temp3[2], sigma1_temp4[2];
+#define SHA512_sigma1(word, ret) ( \
+ SHA512_ROTR(19, (word), sigma1_temp1), \
+ SHA512_ROTR(61, (word), sigma1_temp2), \
+ SHA512_SHR( 6, (word), sigma1_temp3), \
+ SHA512_XOR(sigma1_temp2, sigma1_temp3, sigma1_temp4), \
+ SHA512_XOR(sigma1_temp1, sigma1_temp4, (ret)) )
+
+#undef SHA_Ch
+#undef SHA_Maj
+
+#ifndef USE_MODIFIED_MACROS
+/*
+ * These definitions are the ones used in FIPS-180-2, section 4.1.3
+ * Ch(x,y,z) ((x & y) ^ (~x & z))
+ */
+static uint32_t Ch_temp1[2], Ch_temp2[2], Ch_temp3[2];
+#define SHA_Ch(x, y, z, ret) ( \
+ SHA512_AND(x, y, Ch_temp1), \
+ SHA512_TILDA(x, Ch_temp2), \
+ SHA512_AND(Ch_temp2, z, Ch_temp3), \
+ SHA512_XOR(Ch_temp1, Ch_temp3, (ret)) )
+/*
+ * Maj(x,y,z) (((x)&(y)) ^ ((x)&(z)) ^ ((y)&(z)))
+ */
+static uint32_t Maj_temp1[2], Maj_temp2[2],
+ Maj_temp3[2], Maj_temp4[2];
+#define SHA_Maj(x, y, z, ret) ( \
+ SHA512_AND(x, y, Maj_temp1), \
+ SHA512_AND(x, z, Maj_temp2), \
+ SHA512_AND(y, z, Maj_temp3), \
+ SHA512_XOR(Maj_temp2, Maj_temp3, Maj_temp4), \
+ SHA512_XOR(Maj_temp1, Maj_temp4, (ret)) )
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 49]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+#else /* !USE_32BIT_ONLY */
+/*
+ * These definitions are potentially faster equivalents for the ones
+ * used in FIPS-180-2, section 4.1.3.
+ * ((x & y) ^ (~x & z)) becomes
+ * ((x & (y ^ z)) ^ z)
+ */
+#define SHA_Ch(x, y, z, ret) ( \
+ (ret)[0] = (((x)[0] & ((y)[0] ^ (z)[0])) ^ (z)[0]), \
+ (ret)[1] = (((x)[1] & ((y)[1] ^ (z)[1])) ^ (z)[1]) )
+
+/*
+ * ((x & y) ^ (x & z) ^ (y & z)) becomes
+ * ((x & (y | z)) | (y & z))
+ */
+#define SHA_Maj(x, y, z, ret) ( \
+ ret[0] = (((x)[0] & ((y)[0] | (z)[0])) | ((y)[0] & (z)[0])), \
+ ret[1] = (((x)[1] & ((y)[1] | (z)[1])) | ((y)[1] & (z)[1])) )
+#endif /* USE_MODIFIED_MACROS */
+
+/*
+ * add "length" to the length
+ */
+static uint32_t addTemp[4] = { 0, 0, 0, 0 };
+#define SHA384_512AddLength(context, length) ( \
+ addTemp[3] = (length), SHA512_ADDTO4((context)->Length, addTemp), \
+ (context)->Corrupted = (((context)->Length[3] == 0) && \
+ ((context)->Length[2] == 0) && ((context)->Length[1] == 0) && \
+ ((context)->Length[0] < 8)) ? 1 : 0 )
+
+/* Local Function Prototypes */
+static void SHA384_512Finalize(SHA512Context *context,
+ uint8_t Pad_Byte);
+static void SHA384_512PadMessage(SHA512Context *context,
+ uint8_t Pad_Byte);
+static void SHA384_512ProcessMessageBlock(SHA512Context *context);
+static int SHA384_512Reset(SHA512Context *context, uint32_t H0[]);
+static int SHA384_512ResultN( SHA512Context *context,
+ uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */
+static uint32_t SHA384_H0[SHA512HashSize/4] = {
+ 0xCBBB9D5D, 0xC1059ED8, 0x629A292A, 0x367CD507, 0x9159015A,
+ 0x3070DD17, 0x152FECD8, 0xF70E5939, 0x67332667, 0xFFC00B31,
+ 0x8EB44A87, 0x68581511, 0xDB0C2E0D, 0x64F98FA7, 0x47B5481D,
+ 0xBEFA4FA4
+};
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 50]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+static uint32_t SHA512_H0[SHA512HashSize/4] = {
+ 0x6A09E667, 0xF3BCC908, 0xBB67AE85, 0x84CAA73B, 0x3C6EF372,
+ 0xFE94F82B, 0xA54FF53A, 0x5F1D36F1, 0x510E527F, 0xADE682D1,
+ 0x9B05688C, 0x2B3E6C1F, 0x1F83D9AB, 0xFB41BD6B, 0x5BE0CD19,
+ 0x137E2179
+};
+
+#else /* !USE_32BIT_ONLY */
+
+/* Define the SHA shift, rotate left and rotate right macro */
+#define SHA512_SHR(bits,word) (((uint64_t)(word)) >> (bits))
+#define SHA512_ROTR(bits,word) ((((uint64_t)(word)) >> (bits)) | \
+ (((uint64_t)(word)) << (64-(bits))))
+
+/* Define the SHA SIGMA and sigma macros */
+#define SHA512_SIGMA0(word) \
+ (SHA512_ROTR(28,word) ^ SHA512_ROTR(34,word) ^ SHA512_ROTR(39,word))
+#define SHA512_SIGMA1(word) \
+ (SHA512_ROTR(14,word) ^ SHA512_ROTR(18,word) ^ SHA512_ROTR(41,word))
+#define SHA512_sigma0(word) \
+ (SHA512_ROTR( 1,word) ^ SHA512_ROTR( 8,word) ^ SHA512_SHR( 7,word))
+#define SHA512_sigma1(word) \
+ (SHA512_ROTR(19,word) ^ SHA512_ROTR(61,word) ^ SHA512_SHR( 6,word))
+
+/*
+ * add "length" to the length
+ */
+static uint64_t addTemp;
+#define SHA384_512AddLength(context, length) \
+ (addTemp = context->Length_Low, context->Corrupted = \
+ ((context->Length_Low += length) < addTemp) && \
+ (++context->Length_High == 0) ? 1 : 0)
+
+/* Local Function Prototypes */
+static void SHA384_512Finalize(SHA512Context *context,
+ uint8_t Pad_Byte);
+static void SHA384_512PadMessage(SHA512Context *context,
+ uint8_t Pad_Byte);
+static void SHA384_512ProcessMessageBlock(SHA512Context *context);
+static int SHA384_512Reset(SHA512Context *context, uint64_t H0[]);
+static int SHA384_512ResultN(SHA512Context *context,
+ uint8_t Message_Digest[], int HashSize);
+
+/* Initial Hash Values: FIPS-180-2 sections 5.3.3 and 5.3.4 */
+static uint64_t SHA384_H0[] = {
+ 0xCBBB9D5DC1059ED8ll, 0x629A292A367CD507ll, 0x9159015A3070DD17ll,
+ 0x152FECD8F70E5939ll, 0x67332667FFC00B31ll, 0x8EB44A8768581511ll,
+ 0xDB0C2E0D64F98FA7ll, 0x47B5481DBEFA4FA4ll
+
+
+
+Eastlake 3rd & Hansen Informational [Page 51]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+};
+static uint64_t SHA512_H0[] = {
+ 0x6A09E667F3BCC908ll, 0xBB67AE8584CAA73Bll, 0x3C6EF372FE94F82Bll,
+ 0xA54FF53A5F1D36F1ll, 0x510E527FADE682D1ll, 0x9B05688C2B3E6C1Fll,
+ 0x1F83D9ABFB41BD6Bll, 0x5BE0CD19137E2179ll
+};
+
+#endif /* USE_32BIT_ONLY */
+
+/*
+ * SHA384Reset
+ *
+ * Description:
+ * This function will initialize the SHA384Context in preparation
+ * for computing a new SHA384 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA384Reset(SHA384Context *context)
+{
+ return SHA384_512Reset(context, SHA384_H0);
+}
+
+/*
+ * SHA384Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 52]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ */
+int SHA384Input(SHA384Context *context,
+ const uint8_t *message_array, unsigned int length)
+{
+ return SHA512Input(context, message_array, length);
+}
+
+/*
+ * SHA384FinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA384FinalBits(SHA384Context *context,
+ const uint8_t message_bits, unsigned int length)
+{
+ return SHA512FinalBits(context, message_bits, length);
+}
+
+/*
+ * SHA384Result
+ *
+ * Description:
+ * This function will return the 384-bit message
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 48th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 53]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA384Result(SHA384Context *context,
+ uint8_t Message_Digest[SHA384HashSize])
+{
+ return SHA384_512ResultN(context, Message_Digest, SHA384HashSize);
+}
+
+/*
+ * SHA512Reset
+ *
+ * Description:
+ * This function will initialize the SHA512Context in preparation
+ * for computing a new SHA512 message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA512Reset(SHA512Context *context)
+{
+ return SHA384_512Reset(context, SHA512_H0);
+}
+
+/*
+ * SHA512Input
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 54]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ */
+int SHA512Input(SHA512Context *context,
+ const uint8_t *message_array,
+ unsigned int length)
+{
+ if (!length)
+ return shaSuccess;
+
+ if (!context || !message_array)
+ return shaNull;
+
+ if (context->Computed) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ while (length-- && !context->Corrupted) {
+ context->Message_Block[context->Message_Block_Index++] =
+ (*message_array & 0xFF);
+
+ if (!SHA384_512AddLength(context, 8) &&
+ (context->Message_Block_Index == SHA512_Message_Block_Size))
+ SHA384_512ProcessMessageBlock(context);
+
+ message_array++;
+ }
+
+ return shaSuccess;
+}
+
+/*
+ * SHA512FinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+
+
+
+Eastlake 3rd & Hansen Informational [Page 55]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int SHA512FinalBits(SHA512Context *context,
+ const uint8_t message_bits, unsigned int length)
+{
+ uint8_t masks[8] = {
+ /* 0 0b00000000 */ 0x00, /* 1 0b10000000 */ 0x80,
+ /* 2 0b11000000 */ 0xC0, /* 3 0b11100000 */ 0xE0,
+ /* 4 0b11110000 */ 0xF0, /* 5 0b11111000 */ 0xF8,
+ /* 6 0b11111100 */ 0xFC, /* 7 0b11111110 */ 0xFE
+ };
+ uint8_t markbit[8] = {
+ /* 0 0b10000000 */ 0x80, /* 1 0b01000000 */ 0x40,
+ /* 2 0b00100000 */ 0x20, /* 3 0b00010000 */ 0x10,
+ /* 4 0b00001000 */ 0x08, /* 5 0b00000100 */ 0x04,
+ /* 6 0b00000010 */ 0x02, /* 7 0b00000001 */ 0x01
+ };
+
+ if (!length)
+ return shaSuccess;
+
+ if (!context)
+ return shaNull;
+
+ if ((context->Computed) || (length >= 8) || (length == 0)) {
+ context->Corrupted = shaStateError;
+ return shaStateError;
+ }
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ SHA384_512AddLength(context, length);
+ SHA384_512Finalize(context, (uint8_t)
+ ((message_bits & masks[length]) | markbit[length]));
+
+ return shaSuccess;
+}
+
+/*
+ * SHA384_512Finalize
+ *
+ * Description:
+ * This helper function finishes off the digest calculations.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 56]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+static void SHA384_512Finalize(SHA512Context *context,
+ uint8_t Pad_Byte)
+{
+ int_least16_t i;
+ SHA384_512PadMessage(context, Pad_Byte);
+ /* message may be sensitive, clear it out */
+ for (i = 0; i < SHA512_Message_Block_Size; ++i)
+ context->Message_Block[i] = 0;
+#ifdef USE_32BIT_ONLY /* and clear length */
+ context->Length[0] = context->Length[1] = 0;
+ context->Length[2] = context->Length[3] = 0;
+#else /* !USE_32BIT_ONLY */
+ context->Length_Low = 0;
+ context->Length_High = 0;
+#endif /* USE_32BIT_ONLY */
+ context->Computed = 1;
+}
+
+/*
+ * SHA512Result
+ *
+ * Description:
+ * This function will return the 512-bit message
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 64th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+
+
+
+Eastlake 3rd & Hansen Informational [Page 57]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * sha Error Code.
+ *
+ */
+int SHA512Result(SHA512Context *context,
+ uint8_t Message_Digest[SHA512HashSize])
+{
+ return SHA384_512ResultN(context, Message_Digest, SHA512HashSize);
+}
+
+/*
+ * SHA384_512PadMessage
+ *
+ * Description:
+ * According to the standard, the message must be padded to an
+ * even 1024 bits. The first padding bit must be a '1'. The
+ * last 128 bits represent the length of the original message.
+ * All bits in between should be 0. This helper function will
+ * pad the message according to those rules by filling the
+ * Message_Block array accordingly. When it returns, it can be
+ * assumed that the message digest has been computed.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to pad
+ * Pad_Byte: [in]
+ * The last byte to add to the digest before the 0-padding
+ * and length. This will contain the last bits of the message
+ * followed by another single bit. If the message was an
+ * exact multiple of 8-bits long, Pad_Byte will be 0x80.
+ *
+ * Returns:
+ * Nothing.
+ *
+ */
+static void SHA384_512PadMessage(SHA512Context *context,
+ uint8_t Pad_Byte)
+{
+ /*
+ * Check to see if the current message block is too small to hold
+ * the initial padding bits and length. If so, we will pad the
+ * block, process it, and then continue padding into a second
+ * block.
+ */
+ if (context->Message_Block_Index >= (SHA512_Message_Block_Size-16)) {
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+ while (context->Message_Block_Index < SHA512_Message_Block_Size)
+ context->Message_Block[context->Message_Block_Index++] = 0;
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 58]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ SHA384_512ProcessMessageBlock(context);
+ } else
+ context->Message_Block[context->Message_Block_Index++] = Pad_Byte;
+
+ while (context->Message_Block_Index < (SHA512_Message_Block_Size-16))
+ context->Message_Block[context->Message_Block_Index++] = 0;
+
+ /*
+ * Store the message length as the last 16 octets
+ */
+#ifdef USE_32BIT_ONLY
+ context->Message_Block[112] = (uint8_t)(context->Length[0] >> 24);
+ context->Message_Block[113] = (uint8_t)(context->Length[0] >> 16);
+ context->Message_Block[114] = (uint8_t)(context->Length[0] >> 8);
+ context->Message_Block[115] = (uint8_t)(context->Length[0]);
+ context->Message_Block[116] = (uint8_t)(context->Length[1] >> 24);
+ context->Message_Block[117] = (uint8_t)(context->Length[1] >> 16);
+ context->Message_Block[118] = (uint8_t)(context->Length[1] >> 8);
+ context->Message_Block[119] = (uint8_t)(context->Length[1]);
+
+ context->Message_Block[120] = (uint8_t)(context->Length[2] >> 24);
+ context->Message_Block[121] = (uint8_t)(context->Length[2] >> 16);
+ context->Message_Block[122] = (uint8_t)(context->Length[2] >> 8);
+ context->Message_Block[123] = (uint8_t)(context->Length[2]);
+ context->Message_Block[124] = (uint8_t)(context->Length[3] >> 24);
+ context->Message_Block[125] = (uint8_t)(context->Length[3] >> 16);
+ context->Message_Block[126] = (uint8_t)(context->Length[3] >> 8);
+ context->Message_Block[127] = (uint8_t)(context->Length[3]);
+#else /* !USE_32BIT_ONLY */
+ context->Message_Block[112] = (uint8_t)(context->Length_High >> 56);
+ context->Message_Block[113] = (uint8_t)(context->Length_High >> 48);
+ context->Message_Block[114] = (uint8_t)(context->Length_High >> 40);
+ context->Message_Block[115] = (uint8_t)(context->Length_High >> 32);
+ context->Message_Block[116] = (uint8_t)(context->Length_High >> 24);
+ context->Message_Block[117] = (uint8_t)(context->Length_High >> 16);
+ context->Message_Block[118] = (uint8_t)(context->Length_High >> 8);
+ context->Message_Block[119] = (uint8_t)(context->Length_High);
+
+ context->Message_Block[120] = (uint8_t)(context->Length_Low >> 56);
+ context->Message_Block[121] = (uint8_t)(context->Length_Low >> 48);
+ context->Message_Block[122] = (uint8_t)(context->Length_Low >> 40);
+ context->Message_Block[123] = (uint8_t)(context->Length_Low >> 32);
+ context->Message_Block[124] = (uint8_t)(context->Length_Low >> 24);
+ context->Message_Block[125] = (uint8_t)(context->Length_Low >> 16);
+ context->Message_Block[126] = (uint8_t)(context->Length_Low >> 8);
+ context->Message_Block[127] = (uint8_t)(context->Length_Low);
+#endif /* USE_32BIT_ONLY */
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 59]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ SHA384_512ProcessMessageBlock(context);
+}
+
+/*
+ * SHA384_512ProcessMessageBlock
+ *
+ * Description:
+ * This helper function will process the next 1024 bits of the
+ * message stored in the Message_Block array.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ *
+ * Returns:
+ * Nothing.
+ *
+ * Comments:
+ * Many of the variable names in this code, especially the
+ * single character names, were used because those were the
+ * names used in the publication.
+ *
+ *
+ */
+static void SHA384_512ProcessMessageBlock(SHA512Context *context)
+{
+ /* Constants defined in FIPS-180-2, section 4.2.3 */
+#ifdef USE_32BIT_ONLY
+ static const uint32_t K[80*2] = {
+ 0x428A2F98, 0xD728AE22, 0x71374491, 0x23EF65CD, 0xB5C0FBCF,
+ 0xEC4D3B2F, 0xE9B5DBA5, 0x8189DBBC, 0x3956C25B, 0xF348B538,
+ 0x59F111F1, 0xB605D019, 0x923F82A4, 0xAF194F9B, 0xAB1C5ED5,
+ 0xDA6D8118, 0xD807AA98, 0xA3030242, 0x12835B01, 0x45706FBE,
+ 0x243185BE, 0x4EE4B28C, 0x550C7DC3, 0xD5FFB4E2, 0x72BE5D74,
+ 0xF27B896F, 0x80DEB1FE, 0x3B1696B1, 0x9BDC06A7, 0x25C71235,
+ 0xC19BF174, 0xCF692694, 0xE49B69C1, 0x9EF14AD2, 0xEFBE4786,
+ 0x384F25E3, 0x0FC19DC6, 0x8B8CD5B5, 0x240CA1CC, 0x77AC9C65,
+ 0x2DE92C6F, 0x592B0275, 0x4A7484AA, 0x6EA6E483, 0x5CB0A9DC,
+ 0xBD41FBD4, 0x76F988DA, 0x831153B5, 0x983E5152, 0xEE66DFAB,
+ 0xA831C66D, 0x2DB43210, 0xB00327C8, 0x98FB213F, 0xBF597FC7,
+ 0xBEEF0EE4, 0xC6E00BF3, 0x3DA88FC2, 0xD5A79147, 0x930AA725,
+ 0x06CA6351, 0xE003826F, 0x14292967, 0x0A0E6E70, 0x27B70A85,
+ 0x46D22FFC, 0x2E1B2138, 0x5C26C926, 0x4D2C6DFC, 0x5AC42AED,
+ 0x53380D13, 0x9D95B3DF, 0x650A7354, 0x8BAF63DE, 0x766A0ABB,
+ 0x3C77B2A8, 0x81C2C92E, 0x47EDAEE6, 0x92722C85, 0x1482353B,
+ 0xA2BFE8A1, 0x4CF10364, 0xA81A664B, 0xBC423001, 0xC24B8B70,
+ 0xD0F89791, 0xC76C51A3, 0x0654BE30, 0xD192E819, 0xD6EF5218,
+ 0xD6990624, 0x5565A910, 0xF40E3585, 0x5771202A, 0x106AA070,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 60]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ 0x32BBD1B8, 0x19A4C116, 0xB8D2D0C8, 0x1E376C08, 0x5141AB53,
+ 0x2748774C, 0xDF8EEB99, 0x34B0BCB5, 0xE19B48A8, 0x391C0CB3,
+ 0xC5C95A63, 0x4ED8AA4A, 0xE3418ACB, 0x5B9CCA4F, 0x7763E373,
+ 0x682E6FF3, 0xD6B2B8A3, 0x748F82EE, 0x5DEFB2FC, 0x78A5636F,
+ 0x43172F60, 0x84C87814, 0xA1F0AB72, 0x8CC70208, 0x1A6439EC,
+ 0x90BEFFFA, 0x23631E28, 0xA4506CEB, 0xDE82BDE9, 0xBEF9A3F7,
+ 0xB2C67915, 0xC67178F2, 0xE372532B, 0xCA273ECE, 0xEA26619C,
+ 0xD186B8C7, 0x21C0C207, 0xEADA7DD6, 0xCDE0EB1E, 0xF57D4F7F,
+ 0xEE6ED178, 0x06F067AA, 0x72176FBA, 0x0A637DC5, 0xA2C898A6,
+ 0x113F9804, 0xBEF90DAE, 0x1B710B35, 0x131C471B, 0x28DB77F5,
+ 0x23047D84, 0x32CAAB7B, 0x40C72493, 0x3C9EBE0A, 0x15C9BEBC,
+ 0x431D67C4, 0x9C100D4C, 0x4CC5D4BE, 0xCB3E42B6, 0x597F299C,
+ 0xFC657E2A, 0x5FCB6FAB, 0x3AD6FAEC, 0x6C44198C, 0x4A475817
+ };
+ int t, t2, t8; /* Loop counter */
+ uint32_t temp1[2], temp2[2], /* Temporary word values */
+ temp3[2], temp4[2], temp5[2];
+ uint32_t W[2*80]; /* Word sequence */
+ uint32_t A[2], B[2], C[2], D[2], /* Word buffers */
+ E[2], F[2], G[2], H[2];
+
+ /* Initialize the first 16 words in the array W */
+ for (t = t2 = t8 = 0; t < 16; t++, t8 += 8) {
+ W[t2++] = ((((uint32_t)context->Message_Block[t8 ])) << 24) |
+ ((((uint32_t)context->Message_Block[t8 + 1])) << 16) |
+ ((((uint32_t)context->Message_Block[t8 + 2])) << 8) |
+ ((((uint32_t)context->Message_Block[t8 + 3])));
+ W[t2++] = ((((uint32_t)context->Message_Block[t8 + 4])) << 24) |
+ ((((uint32_t)context->Message_Block[t8 + 5])) << 16) |
+ ((((uint32_t)context->Message_Block[t8 + 6])) << 8) |
+ ((((uint32_t)context->Message_Block[t8 + 7])));
+ }
+
+ for (t = 16; t < 80; t++, t2 += 2) {
+ /* W[t] = SHA512_sigma1(W[t-2]) + W[t-7] +
+ SHA512_sigma0(W[t-15]) + W[t-16]; */
+ uint32_t *Wt2 = &W[t2-2*2];
+ uint32_t *Wt7 = &W[t2-7*2];
+ uint32_t *Wt15 = &W[t2-15*2];
+ uint32_t *Wt16 = &W[t2-16*2];
+ SHA512_sigma1(Wt2, temp1);
+ SHA512_ADD(temp1, Wt7, temp2);
+ SHA512_sigma0(Wt15, temp1);
+ SHA512_ADD(temp1, Wt16, temp3);
+ SHA512_ADD(temp2, temp3, &W[t2]);
+ }
+
+ A[0] = context->Intermediate_Hash[0];
+
+
+
+Eastlake 3rd & Hansen Informational [Page 61]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ A[1] = context->Intermediate_Hash[1];
+ B[0] = context->Intermediate_Hash[2];
+ B[1] = context->Intermediate_Hash[3];
+ C[0] = context->Intermediate_Hash[4];
+ C[1] = context->Intermediate_Hash[5];
+ D[0] = context->Intermediate_Hash[6];
+ D[1] = context->Intermediate_Hash[7];
+ E[0] = context->Intermediate_Hash[8];
+ E[1] = context->Intermediate_Hash[9];
+ F[0] = context->Intermediate_Hash[10];
+ F[1] = context->Intermediate_Hash[11];
+ G[0] = context->Intermediate_Hash[12];
+ G[1] = context->Intermediate_Hash[13];
+ H[0] = context->Intermediate_Hash[14];
+ H[1] = context->Intermediate_Hash[15];
+
+ for (t = t2 = 0; t < 80; t++, t2 += 2) {
+ /*
+ * temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
+ */
+ SHA512_SIGMA1(E,temp1);
+ SHA512_ADD(H, temp1, temp2);
+ SHA_Ch(E,F,G,temp3);
+ SHA512_ADD(temp2, temp3, temp4);
+ SHA512_ADD(&K[t2], &W[t2], temp5);
+ SHA512_ADD(temp4, temp5, temp1);
+ /*
+ * temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C);
+ */
+ SHA512_SIGMA0(A,temp3);
+ SHA_Maj(A,B,C,temp4);
+ SHA512_ADD(temp3, temp4, temp2);
+ H[0] = G[0]; H[1] = G[1];
+ G[0] = F[0]; G[1] = F[1];
+ F[0] = E[0]; F[1] = E[1];
+ SHA512_ADD(D, temp1, E);
+ D[0] = C[0]; D[1] = C[1];
+ C[0] = B[0]; C[1] = B[1];
+ B[0] = A[0]; B[1] = A[1];
+ SHA512_ADD(temp1, temp2, A);
+ }
+
+ SHA512_ADDTO2(&context->Intermediate_Hash[0], A);
+ SHA512_ADDTO2(&context->Intermediate_Hash[2], B);
+ SHA512_ADDTO2(&context->Intermediate_Hash[4], C);
+ SHA512_ADDTO2(&context->Intermediate_Hash[6], D);
+ SHA512_ADDTO2(&context->Intermediate_Hash[8], E);
+ SHA512_ADDTO2(&context->Intermediate_Hash[10], F);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 62]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ SHA512_ADDTO2(&context->Intermediate_Hash[12], G);
+ SHA512_ADDTO2(&context->Intermediate_Hash[14], H);
+
+#else /* !USE_32BIT_ONLY */
+ static const uint64_t K[80] = {
+ 0x428A2F98D728AE22ll, 0x7137449123EF65CDll, 0xB5C0FBCFEC4D3B2Fll,
+ 0xE9B5DBA58189DBBCll, 0x3956C25BF348B538ll, 0x59F111F1B605D019ll,
+ 0x923F82A4AF194F9Bll, 0xAB1C5ED5DA6D8118ll, 0xD807AA98A3030242ll,
+ 0x12835B0145706FBEll, 0x243185BE4EE4B28Cll, 0x550C7DC3D5FFB4E2ll,
+ 0x72BE5D74F27B896Fll, 0x80DEB1FE3B1696B1ll, 0x9BDC06A725C71235ll,
+ 0xC19BF174CF692694ll, 0xE49B69C19EF14AD2ll, 0xEFBE4786384F25E3ll,
+ 0x0FC19DC68B8CD5B5ll, 0x240CA1CC77AC9C65ll, 0x2DE92C6F592B0275ll,
+ 0x4A7484AA6EA6E483ll, 0x5CB0A9DCBD41FBD4ll, 0x76F988DA831153B5ll,
+ 0x983E5152EE66DFABll, 0xA831C66D2DB43210ll, 0xB00327C898FB213Fll,
+ 0xBF597FC7BEEF0EE4ll, 0xC6E00BF33DA88FC2ll, 0xD5A79147930AA725ll,
+ 0x06CA6351E003826Fll, 0x142929670A0E6E70ll, 0x27B70A8546D22FFCll,
+ 0x2E1B21385C26C926ll, 0x4D2C6DFC5AC42AEDll, 0x53380D139D95B3DFll,
+ 0x650A73548BAF63DEll, 0x766A0ABB3C77B2A8ll, 0x81C2C92E47EDAEE6ll,
+ 0x92722C851482353Bll, 0xA2BFE8A14CF10364ll, 0xA81A664BBC423001ll,
+ 0xC24B8B70D0F89791ll, 0xC76C51A30654BE30ll, 0xD192E819D6EF5218ll,
+ 0xD69906245565A910ll, 0xF40E35855771202All, 0x106AA07032BBD1B8ll,
+ 0x19A4C116B8D2D0C8ll, 0x1E376C085141AB53ll, 0x2748774CDF8EEB99ll,
+ 0x34B0BCB5E19B48A8ll, 0x391C0CB3C5C95A63ll, 0x4ED8AA4AE3418ACBll,
+ 0x5B9CCA4F7763E373ll, 0x682E6FF3D6B2B8A3ll, 0x748F82EE5DEFB2FCll,
+ 0x78A5636F43172F60ll, 0x84C87814A1F0AB72ll, 0x8CC702081A6439ECll,
+ 0x90BEFFFA23631E28ll, 0xA4506CEBDE82BDE9ll, 0xBEF9A3F7B2C67915ll,
+ 0xC67178F2E372532Bll, 0xCA273ECEEA26619Cll, 0xD186B8C721C0C207ll,
+ 0xEADA7DD6CDE0EB1Ell, 0xF57D4F7FEE6ED178ll, 0x06F067AA72176FBAll,
+ 0x0A637DC5A2C898A6ll, 0x113F9804BEF90DAEll, 0x1B710B35131C471Bll,
+ 0x28DB77F523047D84ll, 0x32CAAB7B40C72493ll, 0x3C9EBE0A15C9BEBCll,
+ 0x431D67C49C100D4Cll, 0x4CC5D4BECB3E42B6ll, 0x597F299CFC657E2All,
+ 0x5FCB6FAB3AD6FAECll, 0x6C44198C4A475817ll
+ };
+ int t, t8; /* Loop counter */
+ uint64_t temp1, temp2; /* Temporary word value */
+ uint64_t W[80]; /* Word sequence */
+ uint64_t A, B, C, D, E, F, G, H; /* Word buffers */
+
+ /*
+ * Initialize the first 16 words in the array W
+ */
+ for (t = t8 = 0; t < 16; t++, t8 += 8)
+ W[t] = ((uint64_t)(context->Message_Block[t8 ]) << 56) |
+ ((uint64_t)(context->Message_Block[t8 + 1]) << 48) |
+ ((uint64_t)(context->Message_Block[t8 + 2]) << 40) |
+ ((uint64_t)(context->Message_Block[t8 + 3]) << 32) |
+ ((uint64_t)(context->Message_Block[t8 + 4]) << 24) |
+ ((uint64_t)(context->Message_Block[t8 + 5]) << 16) |
+
+
+
+Eastlake 3rd & Hansen Informational [Page 63]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ ((uint64_t)(context->Message_Block[t8 + 6]) << 8) |
+ ((uint64_t)(context->Message_Block[t8 + 7]));
+
+ for (t = 16; t < 80; t++)
+ W[t] = SHA512_sigma1(W[t-2]) + W[t-7] +
+ SHA512_sigma0(W[t-15]) + W[t-16];
+
+ A = context->Intermediate_Hash[0];
+ B = context->Intermediate_Hash[1];
+ C = context->Intermediate_Hash[2];
+ D = context->Intermediate_Hash[3];
+ E = context->Intermediate_Hash[4];
+ F = context->Intermediate_Hash[5];
+ G = context->Intermediate_Hash[6];
+ H = context->Intermediate_Hash[7];
+
+ for (t = 0; t < 80; t++) {
+ temp1 = H + SHA512_SIGMA1(E) + SHA_Ch(E,F,G) + K[t] + W[t];
+ temp2 = SHA512_SIGMA0(A) + SHA_Maj(A,B,C);
+ H = G;
+ G = F;
+ F = E;
+ E = D + temp1;
+ D = C;
+ C = B;
+ B = A;
+ A = temp1 + temp2;
+ }
+
+ context->Intermediate_Hash[0] += A;
+ context->Intermediate_Hash[1] += B;
+ context->Intermediate_Hash[2] += C;
+ context->Intermediate_Hash[3] += D;
+ context->Intermediate_Hash[4] += E;
+ context->Intermediate_Hash[5] += F;
+ context->Intermediate_Hash[6] += G;
+ context->Intermediate_Hash[7] += H;
+#endif /* USE_32BIT_ONLY */
+
+ context->Message_Block_Index = 0;
+}
+
+/*
+ * SHA384_512Reset
+ *
+ * Description:
+ * This helper function will initialize the SHA512Context in
+ * preparation for computing a new SHA384 or SHA512 message
+
+
+
+Eastlake 3rd & Hansen Informational [Page 64]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ * H0
+ * The initial hash value to use.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+#ifdef USE_32BIT_ONLY
+static int SHA384_512Reset(SHA512Context *context, uint32_t H0[])
+#else /* !USE_32BIT_ONLY */
+static int SHA384_512Reset(SHA512Context *context, uint64_t H0[])
+#endif /* USE_32BIT_ONLY */
+{
+ int i;
+ if (!context)
+ return shaNull;
+
+ context->Message_Block_Index = 0;
+
+#ifdef USE_32BIT_ONLY
+ context->Length[0] = context->Length[1] = 0;
+ context->Length[2] = context->Length[3] = 0;
+
+ for (i = 0; i < SHA512HashSize/4; i++)
+ context->Intermediate_Hash[i] = H0[i];
+#else /* !USE_32BIT_ONLY */
+ context->Length_High = context->Length_Low = 0;
+
+ for (i = 0; i < SHA512HashSize/8; i++)
+ context->Intermediate_Hash[i] = H0[i];
+#endif /* USE_32BIT_ONLY */
+
+ context->Computed = 0;
+ context->Corrupted = 0;
+
+ return shaSuccess;
+}
+
+/*
+ * SHA384_512ResultN
+ *
+ * Description:
+ * This helper function will return the 384-bit or 512-bit message
+
+
+
+Eastlake 3rd & Hansen Informational [Page 65]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * digest into the Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 48th/64th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ * HashSize: [in]
+ * The size of the hash, either 48 or 64.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+static int SHA384_512ResultN(SHA512Context *context,
+ uint8_t Message_Digest[], int HashSize)
+{
+ int i;
+
+#ifdef USE_32BIT_ONLY
+ int i2;
+#endif /* USE_32BIT_ONLY */
+
+ if (!context || !Message_Digest)
+ return shaNull;
+
+ if (context->Corrupted)
+ return context->Corrupted;
+
+ if (!context->Computed)
+ SHA384_512Finalize(context, 0x80);
+
+#ifdef USE_32BIT_ONLY
+ for (i = i2 = 0; i < HashSize; ) {
+ Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>24);
+ Message_Digest[i++]=(uint8_t)(context->Intermediate_Hash[i2]>>16);
+ 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]>>24);
+ 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++]);
+ }
+#else /* !USE_32BIT_ONLY */
+ for (i = 0; i < HashSize; ++i)
+ Message_Digest[i] = (uint8_t)
+
+
+
+Eastlake 3rd & Hansen Informational [Page 66]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ (context->Intermediate_Hash[i>>3] >> 8 * ( 7 - ( i % 8 ) ));
+#endif /* USE_32BIT_ONLY */
+
+ return shaSuccess;
+}
+
+8.2.4. usha.c
+
+/**************************** usha.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+ * Description:
+ * This file implements a unified interface to the SHA algorithms.
+ */
+
+#include "sha.h"
+
+/*
+ * USHAReset
+ *
+ * Description:
+ * This function will initialize the SHA Context in preparation
+ * for computing a new SHA message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ * whichSha: [in]
+ * Selects which SHA reset to call
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int USHAReset(USHAContext *ctx, enum SHAversion whichSha)
+{
+ if (ctx) {
+ ctx->whichSha = whichSha;
+ switch (whichSha) {
+ case SHA1: return SHA1Reset((SHA1Context*)&ctx->ctx);
+ case SHA224: return SHA224Reset((SHA224Context*)&ctx->ctx);
+ case SHA256: return SHA256Reset((SHA256Context*)&ctx->ctx);
+ case SHA384: return SHA384Reset((SHA384Context*)&ctx->ctx);
+ case SHA512: return SHA512Reset((SHA512Context*)&ctx->ctx);
+ default: return shaBadParam;
+ }
+ } else {
+ return shaNull;
+
+
+
+Eastlake 3rd & Hansen Informational [Page 67]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ }
+}
+
+/*
+ * USHAInput
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int USHAInput(USHAContext *ctx,
+ const uint8_t *bytes, unsigned int bytecount)
+{
+ if (ctx) {
+ switch (ctx->whichSha) {
+ case SHA1:
+ return SHA1Input((SHA1Context*)&ctx->ctx, bytes, bytecount);
+ case SHA224:
+ return SHA224Input((SHA224Context*)&ctx->ctx, bytes,
+ bytecount);
+ case SHA256:
+ return SHA256Input((SHA256Context*)&ctx->ctx, bytes,
+ bytecount);
+ case SHA384:
+ return SHA384Input((SHA384Context*)&ctx->ctx, bytes,
+ bytecount);
+ case SHA512:
+ return SHA512Input((SHA512Context*)&ctx->ctx, bytes,
+ bytecount);
+ default: return shaBadParam;
+ }
+ } else {
+ return shaNull;
+ }
+}
+
+
+
+Eastlake 3rd & Hansen Informational [Page 68]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * USHAFinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The SHA context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int USHAFinalBits(USHAContext *ctx,
+ const uint8_t bits, unsigned int bitcount)
+{
+ if (ctx) {
+ switch (ctx->whichSha) {
+ case SHA1:
+ return SHA1FinalBits((SHA1Context*)&ctx->ctx, bits, bitcount);
+ case SHA224:
+ return SHA224FinalBits((SHA224Context*)&ctx->ctx, bits,
+ bitcount);
+ case SHA256:
+ return SHA256FinalBits((SHA256Context*)&ctx->ctx, bits,
+ bitcount);
+ case SHA384:
+ return SHA384FinalBits((SHA384Context*)&ctx->ctx, bits,
+ bitcount);
+ case SHA512:
+ return SHA512FinalBits((SHA512Context*)&ctx->ctx, bits,
+ bitcount);
+ default: return shaBadParam;
+ }
+ } else {
+ return shaNull;
+ }
+}
+
+/*
+ * USHAResult
+ *
+
+
+
+Eastlake 3rd & Hansen Informational [Page 69]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Description:
+ * This function will return the 160-bit message digest into the
+ * Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the 19th element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the SHA-1 hash.
+ * Message_Digest: [out]
+ * Where the digest is returned.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int USHAResult(USHAContext *ctx,
+ uint8_t Message_Digest[USHAMaxHashSize])
+{
+ if (ctx) {
+ switch (ctx->whichSha) {
+ case SHA1:
+ return SHA1Result((SHA1Context*)&ctx->ctx, Message_Digest);
+ case SHA224:
+ return SHA224Result((SHA224Context*)&ctx->ctx, Message_Digest);
+ case SHA256:
+ return SHA256Result((SHA256Context*)&ctx->ctx, Message_Digest);
+ case SHA384:
+ return SHA384Result((SHA384Context*)&ctx->ctx, Message_Digest);
+ case SHA512:
+ return SHA512Result((SHA512Context*)&ctx->ctx, Message_Digest);
+ default: return shaBadParam;
+ }
+ } else {
+ return shaNull;
+ }
+}
+
+/*
+ * USHABlockSize
+ *
+ * Description:
+ * This function will return the blocksize for the given SHA
+ * algorithm.
+ *
+ * Parameters:
+ * whichSha:
+ * which SHA algorithm to query
+
+
+
+Eastlake 3rd & Hansen Informational [Page 70]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ * Returns:
+ * block size
+ *
+ */
+int USHABlockSize(enum SHAversion whichSha)
+{
+ switch (whichSha) {
+ case SHA1: return SHA1_Message_Block_Size;
+ case SHA224: return SHA224_Message_Block_Size;
+ case SHA256: return SHA256_Message_Block_Size;
+ case SHA384: return SHA384_Message_Block_Size;
+ default:
+ case SHA512: return SHA512_Message_Block_Size;
+ }
+}
+
+/*
+ * USHAHashSize
+ *
+ * Description:
+ * This function will return the hashsize for the given SHA
+ * algorithm.
+ *
+ * Parameters:
+ * whichSha:
+ * which SHA algorithm to query
+ *
+ * Returns:
+ * hash size
+ *
+ */
+int USHAHashSize(enum SHAversion whichSha)
+{
+ switch (whichSha) {
+ case SHA1: return SHA1HashSize;
+ case SHA224: return SHA224HashSize;
+ case SHA256: return SHA256HashSize;
+ case SHA384: return SHA384HashSize;
+ default:
+ case SHA512: return SHA512HashSize;
+ }
+}
+
+/*
+ * USHAHashSizeBits
+ *
+ * Description:
+
+
+
+Eastlake 3rd & Hansen Informational [Page 71]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * This function will return the hashsize for the given SHA
+ * algorithm, expressed in bits.
+ *
+ * Parameters:
+ * whichSha:
+ * which SHA algorithm to query
+ *
+ * Returns:
+ * hash size in bits
+ *
+ */
+int USHAHashSizeBits(enum SHAversion whichSha)
+{
+ switch (whichSha) {
+ case SHA1: return SHA1HashSizeBits;
+ case SHA224: return SHA224HashSizeBits;
+ case SHA256: return SHA256HashSizeBits;
+ case SHA384: return SHA384HashSizeBits;
+ default:
+ case SHA512: return SHA512HashSizeBits;
+ }
+}
+
+8.2.5. sha-private.h
+
+/*************************** sha-private.h ***************************/
+/********************** See RFC 4634 for details *********************/
+#ifndef _SHA_PRIVATE__H
+#define _SHA_PRIVATE__H
+/*
+ * These definitions are defined in FIPS-180-2, section 4.1.
+ * Ch() and Maj() are defined identically in sections 4.1.1,
+ * 4.1.2 and 4.1.3.
+ *
+ * The definitions used in FIPS-180-2 are as follows:
+ */
+
+#ifndef USE_MODIFIED_MACROS
+#define SHA_Ch(x,y,z) (((x) & (y)) ^ ((~(x)) & (z)))
+#define SHA_Maj(x,y,z) (((x) & (y)) ^ ((x) & (z)) ^ ((y) & (z)))
+
+#else /* USE_MODIFIED_MACROS */
+/*
+ * The following definitions are equivalent and potentially faster.
+ */
+
+#define SHA_Ch(x, y, z) (((x) & ((y) ^ (z))) ^ (z))
+#define SHA_Maj(x, y, z) (((x) & ((y) | (z))) | ((y) & (z)))
+
+
+
+Eastlake 3rd & Hansen Informational [Page 72]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+#endif /* USE_MODIFIED_MACROS */
+
+#define SHA_Parity(x, y, z) ((x) ^ (y) ^ (z))
+
+#endif /* _SHA_PRIVATE__H */
+
+8.3 The HMAC Code
+
+/**************************** hmac.c ****************************/
+/******************** See RFC 4634 for details ******************/
+/*
+ * Description:
+ * This file implements the HMAC algorithm (Keyed-Hashing for
+ * Message Authentication, RFC2104), expressed in terms of the
+ * various SHA algorithms.
+ */
+
+#include "sha.h"
+
+/*
+ * hmac
+ *
+ * Description:
+ * This function will compute an HMAC message digest.
+ *
+ * Parameters:
+ * whichSha: [in]
+ * One of SHA1, SHA224, SHA256, SHA384, SHA512
+ * key: [in]
+ * The secret shared key.
+ * key_len: [in]
+ * The length of the secret shared key.
+ * message_array: [in]
+ * An array of characters representing the message.
+ * length: [in]
+ * The length of the message in message_array
+ * digest: [out]
+ * Where the digest is returned.
+ * NOTE: The length of the digest is determined by
+ * the value of whichSha.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int hmac(SHAversion whichSha, const unsigned char *text, int text_len,
+ const unsigned char *key, int key_len,
+ uint8_t digest[USHAMaxHashSize])
+
+
+
+Eastlake 3rd & Hansen Informational [Page 73]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+{
+ HMACContext ctx;
+ return hmacReset(&ctx, whichSha, key, key_len) ||
+ hmacInput(&ctx, text, text_len) ||
+ hmacResult(&ctx, digest);
+}
+
+/*
+ * hmacReset
+ *
+ * Description:
+ * This function will initialize the hmacContext in preparation
+ * for computing a new HMAC message digest.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to reset.
+ * whichSha: [in]
+ * One of SHA1, SHA224, SHA256, SHA384, SHA512
+ * key: [in]
+ * The secret shared key.
+ * key_len: [in]
+ * The length of the secret shared key.
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int hmacReset(HMACContext *ctx, enum SHAversion whichSha,
+ const unsigned char *key, int key_len)
+{
+ int i, blocksize, hashsize;
+
+ /* inner padding - key XORd with ipad */
+ unsigned char k_ipad[USHA_Max_Message_Block_Size];
+
+ /* temporary buffer when keylen > blocksize */
+ unsigned char tempkey[USHAMaxHashSize];
+
+ if (!ctx) return shaNull;
+
+ blocksize = ctx->blockSize = USHABlockSize(whichSha);
+ hashsize = ctx->hashSize = USHAHashSize(whichSha);
+
+ ctx->whichSha = whichSha;
+
+ /*
+ * If key is longer than the hash blocksize,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 74]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * reset it to key = HASH(key).
+ */
+ if (key_len > blocksize) {
+ USHAContext tctx;
+ int err = USHAReset(&tctx, whichSha) ||
+ USHAInput(&tctx, key, key_len) ||
+ USHAResult(&tctx, tempkey);
+ if (err != shaSuccess) return err;
+
+ key = tempkey;
+ key_len = hashsize;
+ }
+
+ /*
+ * The HMAC transform looks like:
+ *
+ * SHA(K XOR opad, SHA(K XOR ipad, text))
+ *
+ * where K is an n byte key.
+ * ipad is the byte 0x36 repeated blocksize times
+ * opad is the byte 0x5c repeated blocksize times
+ * and text is the data being protected.
+ */
+
+ /* store key into the pads, XOR'd with ipad and opad values */
+ for (i = 0; i < key_len; i++) {
+ k_ipad[i] = key[i] ^ 0x36;
+ ctx->k_opad[i] = key[i] ^ 0x5c;
+ }
+ /* remaining pad bytes are '\0' XOR'd with ipad and opad values */
+ for ( ; i < blocksize; i++) {
+ k_ipad[i] = 0x36;
+ ctx->k_opad[i] = 0x5c;
+ }
+
+ /* perform inner hash */
+ /* init context for 1st pass */
+ return USHAReset(&ctx->shaContext, whichSha) ||
+ /* and start with inner pad */
+ USHAInput(&ctx->shaContext, k_ipad, blocksize);
+}
+
+/*
+ * hmacInput
+ *
+ * Description:
+ * This function accepts an array of octets as the next portion
+ * of the message.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 75]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ * Parameters:
+ * context: [in/out]
+ * The HMAC context to update
+ * message_array: [in]
+ * An array of characters representing the next portion of
+ * the message.
+ * length: [in]
+ * The length of the message in message_array
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int hmacInput(HMACContext *ctx, const unsigned char *text,
+ int text_len)
+{
+ if (!ctx) return shaNull;
+ /* then text of datagram */
+ return USHAInput(&ctx->shaContext, text, text_len);
+}
+
+/*
+ * HMACFinalBits
+ *
+ * Description:
+ * This function will add in any final bits of the message.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The HMAC context to update
+ * message_bits: [in]
+ * The final bits of the message, in the upper portion of the
+ * byte. (Use 0b###00000 instead of 0b00000### to input the
+ * three bits ###.)
+ * length: [in]
+ * The number of bits in message_bits, between 1 and 7.
+ *
+ * Returns:
+ * sha Error Code.
+ */
+int hmacFinalBits(HMACContext *ctx,
+ const uint8_t bits,
+ unsigned int bitcount)
+{
+ if (!ctx) return shaNull;
+ /* then final bits of datagram */
+ return USHAFinalBits(&ctx->shaContext, bits, bitcount);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 76]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+}
+
+/*
+ * HMACResult
+ *
+ * Description:
+ * This function will return the N-byte message digest into the
+ * Message_Digest array provided by the caller.
+ * NOTE: The first octet of hash is stored in the 0th element,
+ * the last octet of hash in the Nth element.
+ *
+ * Parameters:
+ * context: [in/out]
+ * The context to use to calculate the HMAC hash.
+ * digest: [out]
+ * Where the digest is returned.
+ * NOTE 2: The length of the hash is determined by the value of
+ * whichSha that was passed to hmacReset().
+ *
+ * Returns:
+ * sha Error Code.
+ *
+ */
+int hmacResult(HMACContext *ctx, uint8_t *digest)
+{
+ if (!ctx) return shaNull;
+
+ /* finish up 1st pass */
+ /* (Use digest here as a temporary buffer.) */
+ return USHAResult(&ctx->shaContext, digest) ||
+
+ /* perform outer SHA */
+ /* init context for 2nd pass */
+ USHAReset(&ctx->shaContext, ctx->whichSha) ||
+
+ /* start with outer pad */
+ USHAInput(&ctx->shaContext, ctx->k_opad, ctx->blockSize) ||
+
+ /* then results of 1st hash */
+ USHAInput(&ctx->shaContext, digest, ctx->hashSize) ||
+
+ /* finish up 2nd pass */
+ USHAResult(&ctx->shaContext, digest);
+}
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 77]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+8.4. The Test Driver
+
+ The following code is a main program test driver to exercise the code
+ in sha1.c, sha224-256.c, and sha384-512.c. The test driver can also
+ be used as a stand-alone program for generating the hashes.
+
+ See also [RFC2202], [RFC4231], and [SHAVS].
+
+/**************************** shatest.c ****************************/
+/********************* See RFC 4634 for details ********************/
+/*
+ * Description:
+ * This file will exercise the SHA code performing
+ * the three tests documented in FIPS PUB 180-2
+ * (http://csrc.nist.gov/publications/fips/
+ * fips180-2/fips180-2withchangenotice.pdf)
+ * one that calls SHAInput with an exact multiple of 512 bits
+ * the seven tests documented for each algorithm in
+ * "The Secure Hash Algorithm Validation System (SHAVS)",
+ * three of which are bit-level tests
+ * (http://csrc.nist.gov/cryptval/shs/SHAVS.pdf)
+ *
+ * This file will exercise the HMAC SHA1 code performing
+ * the seven tests documented in RFCs 2202 and 4231.
+ *
+ * To run the tests and just see PASSED/FAILED, use the -p option.
+ *
+ * Other options exercise:
+ * hashing an arbitrary string
+ * hashing a file's contents
+ * a few error test checks
+ * printing the results in raw format
+ *
+ * Portability Issues:
+ * None.
+ *
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "sha.h"
+
+static int xgetopt(int argc, char **argv, const char *optstring);
+extern char *xoptarg;
+static int scasecmp(const char *s1, const char *s2);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 78]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * Define patterns for testing
+ */
+#define TEST1 "abc"
+#define TEST2_1 \
+ "abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq"
+#define TEST2_2a \
+ "abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmn"
+#define TEST2_2b \
+ "hijklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu"
+#define TEST2_2 TEST2_2a TEST2_2b
+#define TEST3 "a" /* times 1000000 */
+#define TEST4a "01234567012345670123456701234567"
+#define TEST4b "01234567012345670123456701234567"
+ /* an exact multiple of 512 bits */
+#define TEST4 TEST4a TEST4b /* times 10 */
+
+#define TEST7_1 \
+ "\x49\xb2\xae\xc2\x59\x4b\xbe\x3a\x3b\x11\x75\x42\xd9\x4a\xc8"
+#define TEST8_1 \
+ "\x9a\x7d\xfd\xf1\xec\xea\xd0\x6e\xd6\x46\xaa\x55\xfe\x75\x71\x46"
+#define TEST9_1 \
+ "\x65\xf9\x32\x99\x5b\xa4\xce\x2c\xb1\xb4\xa2\xe7\x1a\xe7\x02\x20" \
+ "\xaa\xce\xc8\x96\x2d\xd4\x49\x9c\xbd\x7c\x88\x7a\x94\xea\xaa\x10" \
+ "\x1e\xa5\xaa\xbc\x52\x9b\x4e\x7e\x43\x66\x5a\x5a\xf2\xcd\x03\xfe" \
+ "\x67\x8e\xa6\xa5\x00\x5b\xba\x3b\x08\x22\x04\xc2\x8b\x91\x09\xf4" \
+ "\x69\xda\xc9\x2a\xaa\xb3\xaa\x7c\x11\xa1\xb3\x2a"
+#define TEST10_1 \
+ "\xf7\x8f\x92\x14\x1b\xcd\x17\x0a\xe8\x9b\x4f\xba\x15\xa1\xd5\x9f" \
+ "\x3f\xd8\x4d\x22\x3c\x92\x51\xbd\xac\xbb\xae\x61\xd0\x5e\xd1\x15" \
+ "\xa0\x6a\x7c\xe1\x17\xb7\xbe\xea\xd2\x44\x21\xde\xd9\xc3\x25\x92" \
+ "\xbd\x57\xed\xea\xe3\x9c\x39\xfa\x1f\xe8\x94\x6a\x84\xd0\xcf\x1f" \
+ "\x7b\xee\xad\x17\x13\xe2\xe0\x95\x98\x97\x34\x7f\x67\xc8\x0b\x04" \
+ "\x00\xc2\x09\x81\x5d\x6b\x10\xa6\x83\x83\x6f\xd5\x56\x2a\x56\xca" \
+ "\xb1\xa2\x8e\x81\xb6\x57\x66\x54\x63\x1c\xf1\x65\x66\xb8\x6e\x3b" \
+ "\x33\xa1\x08\xb0\x53\x07\xc0\x0a\xff\x14\xa7\x68\xed\x73\x50\x60" \
+ "\x6a\x0f\x85\xe6\xa9\x1d\x39\x6f\x5b\x5c\xbe\x57\x7f\x9b\x38\x80" \
+ "\x7c\x7d\x52\x3d\x6d\x79\x2f\x6e\xbc\x24\xa4\xec\xf2\xb3\xa4\x27" \
+ "\xcd\xbb\xfb"
+#define TEST7_224 \
+ "\xf0\x70\x06\xf2\x5a\x0b\xea\x68\xcd\x76\xa2\x95\x87\xc2\x8d"
+#define TEST8_224 \
+ "\x18\x80\x40\x05\xdd\x4f\xbd\x15\x56\x29\x9d\x6f\x9d\x93\xdf\x62"
+#define TEST9_224 \
+ "\xa2\xbe\x6e\x46\x32\x81\x09\x02\x94\xd9\xce\x94\x82\x65\x69\x42" \
+ "\x3a\x3a\x30\x5e\xd5\xe2\x11\x6c\xd4\xa4\xc9\x87\xfc\x06\x57\x00" \
+ "\x64\x91\xb1\x49\xcc\xd4\xb5\x11\x30\xac\x62\xb1\x9d\xc2\x48\xc7" \
+ "\x44\x54\x3d\x20\xcd\x39\x52\xdc\xed\x1f\x06\xcc\x3b\x18\xb9\x1f" \
+
+
+
+Eastlake 3rd & Hansen Informational [Page 79]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "\x3f\x55\x63\x3e\xcc\x30\x85\xf4\x90\x70\x60\xd2"
+#define TEST10_224 \
+ "\x55\xb2\x10\x07\x9c\x61\xb5\x3a\xdd\x52\x06\x22\xd1\xac\x97\xd5" \
+ "\xcd\xbe\x8c\xb3\x3a\xa0\xae\x34\x45\x17\xbe\xe4\xd7\xba\x09\xab" \
+ "\xc8\x53\x3c\x52\x50\x88\x7a\x43\xbe\xbb\xac\x90\x6c\x2e\x18\x37" \
+ "\xf2\x6b\x36\xa5\x9a\xe3\xbe\x78\x14\xd5\x06\x89\x6b\x71\x8b\x2a" \
+ "\x38\x3e\xcd\xac\x16\xb9\x61\x25\x55\x3f\x41\x6f\xf3\x2c\x66\x74" \
+ "\xc7\x45\x99\xa9\x00\x53\x86\xd9\xce\x11\x12\x24\x5f\x48\xee\x47" \
+ "\x0d\x39\x6c\x1e\xd6\x3b\x92\x67\x0c\xa5\x6e\xc8\x4d\xee\xa8\x14" \
+ "\xb6\x13\x5e\xca\x54\x39\x2b\xde\xdb\x94\x89\xbc\x9b\x87\x5a\x8b" \
+ "\xaf\x0d\xc1\xae\x78\x57\x36\x91\x4a\xb7\xda\xa2\x64\xbc\x07\x9d" \
+ "\x26\x9f\x2c\x0d\x7e\xdd\xd8\x10\xa4\x26\x14\x5a\x07\x76\xf6\x7c" \
+ "\x87\x82\x73"
+#define TEST7_256 \
+ "\xbe\x27\x46\xc6\xdb\x52\x76\x5f\xdb\x2f\x88\x70\x0f\x9a\x73"
+#define TEST8_256 \
+ "\xe3\xd7\x25\x70\xdc\xdd\x78\x7c\xe3\x88\x7a\xb2\xcd\x68\x46\x52"
+#define TEST9_256 \
+ "\x3e\x74\x03\x71\xc8\x10\xc2\xb9\x9f\xc0\x4e\x80\x49\x07\xef\x7c" \
+ "\xf2\x6b\xe2\x8b\x57\xcb\x58\xa3\xe2\xf3\xc0\x07\x16\x6e\x49\xc1" \
+ "\x2e\x9b\xa3\x4c\x01\x04\x06\x91\x29\xea\x76\x15\x64\x25\x45\x70" \
+ "\x3a\x2b\xd9\x01\xe1\x6e\xb0\xe0\x5d\xeb\xa0\x14\xeb\xff\x64\x06" \
+ "\xa0\x7d\x54\x36\x4e\xff\x74\x2d\xa7\x79\xb0\xb3"
+#define TEST10_256 \
+ "\x83\x26\x75\x4e\x22\x77\x37\x2f\x4f\xc1\x2b\x20\x52\x7a\xfe\xf0" \
+ "\x4d\x8a\x05\x69\x71\xb1\x1a\xd5\x71\x23\xa7\xc1\x37\x76\x00\x00" \
+ "\xd7\xbe\xf6\xf3\xc1\xf7\xa9\x08\x3a\xa3\x9d\x81\x0d\xb3\x10\x77" \
+ "\x7d\xab\x8b\x1e\x7f\x02\xb8\x4a\x26\xc7\x73\x32\x5f\x8b\x23\x74" \
+ "\xde\x7a\x4b\x5a\x58\xcb\x5c\x5c\xf3\x5b\xce\xe6\xfb\x94\x6e\x5b" \
+ "\xd6\x94\xfa\x59\x3a\x8b\xeb\x3f\x9d\x65\x92\xec\xed\xaa\x66\xca" \
+ "\x82\xa2\x9d\x0c\x51\xbc\xf9\x33\x62\x30\xe5\xd7\x84\xe4\xc0\xa4" \
+ "\x3f\x8d\x79\xa3\x0a\x16\x5c\xba\xbe\x45\x2b\x77\x4b\x9c\x71\x09" \
+ "\xa9\x7d\x13\x8f\x12\x92\x28\x96\x6f\x6c\x0a\xdc\x10\x6a\xad\x5a" \
+ "\x9f\xdd\x30\x82\x57\x69\xb2\xc6\x71\xaf\x67\x59\xdf\x28\xeb\x39" \
+ "\x3d\x54\xd6"
+#define TEST7_384 \
+ "\x8b\xc5\x00\xc7\x7c\xee\xd9\x87\x9d\xa9\x89\x10\x7c\xe0\xaa"
+#define TEST8_384 \
+ "\xa4\x1c\x49\x77\x79\xc0\x37\x5f\xf1\x0a\x7f\x4e\x08\x59\x17\x39"
+#define TEST9_384 \
+ "\x68\xf5\x01\x79\x2d\xea\x97\x96\x76\x70\x22\xd9\x3d\xa7\x16\x79" \
+ "\x30\x99\x20\xfa\x10\x12\xae\xa3\x57\xb2\xb1\x33\x1d\x40\xa1\xd0" \
+ "\x3c\x41\xc2\x40\xb3\xc9\xa7\x5b\x48\x92\xf4\xc0\x72\x4b\x68\xc8" \
+ "\x75\x32\x1a\xb8\xcf\xe5\x02\x3b\xd3\x75\xbc\x0f\x94\xbd\x89\xfe" \
+ "\x04\xf2\x97\x10\x5d\x7b\x82\xff\xc0\x02\x1a\xeb\x1c\xcb\x67\x4f" \
+ "\x52\x44\xea\x34\x97\xde\x26\xa4\x19\x1c\x5f\x62\xe5\xe9\xa2\xd8" \
+ "\x08\x2f\x05\x51\xf4\xa5\x30\x68\x26\xe9\x1c\xc0\x06\xce\x1b\xf6" \
+ "\x0f\xf7\x19\xd4\x2f\xa5\x21\xc8\x71\xcd\x23\x94\xd9\x6e\xf4\x46" \
+
+
+
+Eastlake 3rd & Hansen Informational [Page 80]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "\x8f\x21\x96\x6b\x41\xf2\xba\x80\xc2\x6e\x83\xa9"
+#define TEST10_384 \
+ "\x39\x96\x69\xe2\x8f\x6b\x9c\x6d\xbc\xbb\x69\x12\xec\x10\xff\xcf" \
+ "\x74\x79\x03\x49\xb7\xdc\x8f\xbe\x4a\x8e\x7b\x3b\x56\x21\xdb\x0f" \
+ "\x3e\x7d\xc8\x7f\x82\x32\x64\xbb\xe4\x0d\x18\x11\xc9\xea\x20\x61" \
+ "\xe1\xc8\x4a\xd1\x0a\x23\xfa\xc1\x72\x7e\x72\x02\xfc\x3f\x50\x42" \
+ "\xe6\xbf\x58\xcb\xa8\xa2\x74\x6e\x1f\x64\xf9\xb9\xea\x35\x2c\x71" \
+ "\x15\x07\x05\x3c\xf4\xe5\x33\x9d\x52\x86\x5f\x25\xcc\x22\xb5\xe8" \
+ "\x77\x84\xa1\x2f\xc9\x61\xd6\x6c\xb6\xe8\x95\x73\x19\x9a\x2c\xe6" \
+ "\x56\x5c\xbd\xf1\x3d\xca\x40\x38\x32\xcf\xcb\x0e\x8b\x72\x11\xe8" \
+ "\x3a\xf3\x2a\x11\xac\x17\x92\x9f\xf1\xc0\x73\xa5\x1c\xc0\x27\xaa" \
+ "\xed\xef\xf8\x5a\xad\x7c\x2b\x7c\x5a\x80\x3e\x24\x04\xd9\x6d\x2a" \
+ "\x77\x35\x7b\xda\x1a\x6d\xae\xed\x17\x15\x1c\xb9\xbc\x51\x25\xa4" \
+ "\x22\xe9\x41\xde\x0c\xa0\xfc\x50\x11\xc2\x3e\xcf\xfe\xfd\xd0\x96" \
+ "\x76\x71\x1c\xf3\xdb\x0a\x34\x40\x72\x0e\x16\x15\xc1\xf2\x2f\xbc" \
+ "\x3c\x72\x1d\xe5\x21\xe1\xb9\x9b\xa1\xbd\x55\x77\x40\x86\x42\x14" \
+ "\x7e\xd0\x96"
+#define TEST7_512 \
+ "\x08\xec\xb5\x2e\xba\xe1\xf7\x42\x2d\xb6\x2b\xcd\x54\x26\x70"
+#define TEST8_512 \
+ "\x8d\x4e\x3c\x0e\x38\x89\x19\x14\x91\x81\x6e\x9d\x98\xbf\xf0\xa0"
+#define TEST9_512 \
+ "\x3a\xdd\xec\x85\x59\x32\x16\xd1\x61\x9a\xa0\x2d\x97\x56\x97\x0b" \
+ "\xfc\x70\xac\xe2\x74\x4f\x7c\x6b\x27\x88\x15\x10\x28\xf7\xb6\xa2" \
+ "\x55\x0f\xd7\x4a\x7e\x6e\x69\xc2\xc9\xb4\x5f\xc4\x54\x96\x6d\xc3" \
+ "\x1d\x2e\x10\xda\x1f\x95\xce\x02\xbe\xb4\xbf\x87\x65\x57\x4c\xbd" \
+ "\x6e\x83\x37\xef\x42\x0a\xdc\x98\xc1\x5c\xb6\xd5\xe4\xa0\x24\x1b" \
+ "\xa0\x04\x6d\x25\x0e\x51\x02\x31\xca\xc2\x04\x6c\x99\x16\x06\xab" \
+ "\x4e\xe4\x14\x5b\xee\x2f\xf4\xbb\x12\x3a\xab\x49\x8d\x9d\x44\x79" \
+ "\x4f\x99\xcc\xad\x89\xa9\xa1\x62\x12\x59\xed\xa7\x0a\x5b\x6d\xd4" \
+ "\xbd\xd8\x77\x78\xc9\x04\x3b\x93\x84\xf5\x49\x06"
+#define TEST10_512 \
+ "\xa5\x5f\x20\xc4\x11\xaa\xd1\x32\x80\x7a\x50\x2d\x65\x82\x4e\x31" \
+ "\xa2\x30\x54\x32\xaa\x3d\x06\xd3\xe2\x82\xa8\xd8\x4e\x0d\xe1\xde" \
+ "\x69\x74\xbf\x49\x54\x69\xfc\x7f\x33\x8f\x80\x54\xd5\x8c\x26\xc4" \
+ "\x93\x60\xc3\xe8\x7a\xf5\x65\x23\xac\xf6\xd8\x9d\x03\xe5\x6f\xf2" \
+ "\xf8\x68\x00\x2b\xc3\xe4\x31\xed\xc4\x4d\xf2\xf0\x22\x3d\x4b\xb3" \
+ "\xb2\x43\x58\x6e\x1a\x7d\x92\x49\x36\x69\x4f\xcb\xba\xf8\x8d\x95" \
+ "\x19\xe4\xeb\x50\xa6\x44\xf8\xe4\xf9\x5e\xb0\xea\x95\xbc\x44\x65" \
+ "\xc8\x82\x1a\xac\xd2\xfe\x15\xab\x49\x81\x16\x4b\xbb\x6d\xc3\x2f" \
+ "\x96\x90\x87\xa1\x45\xb0\xd9\xcc\x9c\x67\xc2\x2b\x76\x32\x99\x41" \
+ "\x9c\xc4\x12\x8b\xe9\xa0\x77\xb3\xac\xe6\x34\x06\x4e\x6d\x99\x28" \
+ "\x35\x13\xdc\x06\xe7\x51\x5d\x0d\x73\x13\x2e\x9a\x0d\xc6\xd3\xb1" \
+ "\xf8\xb2\x46\xf1\xa9\x8a\x3f\xc7\x29\x41\xb1\xe3\xbb\x20\x98\xe8" \
+ "\xbf\x16\xf2\x68\xd6\x4f\x0b\x0f\x47\x07\xfe\x1e\xa1\xa1\x79\x1b" \
+ "\xa2\xf3\xc0\xc7\x58\xe5\xf5\x51\x86\x3a\x96\xc9\x49\xad\x47\xd7" \
+ "\xfb\x40\xd2"
+#define SHA1_SEED "\xd0\x56\x9c\xb3\x66\x5a\x8a\x43\xeb\x6e\xa2\x3d" \
+
+
+
+Eastlake 3rd & Hansen Informational [Page 81]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "\x75\xa3\xc4\xd2\x05\x4a\x0d\x7d"
+#define SHA224_SEED "\xd0\x56\x9c\xb3\x66\x5a\x8a\x43\xeb\x6e\xa2" \
+ "\x3d\x75\xa3\xc4\xd2\x05\x4a\x0d\x7d\x66\xa9\xca\x99\xc9\xce\xb0" \
+ "\x27"
+#define SHA256_SEED "\xf4\x1e\xce\x26\x13\xe4\x57\x39\x15\x69\x6b" \
+ "\x5a\xdc\xd5\x1c\xa3\x28\xbe\x3b\xf5\x66\xa9\xca\x99\xc9\xce\xb0" \
+ "\x27\x9c\x1c\xb0\xa7"
+#define SHA384_SEED "\x82\x40\xbc\x51\xe4\xec\x7e\xf7\x6d\x18\xe3" \
+ "\x52\x04\xa1\x9f\x51\xa5\x21\x3a\x73\xa8\x1d\x6f\x94\x46\x80\xd3" \
+ "\x07\x59\x48\xb7\xe4\x63\x80\x4e\xa3\xd2\x6e\x13\xea\x82\x0d\x65" \
+ "\xa4\x84\xbe\x74\x53"
+#define SHA512_SEED "\x47\x3f\xf1\xb9\xb3\xff\xdf\xa1\x26\x69\x9a" \
+ "\xc7\xef\x9e\x8e\x78\x77\x73\x09\x58\x24\xc6\x42\x55\x7c\x13\x99" \
+ "\xd9\x8e\x42\x20\x44\x8d\xc3\x5b\x99\xbf\xdd\x44\x77\x95\x43\x92" \
+ "\x4c\x1c\xe9\x3b\xc5\x94\x15\x38\x89\x5d\xb9\x88\x26\x1b\x00\x77" \
+ "\x4b\x12\x27\x20\x39"
+
+#define TESTCOUNT 10
+#define HASHCOUNT 5
+#define RANDOMCOUNT 4
+#define HMACTESTCOUNT 7
+
+#define PRINTNONE 0
+#define PRINTTEXT 1
+#define PRINTRAW 2
+#define PRINTHEX 3
+#define PRINTBASE64 4
+
+#define PRINTPASSFAIL 1
+#define PRINTFAIL 2
+
+#define length(x) (sizeof(x)-1)
+
+/* Test arrays for hashes. */
+struct hash {
+ const char *name;
+ SHAversion whichSha;
+ int hashsize;
+ struct {
+ const char *testarray;
+ int length;
+ long repeatcount;
+ int extrabits;
+ int numberExtrabits;
+ const char *resultarray;
+ } tests[TESTCOUNT];
+ const char *randomtest;
+ const char *randomresults[RANDOMCOUNT];
+
+
+
+Eastlake 3rd & Hansen Informational [Page 82]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+} hashes[HASHCOUNT] = {
+ { "SHA1", SHA1, SHA1HashSize,
+ {
+ /* 1 */ { TEST1, length(TEST1), 1, 0, 0,
+ "A9993E364706816ABA3E25717850C26C9CD0D89D" },
+ /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0,
+ "84983E441C3BD26EBAAE4AA1F95129E5E54670F1" },
+ /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0,
+ "34AA973CD4C4DAA4F61EEB2BDBAD27316534016F" },
+ /* 4 */ { TEST4, length(TEST4), 10, 0, 0,
+ "DEA356A2CDDD90C7A7ECEDC5EBB563934F460452" },
+ /* 5 */ { "", 0, 0, 0x98, 5,
+ "29826B003B906E660EFF4027CE98AF3531AC75BA" },
+ /* 6 */ { "\x5e", 1, 1, 0, 0,
+ "5E6F80A34A9798CAFC6A5DB96CC57BA4C4DB59C2" },
+ /* 7 */ { TEST7_1, length(TEST7_1), 1, 0x80, 3,
+ "6239781E03729919C01955B3FFA8ACB60B988340" },
+ /* 8 */ { TEST8_1, length(TEST8_1), 1, 0, 0,
+ "82ABFF6605DBE1C17DEF12A394FA22A82B544A35" },
+ /* 9 */ { TEST9_1, length(TEST9_1), 1, 0xE0, 3,
+ "8C5B2A5DDAE5A97FC7F9D85661C672ADBF7933D4" },
+ /* 10 */ { TEST10_1, length(TEST10_1), 1, 0, 0,
+ "CB0082C8F197D260991BA6A460E76E202BAD27B3" }
+ }, SHA1_SEED, { "E216836819477C7F78E0D843FE4FF1B6D6C14CD4",
+ "A2DBC7A5B1C6C0A8BCB7AAA41252A6A7D0690DBC",
+ "DB1F9050BB863DFEF4CE37186044E2EEB17EE013",
+ "127FDEDF43D372A51D5747C48FBFFE38EF6CDF7B"
+ } },
+ { "SHA224", SHA224, SHA224HashSize,
+ {
+ /* 1 */ { TEST1, length(TEST1), 1, 0, 0,
+ "23097D223405D8228642A477BDA255B32AADBCE4BDA0B3F7E36C9DA7" },
+ /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0,
+ "75388B16512776CC5DBA5DA1FD890150B0C6455CB4F58B1952522525" },
+ /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0,
+ "20794655980C91D8BBB4C1EA97618A4BF03F42581948B2EE4EE7AD67" },
+ /* 4 */ { TEST4, length(TEST4), 10, 0, 0,
+ "567F69F168CD7844E65259CE658FE7AADFA25216E68ECA0EB7AB8262" },
+ /* 5 */ { "", 0, 0, 0x68, 5,
+ "E3B048552C3C387BCAB37F6EB06BB79B96A4AEE5FF27F51531A9551C" },
+ /* 6 */ { "\x07", 1, 1, 0, 0,
+ "00ECD5F138422B8AD74C9799FD826C531BAD2FCABC7450BEE2AA8C2A" },
+ /* 7 */ { TEST7_224, length(TEST7_224), 1, 0xA0, 3,
+ "1B01DB6CB4A9E43DED1516BEB3DB0B87B6D1EA43187462C608137150" },
+ /* 8 */ { TEST8_224, length(TEST8_224), 1, 0, 0,
+ "DF90D78AA78821C99B40BA4C966921ACCD8FFB1E98AC388E56191DB1" },
+ /* 9 */ { TEST9_224, length(TEST9_224), 1, 0xE0, 3,
+ "54BEA6EAB8195A2EB0A7906A4B4A876666300EEFBD1F3B8474F9CD57" },
+
+
+
+Eastlake 3rd & Hansen Informational [Page 83]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ /* 10 */ { TEST10_224, length(TEST10_224), 1, 0, 0,
+ "0B31894EC8937AD9B91BDFBCBA294D9ADEFAA18E09305E9F20D5C3A4" }
+ }, SHA224_SEED, { "100966A5B4FDE0B42E2A6C5953D4D7F41BA7CF79FD"
+ "2DF431416734BE", "1DCA396B0C417715DEFAAE9641E10A2E99D55A"
+ "BCB8A00061EB3BE8BD", "1864E627BDB2319973CD5ED7D68DA71D8B"
+ "F0F983D8D9AB32C34ADB34", "A2406481FC1BCAF24DD08E6752E844"
+ "709563FB916227FED598EB621F"
+ } },
+ { "SHA256", SHA256, SHA256HashSize,
+ {
+ /* 1 */ { TEST1, length(TEST1), 1, 0, 0, "BA7816BF8F01CFEA4141"
+ "40DE5DAE2223B00361A396177A9CB410FF61F20015AD" },
+ /* 2 */ { TEST2_1, length(TEST2_1), 1, 0, 0, "248D6A61D20638B8"
+ "E5C026930C3E6039A33CE45964FF2167F6ECEDD419DB06C1" },
+ /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0, "CDC76E5C9914FB92"
+ "81A1C7E284D73E67F1809A48A497200E046D39CCC7112CD0" },
+ /* 4 */ { TEST4, length(TEST4), 10, 0, 0, "594847328451BDFA"
+ "85056225462CC1D867D877FB388DF0CE35F25AB5562BFBB5" },
+ /* 5 */ { "", 0, 0, 0x68, 5, "D6D3E02A31A84A8CAA9718ED6C2057BE"
+ "09DB45E7823EB5079CE7A573A3760F95" },
+ /* 6 */ { "\x19", 1, 1, 0, 0, "68AA2E2EE5DFF96E3355E6C7EE373E3D"
+ "6A4E17F75F9518D843709C0C9BC3E3D4" },
+ /* 7 */ { TEST7_256, length(TEST7_256), 1, 0x60, 3, "77EC1DC8"
+ "9C821FF2A1279089FA091B35B8CD960BCAF7DE01C6A7680756BEB972" },
+ /* 8 */ { TEST8_256, length(TEST8_256), 1, 0, 0, "175EE69B02BA"
+ "9B58E2B0A5FD13819CEA573F3940A94F825128CF4209BEABB4E8" },
+ /* 9 */ { TEST9_256, length(TEST9_256), 1, 0xA0, 3, "3E9AD646"
+ "8BBBAD2AC3C2CDC292E018BA5FD70B960CF1679777FCE708FDB066E9" },
+ /* 10 */ { TEST10_256, length(TEST10_256), 1, 0, 0, "97DBCA7D"
+ "F46D62C8A422C941DD7E835B8AD3361763F7E9B2D95F4F0DA6E1CCBC" },
+ }, SHA256_SEED, { "83D28614D49C3ADC1D6FC05DB5F48037C056F8D2A4CE44"
+ "EC6457DEA5DD797CD1", "99DBE3127EF2E93DD9322D6A07909EB33B6399"
+ "5E529B3F954B8581621BB74D39", "8D4BE295BB64661CA3C7EFD129A2F7"
+ "25B33072DBDDE32385B9A87B9AF88EA76F", "40AF5D3F9716B040DF9408"
+ "E31536B70FF906EC51B00447CA97D7DD97C12411F4"
+ } },
+ { "SHA384", SHA384, SHA384HashSize,
+ {
+ /* 1 */ { TEST1, length(TEST1), 1, 0, 0,
+ "CB00753F45A35E8BB5A03D699AC65007272C32AB0EDED163"
+ "1A8B605A43FF5BED8086072BA1E7CC2358BAECA134C825A7" },
+ /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0,
+ "09330C33F71147E83D192FC782CD1B4753111B173B3B05D2"
+ "2FA08086E3B0F712FCC7C71A557E2DB966C3E9FA91746039" },
+ /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0,
+ "9D0E1809716474CB086E834E310A4A1CED149E9C00F24852"
+ "7972CEC5704C2A5B07B8B3DC38ECC4EBAE97DDD87F3D8985" },
+ /* 4 */ { TEST4, length(TEST4), 10, 0, 0,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 84]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "2FC64A4F500DDB6828F6A3430B8DD72A368EB7F3A8322A70"
+ "BC84275B9C0B3AB00D27A5CC3C2D224AA6B61A0D79FB4596" },
+ /* 5 */ { "", 0, 0, 0x10, 5,
+ "8D17BE79E32B6718E07D8A603EB84BA0478F7FCFD1BB9399"
+ "5F7D1149E09143AC1FFCFC56820E469F3878D957A15A3FE4" },
+ /* 6 */ { "\xb9", 1, 1, 0, 0,
+ "BC8089A19007C0B14195F4ECC74094FEC64F01F90929282C"
+ "2FB392881578208AD466828B1C6C283D2722CF0AD1AB6938" },
+ /* 7 */ { TEST7_384, length(TEST7_384), 1, 0xA0, 3,
+ "D8C43B38E12E7C42A7C9B810299FD6A770BEF30920F17532"
+ "A898DE62C7A07E4293449C0B5FA70109F0783211CFC4BCE3" },
+ /* 8 */ { TEST8_384, length(TEST8_384), 1, 0, 0,
+ "C9A68443A005812256B8EC76B00516F0DBB74FAB26D66591"
+ "3F194B6FFB0E91EA9967566B58109CBC675CC208E4C823F7" },
+ /* 9 */ { TEST9_384, length(TEST9_384), 1, 0xE0, 3,
+ "5860E8DE91C21578BB4174D227898A98E0B45C4C760F0095"
+ "49495614DAEDC0775D92D11D9F8CE9B064EEAC8DAFC3A297" },
+ /* 10 */ { TEST10_384, length(TEST10_384), 1, 0, 0,
+ "4F440DB1E6EDD2899FA335F09515AA025EE177A79F4B4AAF"
+ "38E42B5C4DE660F5DE8FB2A5B2FBD2A3CBFFD20CFF1288C0" }
+ }, SHA384_SEED, { "CE44D7D63AE0C91482998CF662A51EC80BF6FC68661A3C"
+ "57F87566112BD635A743EA904DEB7D7A42AC808CABE697F38F", "F9C6D2"
+ "61881FEE41ACD39E67AA8D0BAD507C7363EB67E2B81F45759F9C0FD7B503"
+ "DF1A0B9E80BDE7BC333D75B804197D", "D96512D8C9F4A7A4967A366C01"
+ "C6FD97384225B58343A88264847C18E4EF8AB7AEE4765FFBC3E30BD485D3"
+ "638A01418F", "0CA76BD0813AF1509E170907A96005938BC985628290B2"
+ "5FEF73CF6FAD68DDBA0AC8920C94E0541607B0915A7B4457F7"
+ } },
+ { "SHA512", SHA512, SHA512HashSize,
+ {
+ /* 1 */ { TEST1, length(TEST1), 1, 0, 0,
+ "DDAF35A193617ABACC417349AE20413112E6FA4E89A97EA2"
+ "0A9EEEE64B55D39A2192992A274FC1A836BA3C23A3FEEBBD"
+ "454D4423643CE80E2A9AC94FA54CA49F" },
+ /* 2 */ { TEST2_2, length(TEST2_2), 1, 0, 0,
+ "8E959B75DAE313DA8CF4F72814FC143F8F7779C6EB9F7FA1"
+ "7299AEADB6889018501D289E4900F7E4331B99DEC4B5433A"
+ "C7D329EEB6DD26545E96E55B874BE909" },
+ /* 3 */ { TEST3, length(TEST3), 1000000, 0, 0,
+ "E718483D0CE769644E2E42C7BC15B4638E1F98B13B204428"
+ "5632A803AFA973EBDE0FF244877EA60A4CB0432CE577C31B"
+ "EB009C5C2C49AA2E4EADB217AD8CC09B" },
+ /* 4 */ { TEST4, length(TEST4), 10, 0, 0,
+ "89D05BA632C699C31231DED4FFC127D5A894DAD412C0E024"
+ "DB872D1ABD2BA8141A0F85072A9BE1E2AA04CF33C765CB51"
+ "0813A39CD5A84C4ACAA64D3F3FB7BAE9" },
+ /* 5 */ { "", 0, 0, 0xB0, 5,
+ "D4EE29A9E90985446B913CF1D1376C836F4BE2C1CF3CADA0"
+
+
+
+Eastlake 3rd & Hansen Informational [Page 85]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "720A6BF4857D886A7ECB3C4E4C0FA8C7F95214E41DC1B0D2"
+ "1B22A84CC03BF8CE4845F34DD5BDBAD4" },
+ /* 6 */ { "\xD0", 1, 1, 0, 0,
+ "9992202938E882E73E20F6B69E68A0A7149090423D93C81B"
+ "AB3F21678D4ACEEEE50E4E8CAFADA4C85A54EA8306826C4A"
+ "D6E74CECE9631BFA8A549B4AB3FBBA15" },
+ /* 7 */ { TEST7_512, length(TEST7_512), 1, 0x80, 3,
+ "ED8DC78E8B01B69750053DBB7A0A9EDA0FB9E9D292B1ED71"
+ "5E80A7FE290A4E16664FD913E85854400C5AF05E6DAD316B"
+ "7359B43E64F8BEC3C1F237119986BBB6" },
+ /* 8 */ { TEST8_512, length(TEST8_512), 1, 0, 0,
+ "CB0B67A4B8712CD73C9AABC0B199E9269B20844AFB75ACBD"
+ "D1C153C9828924C3DDEDAAFE669C5FDD0BC66F630F677398"
+ "8213EB1B16F517AD0DE4B2F0C95C90F8" },
+ /* 9 */ { TEST9_512, length(TEST9_512), 1, 0x80, 3,
+ "32BA76FC30EAA0208AEB50FFB5AF1864FDBF17902A4DC0A6"
+ "82C61FCEA6D92B783267B21080301837F59DE79C6B337DB2"
+ "526F8A0A510E5E53CAFED4355FE7C2F1" },
+ /* 10 */ { TEST10_512, length(TEST10_512), 1, 0, 0,
+ "C665BEFB36DA189D78822D10528CBF3B12B3EEF726039909"
+ "C1A16A270D48719377966B957A878E720584779A62825C18"
+ "DA26415E49A7176A894E7510FD1451F5" }
+ }, SHA512_SEED, { "2FBB1E7E00F746BA514FBC8C421F36792EC0E11FF5EFC3"
+ "78E1AB0C079AA5F0F66A1E3EDBAEB4F9984BE14437123038A452004A5576"
+ "8C1FD8EED49E4A21BEDCD0", "25CBE5A4F2C7B1D7EF07011705D50C62C5"
+ "000594243EAFD1241FC9F3D22B58184AE2FEE38E171CF8129E29459C9BC2"
+ "EF461AF5708887315F15419D8D17FE7949", "5B8B1F2687555CE2D7182B"
+ "92E5C3F6C36547DA1C13DBB9EA4F73EA4CBBAF89411527906D35B1B06C1B"
+ "6A8007D05EC66DF0A406066829EAB618BDE3976515AAFC", "46E36B007D"
+ "19876CDB0B29AD074FE3C08CDD174D42169D6ABE5A1414B6E79707DF5877"
+ "6A98091CF431854147BB6D3C66D43BFBC108FD715BDE6AA127C2B0E79F"
+ }
+ }
+};
+
+/* Test arrays for HMAC. */
+struct hmachash {
+ const char *keyarray[5];
+ int keylength[5];
+ const char *dataarray[5];
+ int datalength[5];
+ const char *resultarray[5];
+ int resultlength[5];
+} hmachashes[HMACTESTCOUNT] = {
+ { /* 1 */ {
+ "\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b\x0b"
+ "\x0b\x0b\x0b\x0b\x0b"
+ }, { 20 }, {
+
+
+
+Eastlake 3rd & Hansen Informational [Page 86]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "\x48\x69\x20\x54\x68\x65\x72\x65" /* "Hi There" */
+ }, { 8 }, {
+ /* HMAC-SHA-1 */
+ "B617318655057264E28BC0B6FB378C8EF146BE00",
+ /* HMAC-SHA-224 */
+ "896FB1128ABBDF196832107CD49DF33F47B4B1169912BA4F53684B22",
+ /* HMAC-SHA-256 */
+ "B0344C61D8DB38535CA8AFCEAF0BF12B881DC200C9833DA726E9376C2E32"
+ "CFF7",
+ /* HMAC-SHA-384 */
+ "AFD03944D84895626B0825F4AB46907F15F9DADBE4101EC682AA034C7CEB"
+ "C59CFAEA9EA9076EDE7F4AF152E8B2FA9CB6",
+ /* HMAC-SHA-512 */
+ "87AA7CDEA5EF619D4FF0B4241A1D6CB02379F4E2CE4EC2787AD0B30545E1"
+ "7CDEDAA833B7D6B8A702038B274EAEA3F4E4BE9D914EEB61F1702E696C20"
+ "3A126854"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ },
+ { /* 2 */ {
+ "\x4a\x65\x66\x65" /* "Jefe" */
+ }, { 4 }, {
+ "\x77\x68\x61\x74\x20\x64\x6f\x20\x79\x61\x20\x77\x61\x6e\x74"
+ "\x20\x66\x6f\x72\x20\x6e\x6f\x74\x68\x69\x6e\x67\x3f"
+ /* "what do ya want for nothing?" */
+ }, { 28 }, {
+ /* HMAC-SHA-1 */
+ "EFFCDF6AE5EB2FA2D27416D5F184DF9C259A7C79",
+ /* HMAC-SHA-224 */
+ "A30E01098BC6DBBF45690F3A7E9E6D0F8BBEA2A39E6148008FD05E44",
+ /* HMAC-SHA-256 */
+ "5BDCC146BF60754E6A042426089575C75A003F089D2739839DEC58B964EC"
+ "3843",
+ /* HMAC-SHA-384 */
+ "AF45D2E376484031617F78D2B58A6B1B9C7EF464F5A01B47E42EC3736322"
+ "445E8E2240CA5E69E2C78B3239ECFAB21649",
+ /* HMAC-SHA-512 */
+ "164B7A7BFCF819E2E395FBE73B56E0A387BD64222E831FD610270CD7EA25"
+ "05549758BF75C05A994A6D034F65F8F0E6FDCAEAB1A34D4A6B4B636E070A"
+ "38BCE737"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ },
+ { /* 3 */
+ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa"
+ }, { 20 }, {
+
+
+
+Eastlake 3rd & Hansen Informational [Page 87]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd\xdd"
+ "\xdd\xdd\xdd\xdd\xdd"
+ }, { 50 }, {
+ /* HMAC-SHA-1 */
+ "125D7342B9AC11CD91A39AF48AA17B4F63F175D3",
+ /* HMAC-SHA-224 */
+ "7FB3CB3588C6C1F6FFA9694D7D6AD2649365B0C1F65D69D1EC8333EA",
+ /* HMAC-SHA-256 */
+ "773EA91E36800E46854DB8EBD09181A72959098B3EF8C122D9635514CED5"
+ "65FE",
+ /* HMAC-SHA-384 */
+ "88062608D3E6AD8A0AA2ACE014C8A86F0AA635D947AC9FEBE83EF4E55966"
+ "144B2A5AB39DC13814B94E3AB6E101A34F27",
+ /* HMAC-SHA-512 */
+ "FA73B0089D56A284EFB0F0756C890BE9B1B5DBDD8EE81A3655F83E33B227"
+ "9D39BF3E848279A722C806B485A47E67C807B946A337BEE8942674278859"
+ "E13292FB"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ },
+ { /* 4 */ {
+ "\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+ "\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19"
+ }, { 25 }, {
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd\xcd"
+ "\xcd\xcd\xcd\xcd\xcd"
+ }, { 50 }, {
+ /* HMAC-SHA-1 */
+ "4C9007F4026250C6BC8414F9BF50C86C2D7235DA",
+ /* HMAC-SHA-224 */
+ "6C11506874013CAC6A2ABC1BB382627CEC6A90D86EFC012DE7AFEC5A",
+ /* HMAC-SHA-256 */
+ "82558A389A443C0EA4CC819899F2083A85F0FAA3E578F8077A2E3FF46729"
+ "665B",
+ /* HMAC-SHA-384 */
+ "3E8A69B7783C25851933AB6290AF6CA77A9981480850009CC5577C6E1F57"
+ "3B4E6801DD23C4A7D679CCF8A386C674CFFB",
+ /* HMAC-SHA-512 */
+ "B0BA465637458C6990E5A8C5F61D4AF7E576D97FF94B872DE76F8050361E"
+ "E3DBA91CA5C11AA25EB4D679275CC5788063A5F19741120C4F2DE2ADEBEB"
+ "10A298DD"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ },
+
+
+
+Eastlake 3rd & Hansen Informational [Page 88]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ { /* 5 */ {
+ "\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c\x0c"
+ "\x0c\x0c\x0c\x0c\x0c"
+ }, { 20 }, {
+ "Test With Truncation"
+ }, { 20 }, {
+ /* HMAC-SHA-1 */
+ "4C1A03424B55E07FE7F27BE1",
+ /* HMAC-SHA-224 */
+ "0E2AEA68A90C8D37C988BCDB9FCA6FA8",
+ /* HMAC-SHA-256 */
+ "A3B6167473100EE06E0C796C2955552B",
+ /* HMAC-SHA-384 */
+ "3ABF34C3503B2A23A46EFC619BAEF897",
+ /* HMAC-SHA-512 */
+ "415FAD6271580A531D4179BC891D87A6"
+ }, { 12, 16, 16, 16, 16 }
+ },
+ { /* 6 */ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ }, { 80, 131 }, {
+ "Test Using Larger Than Block-Size Key - Hash Key First"
+ }, { 54 }, {
+ /* HMAC-SHA-1 */
+ "AA4AE5E15272D00E95705637CE8A3B55ED402112",
+ /* HMAC-SHA-224 */
+ "95E9A0DB962095ADAEBE9B2D6F0DBCE2D499F112F2D2B7273FA6870E",
+ /* HMAC-SHA-256 */
+ "60E431591EE0B67F0D8A26AACBF5B77F8E0BC6213728C5140546040F0EE3"
+ "7F54",
+ /* HMAC-SHA-384 */
+ "4ECE084485813E9088D2C63A041BC5B44F9EF1012A2B588F3CD11F05033A"
+ "C4C60C2EF6AB4030FE8296248DF163F44952",
+ /* HMAC-SHA-512 */
+ "80B24263C7C1A3EBB71493C1DD7BE8B49B46D1F41B4AEEC1121B013783F8"
+ "F3526B56D037E05F2598BD0FD2215D6A1E5295E64F73F63F0AEC8B915A98"
+ "5D786598"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ },
+
+
+
+Eastlake 3rd & Hansen Informational [Page 89]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ { /* 7 */ {
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ "\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa\xaa"
+ }, { 80, 131 }, {
+ "Test Using Larger Than Block-Size Key and "
+ "Larger Than One Block-Size Data",
+ "\x54\x68\x69\x73\x20\x69\x73\x20\x61\x20\x74\x65\x73\x74\x20"
+ "\x75\x73\x69\x6e\x67\x20\x61\x20\x6c\x61\x72\x67\x65\x72\x20"
+ "\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73\x69\x7a\x65"
+ "\x20\x6b\x65\x79\x20\x61\x6e\x64\x20\x61\x20\x6c\x61\x72\x67"
+ "\x65\x72\x20\x74\x68\x61\x6e\x20\x62\x6c\x6f\x63\x6b\x2d\x73"
+ "\x69\x7a\x65\x20\x64\x61\x74\x61\x2e\x20\x54\x68\x65\x20\x6b"
+ "\x65\x79\x20\x6e\x65\x65\x64\x73\x20\x74\x6f\x20\x62\x65\x20"
+ "\x68\x61\x73\x68\x65\x64\x20\x62\x65\x66\x6f\x72\x65\x20\x62"
+ "\x65\x69\x6e\x67\x20\x75\x73\x65\x64\x20\x62\x79\x20\x74\x68"
+ "\x65\x20\x48\x4d\x41\x43\x20\x61\x6c\x67\x6f\x72\x69\x74\x68"
+ "\x6d\x2e"
+ /* "This is a test using a larger than block-size key and a "
+ "larger than block-size data. The key needs to be hashed "
+ "before being used by the HMAC algorithm." */
+ }, { 73, 152 }, {
+ /* HMAC-SHA-1 */
+ "E8E99D0F45237D786D6BBAA7965C7808BBFF1A91",
+ /* HMAC-SHA-224 */
+ "3A854166AC5D9F023F54D517D0B39DBD946770DB9C2B95C9F6F565D1",
+ /* HMAC-SHA-256 */
+ "9B09FFA71B942FCB27635FBCD5B0E944BFDC63644F0713938A7F51535C3A"
+ "35E2",
+ /* HMAC-SHA-384 */
+ "6617178E941F020D351E2F254E8FD32C602420FEB0B8FB9ADCCEBB82461E"
+ "99C5A678CC31E799176D3860E6110C46523E",
+ /* HMAC-SHA-512 */
+ "E37B6A775DC87DBAA4DFA9F96E5E3FFDDEBD71F8867289865DF5A32D20CD"
+ "C944B6022CAC3C4982B10D5EEB55C3E4DE15134676FB6DE0446065C97440"
+ "FA8C6A58"
+ }, { SHA1HashSize, SHA224HashSize, SHA256HashSize,
+ SHA384HashSize, SHA512HashSize }
+ }
+};
+
+/*
+
+
+
+Eastlake 3rd & Hansen Informational [Page 90]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * Check the hash value against the expected string, expressed in hex
+ */
+static const char hexdigits[] = "0123456789ABCDEF";
+int checkmatch(const unsigned char *hashvalue,
+ const char *hexstr, int hashsize)
+{
+ int i;
+ for (i = 0; i < hashsize; ++i) {
+ if (*hexstr++ != hexdigits[(hashvalue[i] >> 4) & 0xF])
+ return 0;
+ if (*hexstr++ != hexdigits[hashvalue[i] & 0xF]) return 0;
+ }
+ return 1;
+}
+
+/*
+ * Print the string, converting non-printable characters to "."
+ */
+void printstr(const char *str, int len)
+{
+ for ( ; len-- > 0; str++)
+ putchar(isprint((unsigned char)*str) ? *str : '.');
+}
+
+/*
+ * Print the string, converting non-printable characters to hex "## ".
+ */
+void printxstr(const char *str, int len)
+{
+ for ( ; len-- > 0; str++)
+ printf("%c%c ", hexdigits[(*str >> 4) & 0xF],
+ hexdigits[*str & 0xF]);
+}
+
+/*
+ * Print a usage message.
+ */
+void usage(const char *argv0)
+{
+ fprintf(stderr,
+ "Usage:\n"
+ "Common options: [-h hash] [-w|-x] [-H]\n"
+ "Standard tests:\n"
+ "\t%s [-m] [-l loopcount] [-t test#] [-e]\n"
+ "\t\t[-r randomseed] [-R randomloop-count] "
+ "[-p] [-P|-X]\n"
+ "Hash a string:\n"
+ "\t%s [-S expectedresult] -s hashstr [-k key]\n"
+
+
+
+Eastlake 3rd & Hansen Informational [Page 91]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ "Hash a file:\n"
+ "\t%s [-S expectedresult] -f file [-k key]\n"
+ "Hash a file, ignoring whitespace:\n"
+ "\t%s [-S expectedresult] -F file [-k key]\n"
+ "Additional bits to add in: [-B bitcount -b bits]\n"
+ "-h\thash to test: "
+ "0|SHA1, 1|SHA224, 2|SHA256, 3|SHA384, 4|SHA512\n"
+ "-m\tperform hmac test\n"
+ "-k\tkey for hmac test\n"
+ "-t\ttest case to run, 1-10\n"
+ "-l\thow many times to run the test\n"
+ "-e\ttest error returns\n"
+ "-p\tdo not print results\n"
+ "-P\tdo not print PASSED/FAILED\n"
+ "-X\tprint FAILED, but not PASSED\n"
+ "-r\tseed for random test\n"
+ "-R\thow many times to run random test\n"
+ "-s\tstring to hash\n"
+ "-S\texpected result of hashed string, in hex\n"
+ "-w\toutput hash in raw format\n"
+ "-x\toutput hash in hex format\n"
+ "-B\t# extra bits to add in after string or file input\n"
+ "-b\textra bits to add (high order bits of #, 0# or 0x#)\n"
+ "-H\tinput hashstr or randomseed is in hex\n"
+ , argv0, argv0, argv0, argv0);
+ exit(1);
+}
+
+/*
+ * Print the results and PASS/FAIL.
+ */
+void printResult(uint8_t *Message_Digest, int hashsize,
+ const char *hashname, const char *testtype, const char *testname,
+ const char *resultarray, int printResults, int printPassFail)
+{
+ int i, k;
+ if (printResults == PRINTTEXT) {
+ putchar('\t');
+ for (i = 0; i < hashsize ; ++i) {
+ putchar(hexdigits[(Message_Digest[i] >> 4) & 0xF]);
+ putchar(hexdigits[Message_Digest[i] & 0xF]);
+ putchar(' ');
+ }
+ putchar('\n');
+ } else if (printResults == PRINTRAW) {
+ fwrite(Message_Digest, 1, hashsize, stdout);
+ } else if (printResults == PRINTHEX) {
+ for (i = 0; i < hashsize ; ++i) {
+
+
+
+Eastlake 3rd & Hansen Informational [Page 92]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ putchar(hexdigits[(Message_Digest[i] >> 4) & 0xF]);
+ putchar(hexdigits[Message_Digest[i] & 0xF]);
+ }
+ putchar('\n');
+ }
+
+ if (printResults && resultarray) {
+ printf(" Should match:\n\t");
+ for (i = 0, k = 0; i < hashsize; i++, k += 2) {
+ putchar(resultarray[k]);
+ putchar(resultarray[k+1]);
+ putchar(' ');
+ }
+ putchar('\n');
+ }
+
+ if (printPassFail && resultarray) {
+ int ret = checkmatch(Message_Digest, resultarray, hashsize);
+ if ((printPassFail == PRINTPASSFAIL) || !ret)
+ printf("%s %s %s: %s\n", hashname, testtype, testname,
+ ret ? "PASSED" : "FAILED");
+ }
+}
+
+/*
+ * Exercise a hash series of functions. The input is the testarray,
+ * repeated repeatcount times, followed by the extrabits. If the
+ * result is known, it is in resultarray in uppercase hex.
+ */
+int hash(int testno, int loopno, int hashno,
+ const char *testarray, int length, long repeatcount,
+ int numberExtrabits, int extrabits, const unsigned char *keyarray,
+ int keylen, const char *resultarray, int hashsize, int printResults,
+ int printPassFail)
+{
+ USHAContext sha;
+ HMACContext hmac;
+ int err, i;
+ uint8_t Message_Digest[USHAMaxHashSize];
+ char buf[20];
+
+ if (printResults == PRINTTEXT) {
+ printf("\nTest %d: Iteration %d, Repeat %ld\n\t'", testno+1,
+ loopno, repeatcount);
+ printstr(testarray, length);
+ printf("'\n\t'");
+ printxstr(testarray, length);
+ printf("'\n");
+
+
+
+Eastlake 3rd & Hansen Informational [Page 93]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ printf(" Length=%d bytes (%d bits), ", length, length * 8);
+ printf("ExtraBits %d: %2.2x\n", numberExtrabits, extrabits);
+ }
+
+ memset(&sha, '\343', sizeof(sha)); /* force bad data into struct */
+ memset(&hmac, '\343', sizeof(hmac));
+ err = keyarray ? hmacReset(&hmac, hashes[hashno].whichSha,
+ keyarray, keylen) :
+ USHAReset(&sha, hashes[hashno].whichSha);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hash(): %sReset Error %d.\n",
+ keyarray ? "hmac" : "sha", err);
+ return err;
+ }
+
+ for (i = 0; i < repeatcount; ++i) {
+ err = keyarray ? hmacInput(&hmac, (const uint8_t *) testarray,
+ length) :
+ USHAInput(&sha, (const uint8_t *) testarray,
+ length);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hash(): %sInput Error %d.\n",
+ keyarray ? "hmac" : "sha", err);
+ return err;
+ }
+ }
+
+ if (numberExtrabits > 0) {
+ err = keyarray ? hmacFinalBits(&hmac, (uint8_t) extrabits,
+ numberExtrabits) :
+ USHAFinalBits(&sha, (uint8_t) extrabits,
+ numberExtrabits);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hash(): %sFinalBits Error %d.\n",
+ keyarray ? "hmac" : "sha", err);
+ return err;
+ }
+ }
+
+ err = keyarray ? hmacResult(&hmac, Message_Digest) :
+ USHAResult(&sha, Message_Digest);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hash(): %s Result Error %d, could not "
+ "compute message digest.\n", keyarray ? "hmac" : "sha", err);
+ return err;
+ }
+
+ sprintf(buf, "%d", testno+1);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 94]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ printResult(Message_Digest, hashsize, hashes[hashno].name,
+ keyarray ? "hmac standard test" : "sha standard test", buf,
+ resultarray, printResults, printPassFail);
+
+ return err;
+}
+
+/*
+ * Exercise a hash series of functions. The input is a filename.
+ * If the result is known, it is in resultarray in uppercase hex.
+ */
+int hashfile(int hashno, const char *hashfilename, int bits,
+ int bitcount, int skipSpaces, const unsigned char *keyarray,
+ int keylen, const char *resultarray, int hashsize,
+ int printResults, int printPassFail)
+{
+ USHAContext sha;
+ HMACContext hmac;
+ int err, nread, c;
+ unsigned char buf[4096];
+ uint8_t Message_Digest[USHAMaxHashSize];
+ unsigned char cc;
+ FILE *hashfp = (strcmp(hashfilename, "-") == 0) ? stdin :
+ fopen(hashfilename, "r");
+
+ if (!hashfp) {
+ fprintf(stderr, "cannot open file '%s'\n", hashfilename);
+ return shaStateError;
+ }
+
+ memset(&sha, '\343', sizeof(sha)); /* force bad data into struct */
+ memset(&hmac, '\343', sizeof(hmac));
+ err = keyarray ? hmacReset(&hmac, hashes[hashno].whichSha,
+ keyarray, keylen) :
+ USHAReset(&sha, hashes[hashno].whichSha);
+
+ if (err != shaSuccess) {
+ fprintf(stderr, "hashfile(): %sReset Error %d.\n",
+ keyarray ? "hmac" : "sha", err);
+ return err;
+ }
+
+ if (skipSpaces)
+ while ((c = getc(hashfp)) != EOF) {
+ if (!isspace(c)) {
+ cc = (unsigned char)c;
+ err = keyarray ? hmacInput(&hmac, &cc, 1) :
+ USHAInput(&sha, &cc, 1);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 95]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ if (err != shaSuccess) {
+ fprintf(stderr, "hashfile(): %sInput Error %d.\n",
+ keyarray ? "hmac" : "sha", err);
+ if (hashfp != stdin) fclose(hashfp);
+ return err;
+ }
+ }
+ }
+ else
+ while ((nread = fread(buf, 1, sizeof(buf), hashfp)) > 0) {
+ err = keyarray ? hmacInput(&hmac, buf, nread) :
+ USHAInput(&sha, buf, nread);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hashfile(): %s Error %d.\n",
+ keyarray ? "hmacInput" : "shaInput", err);
+ if (hashfp != stdin) fclose(hashfp);
+ return err;
+ }
+ }
+
+ if (bitcount > 0)
+ err = keyarray ? hmacFinalBits(&hmac, bits, bitcount) :
+ USHAFinalBits(&sha, bits, bitcount);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hashfile(): %s Error %d.\n",
+ keyarray ? "hmacResult" : "shaResult", err);
+ if (hashfp != stdin) fclose(hashfp);
+ return err;
+ }
+
+ err = keyarray ? hmacResult(&hmac, Message_Digest) :
+ USHAResult(&sha, Message_Digest);
+ if (err != shaSuccess) {
+ fprintf(stderr, "hashfile(): %s Error %d.\n",
+ keyarray ? "hmacResult" : "shaResult", err);
+ if (hashfp != stdin) fclose(hashfp);
+ return err;
+ }
+
+ printResult(Message_Digest, hashsize, hashes[hashno].name, "file",
+ hashfilename, resultarray, printResults, printPassFail);
+
+ if (hashfp != stdin) fclose(hashfp);
+ return err;
+}
+
+/*
+ * Exercise a hash series of functions through multiple permutations.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 96]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ * The input is an initial seed. That seed is replicated 3 times.
+ * For 1000 rounds, the previous three results are used as the input.
+ * This result is then checked, and used to seed the next cycle.
+ * If the result is known, it is in resultarrays in uppercase hex.
+ */
+void randomtest(int hashno, const char *seed, int hashsize,
+ const char **resultarrays, int randomcount,
+ int printResults, int printPassFail)
+{
+ int i, j; char buf[20];
+ unsigned char SEED[USHAMaxHashSize], MD[1003][USHAMaxHashSize];
+
+ /* INPUT: Seed - A random seed n bits long */
+ memcpy(SEED, seed, hashsize);
+ if (printResults == PRINTTEXT) {
+ printf("%s random test seed= '", hashes[hashno].name);
+ printxstr(seed, hashsize);
+ printf("'\n");
+ }
+
+ for (j = 0; j < randomcount; j++) {
+ /* MD0 = MD1 = MD2 = Seed; */
+ memcpy(MD[0], SEED, hashsize);
+ memcpy(MD[1], SEED, hashsize);
+ memcpy(MD[2], SEED, hashsize);
+ for (i=3; i<1003; i++) {
+ /* Mi = MDi-3 || MDi-2 || MDi-1; */
+ USHAContext Mi;
+ memset(&Mi, '\343', sizeof(Mi)); /* force bad data into struct */
+ USHAReset(&Mi, hashes[hashno].whichSha);
+ USHAInput(&Mi, MD[i-3], hashsize);
+ USHAInput(&Mi, MD[i-2], hashsize);
+ USHAInput(&Mi, MD[i-1], hashsize);
+ /* MDi = SHA(Mi); */
+ USHAResult(&Mi, MD[i]);
+ }
+
+ /* MDj = Seed = MDi; */
+ memcpy(SEED, MD[i-1], hashsize);
+
+ /* OUTPUT: MDj */
+ sprintf(buf, "%d", j);
+ printResult(SEED, hashsize, hashes[hashno].name, "random test",
+ buf, resultarrays ? resultarrays[j] : 0, printResults,
+ (j < RANDOMCOUNT) ? printPassFail : 0);
+ }
+}
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 97]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+/*
+ * Look up a hash name.
+ */
+int findhash(const char *argv0, const char *opt)
+{
+ int i;
+ const char *names[HASHCOUNT][2] = {
+ { "0", "sha1" }, { "1", "sha224" }, { "2", "sha256" },
+ { "3", "sha384" }, { "4", "sha512" }
+ };
+
+ for (i = 0; i < HASHCOUNT; i++)
+ if ((strcmp(opt, names[i][0]) == 0) ||
+ (scasecmp(opt, names[i][1]) == 0))
+ return i;
+
+ fprintf(stderr, "%s: Unknown hash name: '%s'\n", argv0, opt);
+ usage(argv0);
+ return 0;
+}
+
+/*
+ * Run some tests that should invoke errors.
+ */
+void testErrors(int hashnolow, int hashnohigh, int printResults,
+ int printPassFail)
+{
+ USHAContext usha;
+ uint8_t Message_Digest[USHAMaxHashSize];
+ int hashno, err;
+
+ for (hashno = hashnolow; hashno <= hashnohigh; hashno++) {
+ memset(&usha, '\343', sizeof(usha)); /* force bad data */
+ USHAReset(&usha, hashno);
+ USHAResult(&usha, Message_Digest);
+ err = USHAInput(&usha, (const unsigned char *)"foo", 3);
+ if (printResults == PRINTTEXT)
+ printf ("\nError %d. Should be %d.\n", err, shaStateError);
+ if ((printPassFail == PRINTPASSFAIL) ||
+ ((printPassFail == PRINTFAIL) && (err != shaStateError)))
+ printf("%s se: %s\n", hashes[hashno].name,
+ (err == shaStateError) ? "PASSED" : "FAILED");
+
+ err = USHAFinalBits(&usha, 0x80, 3);
+ if (printResults == PRINTTEXT)
+ printf ("\nError %d. Should be %d.\n", err, shaStateError);
+ if ((printPassFail == PRINTPASSFAIL) ||
+ ((printPassFail == PRINTFAIL) && (err != shaStateError)))
+
+
+
+Eastlake 3rd & Hansen Informational [Page 98]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ printf("%s se: %s\n", hashes[hashno].name,
+ (err == shaStateError) ? "PASSED" : "FAILED");
+
+ err = USHAReset(0, hashes[hashno].whichSha);
+ if (printResults == PRINTTEXT)
+ printf("\nError %d. Should be %d.\n", err, shaNull);
+ if ((printPassFail == PRINTPASSFAIL) ||
+ ((printPassFail == PRINTFAIL) && (err != shaNull)))
+ printf("%s usha null: %s\n", hashes[hashno].name,
+ (err == shaNull) ? "PASSED" : "FAILED");
+
+ switch (hashno) {
+ case SHA1: err = SHA1Reset(0); break;
+ case SHA224: err = SHA224Reset(0); break;
+ case SHA256: err = SHA256Reset(0); break;
+ case SHA384: err = SHA384Reset(0); break;
+ case SHA512: err = SHA512Reset(0); break;
+ }
+ if (printResults == PRINTTEXT)
+ printf("\nError %d. Should be %d.\n", err, shaNull);
+ if ((printPassFail == PRINTPASSFAIL) ||
+ ((printPassFail == PRINTFAIL) && (err != shaNull)))
+ printf("%s sha null: %s\n", hashes[hashno].name,
+ (err == shaNull) ? "PASSED" : "FAILED");
+ }
+}
+
+/* replace a hex string in place with its value */
+int unhexStr(char *hexstr)
+{
+ char *o = hexstr;
+ int len = 0, nibble1 = 0, nibble2 = 0;
+ if (!hexstr) return 0;
+ for ( ; *hexstr; hexstr++) {
+ if (isalpha((int)(unsigned char)(*hexstr))) {
+ nibble1 = tolower(*hexstr) - 'a' + 10;
+ } else if (isdigit((int)(unsigned char)(*hexstr))) {
+ nibble1 = *hexstr - '0';
+ } else {
+ printf("\nError: bad hex character '%c'\n", *hexstr);
+ }
+ if (!*++hexstr) break;
+ if (isalpha((int)(unsigned char)(*hexstr))) {
+ nibble2 = tolower(*hexstr) - 'a' + 10;
+ } else if (isdigit((int)(unsigned char)(*hexstr))) {
+ nibble2 = *hexstr - '0';
+ } else {
+ printf("\nError: bad hex character '%c'\n", *hexstr);
+
+
+
+Eastlake 3rd & Hansen Informational [Page 99]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ }
+ *o++ = (char)((nibble1 << 4) | nibble2);
+ len++;
+ }
+ return len;
+}
+
+int main(int argc, char **argv)
+{
+ int i, err;
+ int loopno, loopnohigh = 1;
+ int hashno, hashnolow = 0, hashnohigh = HASHCOUNT - 1;
+ int testno, testnolow = 0, testnohigh;
+ int ntestnohigh = 0;
+ int printResults = PRINTTEXT;
+ int printPassFail = 1;
+ int checkErrors = 0;
+ char *hashstr = 0;
+ int hashlen = 0;
+ const char *resultstr = 0;
+ char *randomseedstr = 0;
+ int runHmacTests = 0;
+ char *hmacKey = 0;
+ int hmaclen = 0;
+ int randomcount = RANDOMCOUNT;
+ const char *hashfilename = 0;
+ const char *hashFilename = 0;
+ int extrabits = 0, numberExtrabits = 0;
+ int strIsHex = 0;
+
+ while ((i = xgetopt(argc, argv, "b:B:ef:F:h:Hk:l:mpPr:R:s:S:t:wxX"))
+ != -1)
+ switch (i) {
+ case 'b': extrabits = strtol(xoptarg, 0, 0); break;
+ case 'B': numberExtrabits = atoi(xoptarg); break;
+ case 'e': checkErrors = 1; break;
+ case 'f': hashfilename = xoptarg; break;
+ case 'F': hashFilename = xoptarg; break;
+ case 'h': hashnolow = hashnohigh = findhash(argv[0], xoptarg);
+ break;
+ case 'H': strIsHex = 1; break;
+ case 'k': hmacKey = xoptarg; hmaclen = strlen(xoptarg); break;
+ case 'l': loopnohigh = atoi(xoptarg); break;
+ case 'm': runHmacTests = 1; break;
+ case 'P': printPassFail = 0; break;
+ case 'p': printResults = PRINTNONE; break;
+ case 'R': randomcount = atoi(xoptarg); break;
+ case 'r': randomseedstr = xoptarg; break;
+
+
+
+Eastlake 3rd & Hansen Informational [Page 100]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ case 's': hashstr = xoptarg; hashlen = strlen(hashstr); break;
+ case 'S': resultstr = xoptarg; break;
+ case 't': testnolow = ntestnohigh = atoi(xoptarg) - 1; break;
+ case 'w': printResults = PRINTRAW; break;
+ case 'x': printResults = PRINTHEX; break;
+ case 'X': printPassFail = 2; break;
+ default: usage(argv[0]);
+ }
+
+ if (strIsHex) {
+ hashlen = unhexStr(hashstr);
+ unhexStr(randomseedstr);
+ hmaclen = unhexStr(hmacKey);
+ }
+ testnohigh = (ntestnohigh != 0) ? ntestnohigh:
+ runHmacTests ? (HMACTESTCOUNT-1) : (TESTCOUNT-1);
+ if ((testnolow < 0) ||
+ (testnohigh >= (runHmacTests ? HMACTESTCOUNT : TESTCOUNT)) ||
+ (hashnolow < 0) || (hashnohigh >= HASHCOUNT) ||
+ (hashstr && (testnolow == testnohigh)) ||
+ (randomcount < 0) ||
+ (resultstr && (!hashstr && !hashfilename && !hashFilename)) ||
+ ((runHmacTests || hmacKey) && randomseedstr) ||
+ (hashfilename && hashFilename))
+ usage(argv[0]);
+
+ /*
+ * Perform SHA/HMAC tests
+ */
+ for (hashno = hashnolow; hashno <= hashnohigh; ++hashno) {
+ if (printResults == PRINTTEXT)
+ printf("Hash %s\n", hashes[hashno].name);
+ err = shaSuccess;
+
+ for (loopno = 1; (loopno <= loopnohigh) && (err == shaSuccess);
+ ++loopno) {
+ if (hashstr)
+ err = hash(0, loopno, hashno, hashstr, hashlen, 1,
+ numberExtrabits, extrabits, (const unsigned char *)hmacKey,
+ hmaclen, resultstr, hashes[hashno].hashsize, printResults,
+ printPassFail);
+
+ else if (randomseedstr)
+ randomtest(hashno, randomseedstr, hashes[hashno].hashsize, 0,
+ randomcount, printResults, printPassFail);
+
+ else if (hashfilename)
+ err = hashfile(hashno, hashfilename, extrabits,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 101]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ numberExtrabits, 0,
+ (const unsigned char *)hmacKey, hmaclen,
+ resultstr, hashes[hashno].hashsize,
+ printResults, printPassFail);
+
+ else if (hashFilename)
+ err = hashfile(hashno, hashFilename, extrabits,
+ numberExtrabits, 1,
+ (const unsigned char *)hmacKey, hmaclen,
+ resultstr, hashes[hashno].hashsize,
+ printResults, printPassFail);
+
+ else /* standard tests */ {
+ for (testno = testnolow;
+ (testno <= testnohigh) && (err == shaSuccess); ++testno) {
+ if (runHmacTests) {
+ err = hash(testno, loopno, hashno,
+ hmachashes[testno].dataarray[hashno] ?
+ hmachashes[testno].dataarray[hashno] :
+ hmachashes[testno].dataarray[1] ?
+ hmachashes[testno].dataarray[1] :
+ hmachashes[testno].dataarray[0],
+ hmachashes[testno].datalength[hashno] ?
+ hmachashes[testno].datalength[hashno] :
+ hmachashes[testno].datalength[1] ?
+ hmachashes[testno].datalength[1] :
+ hmachashes[testno].datalength[0],
+ 1, 0, 0,
+ (const unsigned char *)(
+ hmachashes[testno].keyarray[hashno] ?
+ hmachashes[testno].keyarray[hashno] :
+ hmachashes[testno].keyarray[1] ?
+ hmachashes[testno].keyarray[1] :
+ hmachashes[testno].keyarray[0]),
+ hmachashes[testno].keylength[hashno] ?
+ hmachashes[testno].keylength[hashno] :
+ hmachashes[testno].keylength[1] ?
+ hmachashes[testno].keylength[1] :
+ hmachashes[testno].keylength[0],
+ hmachashes[testno].resultarray[hashno],
+ hmachashes[testno].resultlength[hashno],
+ printResults, printPassFail);
+ } else {
+ err = hash(testno, loopno, hashno,
+ hashes[hashno].tests[testno].testarray,
+ hashes[hashno].tests[testno].length,
+ hashes[hashno].tests[testno].repeatcount,
+ hashes[hashno].tests[testno].numberExtrabits,
+
+
+
+Eastlake 3rd & Hansen Informational [Page 102]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ hashes[hashno].tests[testno].extrabits, 0, 0,
+ hashes[hashno].tests[testno].resultarray,
+ hashes[hashno].hashsize,
+ printResults, printPassFail);
+ }
+ }
+
+ if (!runHmacTests) {
+ randomtest(hashno, hashes[hashno].randomtest,
+ hashes[hashno].hashsize, hashes[hashno].randomresults,
+ RANDOMCOUNT, printResults, printPassFail);
+ }
+ }
+ }
+ }
+
+ /* Test some error returns */
+ if (checkErrors) {
+ testErrors(hashnolow, hashnohigh, printResults, printPassFail);
+ }
+
+ return 0;
+}
+
+/*
+ * Compare two strings, case independently.
+ * Equivalent to strcasecmp() found on some systems.
+ */
+int scasecmp(const char *s1, const char *s2)
+{
+ for (;;) {
+ char u1 = tolower(*s1++);
+ char u2 = tolower(*s2++);
+ if (u1 != u2)
+ return u1 - u2;
+ if (u1 == '\0')
+ return 0;
+ }
+}
+
+/*
+ * This is a copy of getopt provided for those systems that do not
+ * have it. The name was changed to xgetopt to not conflict on those
+ * systems that do have it. Similarly, optarg, optind and opterr
+ * were renamed to xoptarg, xoptind and xopterr.
+ *
+ * Copyright 1990, 1991, 1992 by the Massachusetts Institute of
+ * Technology and UniSoft Group Limited.
+
+
+
+Eastlake 3rd & Hansen Informational [Page 103]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ *
+ * Permission to use, copy, modify, distribute, and sell this software
+ * and its documentation for any purpose is hereby granted without fee,
+ * provided that the above copyright notice appear in all copies and
+ * that both that copyright notice and this permission notice appear in
+ * supporting documentation, and that the names of MIT and UniSoft not
+ * be used in advertising or publicity pertaining to distribution of
+ * the software without specific, written prior permission. MIT and
+ * UniSoft make no representations about the suitability of this
+ * software for any purpose. It is provided "as is" without express
+ * or implied warranty.
+ *
+ * $XConsortium: getopt.c,v 1.2 92/07/01 11:59:04 rws Exp $
+ * NB: Reformatted to match above style.
+ */
+
+char *xoptarg;
+int xoptind = 1;
+int xopterr = 1;
+
+static int xgetopt(int argc, char **argv, const char *optstring)
+{
+ static int avplace;
+ char *ap;
+ char *cp;
+ int c;
+
+ if (xoptind >= argc)
+ return EOF;
+
+ ap = argv[xoptind] + avplace;
+
+ /* At beginning of arg but not an option */
+ if (avplace == 0) {
+ if (ap[0] != '-')
+ return EOF;
+ else if (ap[1] == '-') {
+ /* Special end of options option */
+ xoptind++;
+ return EOF;
+ } else if (ap[1] == '\0')
+ return EOF; /* single '-' is not allowed */
+ }
+
+ /* Get next letter */
+ avplace++;
+ c = *++ap;
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 104]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+ cp = strchr(optstring, c);
+ if (cp == NULL || c == ':') {
+ if (xopterr)
+ fprintf(stderr, "Unrecognised option -- %c\n", c);
+ return '?';
+ }
+
+ if (cp[1] == ':') {
+ /* There should be an option arg */
+ avplace = 0;
+ if (ap[1] == '\0') {
+ /* It is a separate arg */
+ if (++xoptind >= argc) {
+ if (xopterr)
+ fprintf(stderr, "Option requires an argument\n");
+ return '?';
+ }
+ xoptarg = argv[xoptind++];
+ } else {
+ /* is attached to option letter */
+ xoptarg = ap + 1;
+ ++xoptind;
+ }
+ } else {
+ /* If we are out of letters then go to next arg */
+ if (ap[1] == '\0') {
+ ++xoptind;
+ avplace = 0;
+ }
+
+ xoptarg = NULL;
+ }
+ return c;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 105]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+9. Security Considerations
+
+ This document is intended to provides the Internet community
+ convenient access to source code that implements the United States of
+ America Federal Information Processing Standard Secure Hash
+ Algorithms (SHAs) [FIPS180-2] and HMACs based upon these one-way hash
+ functions. See license in Section 1.1. No independent assertion of
+ the security of this hash function by the authors for any particular
+ use is intended.
+
+10. Normative References
+
+ [FIPS180-2] "Secure Hash Standard", United States of America,
+ National Institute of Standards and Technology, Federal
+ Information Processing Standard (FIPS) 180-2,
+ http://csrc.nist.gov/publications/fips/fips180-2/
+ fips180-2withchangenotice.pdf.
+
+ [RFC2104] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
+ Hashing for Message Authentication", RFC 2104, February
+ 1997.
+
+11. Informative References
+
+ [RFC2202] Cheng, P. and R. Glenn, "Test Cases for HMAC-MD5 and
+ HMAC-SHA-1", RFC 2202, September 1997.
+
+ [RFC3174] Eastlake 3rd, D. and P. Jones, "US Secure Hash Algorithm
+ 1 (SHA1)", RFC 3174, September 2001.
+
+ [RFC3874] Housley, R., "A 224-bit One-way Hash Function: SHA-224",
+ RFC 3874, September 2004.
+
+ [RFC4086] Eastlake, D., 3rd, Schiller, J., and S. Crocker,
+ "Randomness Requirements for Security", BCP 106, RFC
+ 4086, June 2005.
+
+ [RFC4231] Nystrom, M., "Identifiers and Test Vectors for HMAC-SHA-
+ 224, HMAC-SHA-256, HMAC-SHA-384, and HMAC-SHA-512", RFC
+ 4231, December 2005.
+
+ [SHAVS] "The Secure Hash Algorithm Validation System (SHAVS)",
+ http://csrc.nist.gov/cryptval/shs/SHAVS.pdf.
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 106]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+Authors' Addresses
+
+ Donald E. Eastlake, 3rd
+ Motorola Laboratories
+ 155 Beaver Street
+ Milford, MA 01757 USA
+
+ Phone: +1-508-786-7554 (w)
+ EMail: donald.eastlake@motorola.com
+
+
+ Tony Hansen
+ AT&T Laboratories
+ 200 Laurel Ave.
+ Middletown, NJ 07748 USA
+
+ Phone: +1-732-420-8934 (w)
+ EMail: tony+shs@maillennium.att.com
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 107]
+
+RFC 4634 SHAs and HMAC-SHAs July 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Eastlake 3rd & Hansen Informational [Page 108]
+
diff --git a/contrib/bind9/doc/rfc/rfc4641.txt b/contrib/bind9/doc/rfc/rfc4641.txt
new file mode 100644
index 000000000000..0a013bcba5a8
--- /dev/null
+++ b/contrib/bind9/doc/rfc/rfc4641.txt
@@ -0,0 +1,1963 @@
+
+
+
+
+
+
+Network Working Group O. Kolkman
+Request for Comments: 4641 R. Gieben
+Obsoletes: 2541 NLnet Labs
+Category: Informational September 2006
+
+
+ DNSSEC Operational Practices
+
+Status of This Memo
+
+ This memo provides information for the Internet community. It does
+ not specify an Internet standard of any kind. Distribution of this
+ memo is unlimited.
+
+Copyright Notice
+
+ Copyright (C) The Internet Society (2006).
+
+Abstract
+
+ This document describes a set of practices for operating the DNS with
+ security extensions (DNSSEC). The target audience is zone
+ administrators deploying DNSSEC.
+
+ The document discusses operational aspects of using keys and
+ signatures in the DNS. It discusses issues of key generation, key
+ storage, signature generation, key rollover, and related policies.
+
+ This document obsoletes RFC 2541, as it covers more operational
+ ground and gives more up-to-date requirements with respect to key
+ sizes and the new DNSSEC specification.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 1]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+Table of Contents
+
+ 1. Introduction ....................................................3
+ 1.1. The Use of the Term 'key' ..................................4
+ 1.2. Time Definitions ...........................................4
+ 2. Keeping the Chain of Trust Intact ...............................5
+ 3. Keys Generation and Storage .....................................6
+ 3.1. Zone and Key Signing Keys ..................................6
+ 3.1.1. Motivations for the KSK and ZSK Separation ..........6
+ 3.1.2. KSKs for High-Level Zones ...........................7
+ 3.2. Key Generation .............................................8
+ 3.3. Key Effectivity Period .....................................8
+ 3.4. Key Algorithm ..............................................9
+ 3.5. Key Sizes ..................................................9
+ 3.6. Private Key Storage .......................................11
+ 4. Signature Generation, Key Rollover, and Related Policies .......12
+ 4.1. Time in DNSSEC ............................................12
+ 4.1.1. Time Considerations ................................12
+ 4.2. Key Rollovers .............................................14
+ 4.2.1. Zone Signing Key Rollovers .........................14
+ 4.2.1.1. Pre-Publish Key Rollover ..................15
+ 4.2.1.2. Double Signature Zone Signing Key
+ Rollover ..................................17
+ 4.2.1.3. Pros and Cons of the Schemes ..............18
+ 4.2.2. Key Signing Key Rollovers ..........................18
+ 4.2.3. Difference Between ZSK and KSK Rollovers ...........20
+ 4.2.4. Automated Key Rollovers ............................21
+ 4.3. Planning for Emergency Key Rollover .......................21
+ 4.3.1. KSK Compromise .....................................22
+ 4.3.1.1. Keeping the Chain of Trust Intact .........22
+ 4.3.1.2. Breaking the Chain of Trust ...............23
+ 4.3.2. ZSK Compromise .....................................23
+ 4.3.3. Compromises of Keys Anchored in Resolvers ..........24
+ 4.4. Parental Policies .........................................24
+ 4.4.1. Initial Key Exchanges and Parental Policies
+ Considerations .....................................24
+ 4.4.2. Storing Keys or Hashes? ............................25
+ 4.4.3. Security Lameness ..................................25
+ 4.4.4. DS Signature Validity Period .......................26
+ 5. Security Considerations ........................................26
+ 6. Acknowledgments ................................................26
+ 7. References .....................................................27
+ 7.1. Normative References ......................................27
+ 7.2. Informative References ....................................28
+ Appendix A. Terminology ...........................................30
+ Appendix B. Zone Signing Key Rollover How-To ......................31
+ Appendix C. Typographic Conventions ...............................32
+
+
+
+
+Kolkman & Gieben Informational [Page 2]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+1. Introduction
+
+ This document describes how to run a DNS Security (DNSSEC)-enabled
+ environment. It is intended for operators who have knowledge of the
+ DNS (see RFC 1034 [1] and RFC 1035 [2]) and want to deploy DNSSEC.
+ See RFC 4033 [4] for an introduction to DNSSEC, RFC 4034 [5] for the
+ newly introduced Resource Records (RRs), and RFC 4035 [6] for the
+ protocol changes.
+
+ During workshops and early operational deployment tests, operators
+ and system administrators have gained experience about operating the
+ DNS with security extensions (DNSSEC). This document translates
+ these experiences into a set of practices for zone administrators.
+ At the time of writing, there exists very little experience with
+ DNSSEC in production environments; this document should therefore
+ explicitly not be seen as representing 'Best Current Practices'.
+
+ The procedures herein are focused on the maintenance of signed zones
+ (i.e., signing and publishing zones on authoritative servers). It is
+ intended that maintenance of zones such as re-signing or key
+ rollovers be transparent to any verifying clients on the Internet.
+
+ The structure of this document is as follows. In Section 2, we
+ discuss the importance of keeping the "chain of trust" intact.
+ Aspects of key generation and storage of private keys are discussed
+ in Section 3; the focus in this section is mainly on the private part
+ of the key(s). Section 4 describes considerations concerning the
+ public part of the keys. Since these public keys appear in the DNS
+ one has to take into account all kinds of timing issues, which are
+ discussed in Section 4.1. Section 4.2 and Section 4.3 deal with the
+ rollover, or supercession, of keys. Finally, Section 4.4 discusses
+ considerations on how parents deal with their children's public keys
+ in order to maintain chains of trust.
+
+ The typographic conventions used in this document are explained in
+ Appendix C.
+
+ Since this is a document with operational suggestions and there are
+ no protocol specifications, the RFC 2119 [7] language does not apply.
+
+ This document obsoletes RFC 2541 [12] to reflect the evolution of the
+ underlying DNSSEC protocol since then. Changes in the choice of
+ cryptographic algorithms, DNS record types and type names, and the
+ parent-child key and signature exchange demanded a major rewrite and
+ additional information and explanation.
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 3]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+1.1. The Use of the Term 'key'
+
+ It is assumed that the reader is familiar with the concept of
+ asymmetric keys on which DNSSEC is based (public key cryptography
+ [17]). Therefore, this document will use the term 'key' rather
+ loosely. Where it is written that 'a key is used to sign data' it is
+ assumed that the reader understands that it is the private part of
+ the key pair that is used for signing. It is also assumed that the
+ reader understands that the public part of the key pair is published
+ in the DNSKEY Resource Record and that it is the public part that is
+ used in key exchanges.
+
+1.2. Time Definitions
+
+ In this document, we will be using a number of time-related terms.
+ The following definitions apply:
+
+ o "Signature validity period" The period that a signature is valid.
+ It starts at the time specified in the signature inception field
+ of the RRSIG RR and ends at the time specified in the expiration
+ field of the RRSIG RR.
+
+ o "Signature publication period" Time after which a signature (made
+ with a specific key) is replaced with a new signature (made with
+ the same key). This replacement takes place by publishing the
+ relevant RRSIG in the master zone file. After one stops
+ publishing an RRSIG in a zone, it may take a while before the
+ RRSIG has expired from caches and has actually been removed from
+ the DNS.
+
+ o "Key effectivity period" The period during which a key pair is
+ expected to be effective. This period is defined as the time
+ between the first inception time stamp and the last expiration
+ date of any signature made with this key, regardless of any
+ discontinuity in the use of the key. The key effectivity period
+ can span multiple signature validity periods.
+
+ o "Maximum/Minimum Zone Time to Live (TTL)" The maximum or minimum
+ value of the TTLs from the complete set of RRs in a zone. Note
+ that the minimum TTL is not the same as the MINIMUM field in the
+ SOA RR. See [11] for more information.
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 4]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+2. Keeping the Chain of Trust Intact
+
+ Maintaining a valid chain of trust is important because broken chains
+ of trust will result in data being marked as Bogus (as defined in [4]
+ Section 5), which may cause entire (sub)domains to become invisible
+ to verifying clients. The administrators of secured zones have to
+ realize that their zone is, to verifying clients, part of a chain of
+ trust.
+
+ As mentioned in the introduction, the procedures herein are intended
+ to ensure that maintenance of zones, such as re-signing or key
+ rollovers, will be transparent to the verifying clients on the
+ Internet.
+
+ Administrators of secured zones will have to keep in mind that data
+ published on an authoritative primary server will not be immediately
+ seen by verifying clients; it may take some time for the data to be
+ transferred to other secondary authoritative nameservers and clients
+ may be fetching data from caching non-authoritative servers. In this
+ light, note that the time for a zone transfer from master to slave is
+ negligible when using NOTIFY [9] and incremental transfer (IXFR) [8].
+ It increases when full zone transfers (AXFR) are used in combination
+ with NOTIFY. It increases even more if you rely on full zone
+ transfers based on only the SOA timing parameters for refresh.
+
+ For the verifying clients, it is important that data from secured
+ zones can be used to build chains of trust regardless of whether the
+ data came directly from an authoritative server, a caching
+ nameserver, or some middle box. Only by carefully using the
+ available timing parameters can a zone administrator ensure that the
+ data necessary for verification can be obtained.
+
+ The responsibility for maintaining the chain of trust is shared by
+ administrators of secured zones in the chain of trust. This is most
+ obvious in the case of a 'key compromise' when a trade-off between
+ maintaining a valid chain of trust and replacing the compromised keys
+ as soon as possible must be made. Then zone administrators will have
+ to make a trade-off, between keeping the chain of trust intact --
+ thereby allowing for attacks with the compromised key -- or
+ deliberately breaking the chain of trust and making secured
+ subdomains invisible to security-aware resolvers. Also see Section
+ 4.3.
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 5]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+3. Keys Generation and Storage
+
+ This section describes a number of considerations with respect to the
+ security of keys. It deals with the generation, effectivity period,
+ size, and storage of private keys.
+
+3.1. Zone and Key Signing Keys
+
+ The DNSSEC validation protocol does not distinguish between different
+ types of DNSKEYs. All DNSKEYs can be used during the validation. In
+ practice, operators use Key Signing and Zone Signing Keys and use the
+ so-called Secure Entry Point (SEP) [3] flag to distinguish between
+ them during operations. The dynamics and considerations are
+ discussed below.
+
+ To make zone re-signing and key rollover procedures easier to
+ implement, it is possible to use one or more keys as Key Signing Keys
+ (KSKs). These keys will only sign the apex DNSKEY RRSet in a zone.
+ Other keys can be used to sign all the RRSets in a zone and are
+ referred to as Zone Signing Keys (ZSKs). In this document, we assume
+ that KSKs are the subset of keys that are used for key exchanges with
+ the parent and potentially for configuration as trusted anchors --
+ the SEP keys. In this document, we assume a one-to-one mapping
+ between KSK and SEP keys and we assume the SEP flag to be set on all
+ KSKs.
+
+3.1.1. Motivations for the KSK and ZSK Separation
+
+ Differentiating between the KSK and ZSK functions has several
+ advantages:
+
+ o No parent/child interaction is required when ZSKs are updated.
+
+ o The KSK can be made stronger (i.e., using more bits in the key
+ material). This has little operational impact since it is only
+ used to sign a small fraction of the zone data. Also, the KSK is
+ only used to verify the zone's key set, not for other RRSets in
+ the zone.
+
+ o As the KSK is only used to sign a key set, which is most probably
+ updated less frequently than other data in the zone, it can be
+ stored separately from and in a safer location than the ZSK.
+
+ o A KSK can have a longer key effectivity period.
+
+ For almost any method of key management and zone signing, the KSK is
+ used less frequently than the ZSK. Once a key set is signed with the
+ KSK, all the keys in the key set can be used as ZSKs. If a ZSK is
+
+
+
+Kolkman & Gieben Informational [Page 6]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ compromised, it can be simply dropped from the key set. The new key
+ set is then re-signed with the KSK.
+
+ Given the assumption that for KSKs the SEP flag is set, the KSK can
+ be distinguished from a ZSK by examining the flag field in the DNSKEY
+ RR. If the flag field is an odd number it is a KSK. If it is an
+ even number it is a ZSK.
+
+ The Zone Signing Key can be used to sign all the data in a zone on a
+ regular basis. When a Zone Signing Key is to be rolled, no
+ interaction with the parent is needed. This allows for signature
+ validity periods on the order of days.
+
+ The Key Signing Key is only to be used to sign the DNSKEY RRs in a
+ zone. If a Key Signing Key is to be rolled over, there will be
+ interactions with parties other than the zone administrator. These
+ can include the registry of the parent zone or administrators of
+ verifying resolvers that have the particular key configured as secure
+ entry points. Hence, the key effectivity period of these keys can
+ and should be made much longer. Although, given a long enough key,
+ the key effectivity period can be on the order of years, we suggest
+ planning for a key effectivity on the order of a few months so that a
+ key rollover remains an operational routine.
+
+3.1.2. KSKs for High-Level Zones
+
+ Higher-level zones are generally more sensitive than lower-level
+ zones. Anyone controlling or breaking the security of a zone thereby
+ obtains authority over all of its subdomains (except in the case of
+ resolvers that have locally configured the public key of a subdomain,
+ in which case this, and only this, subdomain wouldn't be affected by
+ the compromise of the parent zone). Therefore, extra care should be
+ taken with high-level zones, and strong keys should be used.
+
+ The root zone is the most critical of all zones. Someone controlling
+ or compromising the security of the root zone would control the
+ entire DNS namespace of all resolvers using that root zone (except in
+ the case of resolvers that have locally configured the public key of
+ a subdomain). Therefore, the utmost care must be taken in the
+ securing of the root zone. The strongest and most carefully handled
+ keys should be used. The root zone private key should always be kept
+ off-line.
+
+ Many resolvers will start at a root server for their access to and
+ authentication of DNS data. Securely updating the trust anchors in
+ an enormous population of resolvers around the world will be
+ extremely difficult.
+
+
+
+
+Kolkman & Gieben Informational [Page 7]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+3.2. Key Generation
+
+ Careful generation of all keys is a sometimes overlooked but
+ absolutely essential element in any cryptographically secure system.
+ The strongest algorithms used with the longest keys are still of no
+ use if an adversary can guess enough to lower the size of the likely
+ key space so that it can be exhaustively searched. Technical
+ suggestions for the generation of random keys will be found in RFC
+ 4086 [14]. One should carefully assess if the random number
+ generator used during key generation adheres to these suggestions.
+
+ Keys with a long effectivity period are particularly sensitive as
+ they will represent a more valuable target and be subject to attack
+ for a longer time than short-period keys. It is strongly recommended
+ that long-term key generation occur off-line in a manner isolated
+ from the network via an air gap or, at a minimum, high-level secure
+ hardware.
+
+3.3. Key Effectivity Period
+
+ For various reasons, keys in DNSSEC need to be changed once in a
+ while. The longer a key is in use, the greater the probability that
+ it will have been compromised through carelessness, accident,
+ espionage, or cryptanalysis. Furthermore, when key rollovers are too
+ rare an event, they will not become part of the operational habit and
+ there is risk that nobody on-site will remember the procedure for
+ rollover when the need is there.
+
+ From a purely operational perspective, a reasonable key effectivity
+ period for Key Signing Keys is 13 months, with the intent to replace
+ them after 12 months. An intended key effectivity period of a month
+ is reasonable for Zone Signing Keys.
+
+ For key sizes that match these effectivity periods, see Section 3.5.
+
+ As argued in Section 3.1.2, securely updating trust anchors will be
+ extremely difficult. On the other hand, the "operational habit"
+ argument does also apply to trust anchor reconfiguration. If a short
+ key effectivity period is used and the trust anchor configuration has
+ to be revisited on a regular basis, the odds that the configuration
+ tends to be forgotten is smaller. The trade-off is against a system
+ that is so dynamic that administrators of the validating clients will
+ not be able to follow the modifications.
+
+ Key effectivity periods can be made very short, as in a few minutes.
+ But when replacing keys one has to take the considerations from
+ Section 4.1 and Section 4.2 into account.
+
+
+
+
+Kolkman & Gieben Informational [Page 8]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+3.4. Key Algorithm
+
+ There are currently three different types of algorithms that can be
+ used in DNSSEC: RSA, DSA, and elliptic curve cryptography. The
+ latter is fairly new and has yet to be standardized for usage in
+ DNSSEC.
+
+ RSA has been developed in an open and transparent manner. As the
+ patent on RSA expired in 2000, its use is now also free.
+
+ DSA has been developed by the National Institute of Standards and
+ Technology (NIST). The creation of signatures takes roughly the same
+ time as with RSA, but is 10 to 40 times as slow for verification
+ [17].
+
+ We suggest the use of RSA/SHA-1 as the preferred algorithm for the
+ key. The current known attacks on RSA can be defeated by making your
+ key longer. As the MD5 hashing algorithm is showing cracks, we
+ recommend the usage of SHA-1.
+
+ At the time of publication, it is known that the SHA-1 hash has
+ cryptanalysis issues. There is work in progress on addressing these
+ issues. We recommend the use of public key algorithms based on
+ hashes stronger than SHA-1 (e.g., SHA-256), as soon as these
+ algorithms are available in protocol specifications (see [19] and
+ [20]) and implementations.
+
+3.5. Key Sizes
+
+ When choosing key sizes, zone administrators will need to take into
+ account how long a key will be used, how much data will be signed
+ during the key publication period (see Section 8.10 of [17]), and,
+ optionally, how large the key size of the parent is. As the chain of
+ trust really is "a chain", there is not much sense in making one of
+ the keys in the chain several times larger then the others. As
+ always, it's the weakest link that defines the strength of the entire
+ chain. Also see Section 3.1.1 for a discussion of how keys serving
+ different roles (ZSK vs. KSK) may need different key sizes.
+
+ Generating a key of the correct size is a difficult problem; RFC 3766
+ [13] tries to deal with that problem. The first part of the
+ selection procedure in Section 1 of the RFC states:
+
+ 1. Determine the attack resistance necessary to satisfy the
+ security requirements of the application. Do this by
+ estimating the minimum number of computer operations that the
+ attacker will be forced to do in order to compromise the
+
+
+
+
+Kolkman & Gieben Informational [Page 9]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ security of the system and then take the logarithm base two of
+ that number. Call that logarithm value "n".
+
+ A 1996 report recommended 90 bits as a good all-around choice
+ for system security. The 90 bit number should be increased by
+ about 2/3 bit/year, or about 96 bits in 2005.
+
+ [13] goes on to explain how this number "n" can be used to calculate
+ the key sizes in public key cryptography. This culminated in the
+ table given below (slightly modified for our purpose):
+
+ +-------------+-----------+--------------+
+ | System | | |
+ | requirement | Symmetric | RSA or DSA |
+ | for attack | key size | modulus size |
+ | resistance | (bits) | (bits) |
+ | (bits) | | |
+ +-------------+-----------+--------------+
+ | 70 | 70 | 947 |
+ | 80 | 80 | 1228 |
+ | 90 | 90 | 1553 |
+ | 100 | 100 | 1926 |
+ | 150 | 150 | 4575 |
+ | 200 | 200 | 8719 |
+ | 250 | 250 | 14596 |
+ +-------------+-----------+--------------+
+
+ The key sizes given are rather large. This is because these keys are
+ resilient against a trillionaire attacker. Assuming this rich
+ attacker will not attack your key and that the key is rolled over
+ once a year, we come to the following recommendations about KSK
+ sizes: 1024 bits for low-value domains, 1300 bits for medium-value
+ domains, and 2048 bits for high-value domains.
+
+ Whether a domain is of low, medium, or high value depends solely on
+ the views of the zone owner. One could, for instance, view leaf
+ nodes in the DNS as of low value, and top-level domains (TLDs) or the
+ root zone of high value. The suggested key sizes should be safe for
+ the next 5 years.
+
+ As ZSKs can be rolled over more easily (and thus more often), the key
+ sizes can be made smaller. But as said in the introduction of this
+ paragraph, making the ZSKs' key sizes too small (in relation to the
+ KSKs' sizes) doesn't make much sense. Try to limit the difference in
+ size to about 100 bits.
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 10]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ Note that nobody can see into the future and that these key sizes are
+ only provided here as a guide. Further information can be found in
+ [16] and Section 7.5 of [17]. It should be noted though that [16] is
+ already considered overly optimistic about what key sizes are
+ considered safe.
+
+ One final note concerning key sizes. Larger keys will increase the
+ sizes of the RRSIG and DNSKEY records and will therefore increase the
+ chance of DNS UDP packet overflow. Also, the time it takes to
+ validate and create RRSIGs increases with larger keys, so don't
+ needlessly double your key sizes.
+
+3.6. Private Key Storage
+
+ It is recommended that, where possible, zone private keys and the
+ zone file master copy that is to be signed be kept and used in off-
+ line, non-network-connected, physically secure machines only.
+ Periodically, an application can be run to add authentication to a
+ zone by adding RRSIG and NSEC RRs. Then the augmented file can be
+ transferred.
+
+ When relying on dynamic update to manage a signed zone [10], be aware
+ that at least one private key of the zone will have to reside on the
+ master server. This key is only as secure as the amount of exposure
+ the server receives to unknown clients and the security of the host.
+ Although not mandatory, one could administer the DNS in the following
+ way. The master that processes the dynamic updates is unavailable
+ from generic hosts on the Internet, it is not listed in the NS RR
+ set, although its name appears in the SOA RRs MNAME field. The
+ nameservers in the NS RRSet are able to receive zone updates through
+ NOTIFY, IXFR, AXFR, or an out-of-band distribution mechanism. This
+ approach is known as the "hidden master" setup.
+
+ The ideal situation is to have a one-way information flow to the
+ network to avoid the possibility of tampering from the network.
+ Keeping the zone master file on-line on the network and simply
+ cycling it through an off-line signer does not do this. The on-line
+ version could still be tampered with if the host it resides on is
+ compromised. For maximum security, the master copy of the zone file
+ should be off-net and should not be updated based on an unsecured
+ network mediated communication.
+
+ In general, keeping a zone file off-line will not be practical and
+ the machines on which zone files are maintained will be connected to
+ a network. Operators are advised to take security measures to shield
+ unauthorized access to the master copy.
+
+
+
+
+
+Kolkman & Gieben Informational [Page 11]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ For dynamically updated secured zones [10], both the master copy and
+ the private key that is used to update signatures on updated RRs will
+ need to be on-line.
+
+4. Signature Generation, Key Rollover, and Related Policies
+
+4.1. Time in DNSSEC
+
+ Without DNSSEC, all times in the DNS are relative. The SOA fields
+ REFRESH, RETRY, and EXPIRATION are timers used to determine the time
+ elapsed after a slave server synchronized with a master server. The
+ Time to Live (TTL) value and the SOA RR minimum TTL parameter [11]
+ are used to determine how long a forwarder should cache data after it
+ has been fetched from an authoritative server. By using a signature
+ validity period, DNSSEC introduces the notion of an absolute time in
+ the DNS. Signatures in DNSSEC have an expiration date after which
+ the signature is marked as invalid and the signed data is to be
+ considered Bogus.
+
+4.1.1. Time Considerations
+
+ Because of the expiration of signatures, one should consider the
+ following:
+
+ o We suggest the Maximum Zone TTL of your zone data to be a fraction
+ of your signature validity period.
+
+ If the TTL would be of similar order as the signature validity
+ period, then all RRSets fetched during the validity period
+ would be cached until the signature expiration time. Section
+ 7.1 of [4] suggests that "the resolver may use the time
+ remaining before expiration of the signature validity period of
+ a signed RRSet as an upper bound for the TTL". As a result,
+ query load on authoritative servers would peak at signature
+ expiration time, as this is also the time at which records
+ simultaneously expire from caches.
+
+ To avoid query load peaks, we suggest the TTL on all the RRs in
+ your zone to be at least a few times smaller than your
+ signature validity period.
+
+ o We suggest the signature publication period to end at least one
+ Maximum Zone TTL duration before the end of the signature validity
+ period.
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 12]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ Re-signing a zone shortly before the end of the signature
+ validity period may cause simultaneous expiration of data from
+ caches. This in turn may lead to peaks in the load on
+ authoritative servers.
+
+ o We suggest the Minimum Zone TTL to be long enough to both fetch
+ and verify all the RRs in the trust chain. In workshop
+ environments, it has been demonstrated [18] that a low TTL (under
+ 5 to 10 minutes) caused disruptions because of the following two
+ problems:
+
+ 1. During validation, some data may expire before the
+ validation is complete. The validator should be able to
+ keep all data until it is completed. This applies to all
+ RRs needed to complete the chain of trust: DSes, DNSKEYs,
+ RRSIGs, and the final answers, i.e., the RRSet that is
+ returned for the initial query.
+
+ 2. Frequent verification causes load on recursive nameservers.
+ Data at delegation points, DSes, DNSKEYs, and RRSIGs
+ benefit from caching. The TTL on those should be
+ relatively long.
+
+ o Slave servers will need to be able to fetch newly signed zones
+ well before the RRSIGs in the zone served by the slave server pass
+ their signature expiration time.
+
+ When a slave server is out of sync with its master and data in
+ a zone is signed by expired signatures, it may be better for
+ the slave server not to give out any answer.
+
+ Normally, a slave server that is not able to contact a master
+ server for an extended period will expire a zone. When that
+ happens, the server will respond differently to queries for
+ that zone. Some servers issue SERVFAIL, whereas others turn
+ off the 'AA' bit in the answers. The time of expiration is set
+ in the SOA record and is relative to the last successful
+ refresh between the master and the slave servers. There exists
+ no coupling between the signature expiration of RRSIGs in the
+ zone and the expire parameter in the SOA.
+
+ If the server serves a DNSSEC zone, then it may well happen
+ that the signatures expire well before the SOA expiration timer
+ counts down to zero. It is not possible to completely prevent
+ this from happening by tweaking the SOA parameters. However,
+ the effects can be minimized where the SOA expiration time is
+ equal to or shorter than the signature validity period. The
+ consequence of an authoritative server not being able to update
+
+
+
+Kolkman & Gieben Informational [Page 13]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ a zone, whilst that zone includes expired signatures, is that
+ non-secure resolvers will continue to be able to resolve data
+ served by the particular slave servers while security-aware
+ resolvers will experience problems because of answers being
+ marked as Bogus.
+
+ We suggest the SOA expiration timer being approximately one
+ third or one fourth of the signature validity period. It will
+ allow problems with transfers from the master server to be
+ noticed before the actual signature times out. We also suggest
+ that operators of nameservers that supply secondary services
+ develop 'watch dogs' to spot upcoming signature expirations in
+ zones they slave, and take appropriate action.
+
+ When determining the value for the expiration parameter one has
+ to take the following into account: What are the chances that
+ all my secondaries expire the zone? How quickly can I reach an
+ administrator of secondary servers to load a valid zone? These
+ questions are not DNSSEC specific but may influence the choice
+ of your signature validity intervals.
+
+4.2. Key Rollovers
+
+ A DNSSEC key cannot be used forever (see Section 3.3). So key
+ rollovers -- or supercessions, as they are sometimes called -- are a
+ fact of life when using DNSSEC. Zone administrators who are in the
+ process of rolling their keys have to take into account that data
+ published in previous versions of their zone still lives in caches.
+ When deploying DNSSEC, this becomes an important consideration;
+ ignoring data that may be in caches may lead to loss of service for
+ clients.
+
+ The most pressing example of this occurs when zone material signed
+ with an old key is being validated by a resolver that does not have
+ the old zone key cached. If the old key is no longer present in the
+ current zone, this validation fails, marking the data "Bogus".
+ Alternatively, an attempt could be made to validate data that is
+ signed with a new key against an old key that lives in a local cache,
+ also resulting in data being marked "Bogus".
+
+4.2.1. Zone Signing Key Rollovers
+
+ For "Zone Signing Key rollovers", there are two ways to make sure
+ that during the rollover data still cached can be verified with the
+ new key sets or newly generated signatures can be verified with the
+ keys still in caches. One schema, described in Section 4.2.1.2, uses
+
+
+
+
+
+Kolkman & Gieben Informational [Page 14]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ double signatures; the other uses key pre-publication (Section
+ 4.2.1.1). The pros, cons, and recommendations are described in
+ Section 4.2.1.3.
+
+4.2.1.1. Pre-Publish Key Rollover
+
+ This section shows how to perform a ZSK rollover without the need to
+ sign all the data in a zone twice -- the "pre-publish key rollover".
+ This method has advantages in the case of a key compromise. If the
+ old key is compromised, the new key has already been distributed in
+ the DNS. The zone administrator is then able to quickly switch to
+ the new key and remove the compromised key from the zone. Another
+ major advantage is that the zone size does not double, as is the case
+ with the double signature ZSK rollover. A small "how-to" for this
+ kind of rollover can be found in Appendix B.
+
+ Pre-publish key rollover involves four stages as follows:
+
+ ----------------------------------------------------------------
+ initial new DNSKEY new RRSIGs DNSKEY removal
+ ----------------------------------------------------------------
+ SOA0 SOA1 SOA2 SOA3
+ RRSIG10(SOA0) RRSIG10(SOA1) RRSIG11(SOA2) RRSIG11(SOA3)
+
+ DNSKEY1 DNSKEY1 DNSKEY1 DNSKEY1
+ DNSKEY10 DNSKEY10 DNSKEY10 DNSKEY11
+ DNSKEY11 DNSKEY11
+ RRSIG1 (DNSKEY) RRSIG1 (DNSKEY) RRSIG1(DNSKEY) RRSIG1 (DNSKEY)
+ RRSIG10(DNSKEY) RRSIG10(DNSKEY) RRSIG11(DNSKEY) RRSIG11(DNSKEY)
+ ----------------------------------------------------------------
+
+ Pre-Publish Key Rollover
+
+ initial: Initial version of the zone: DNSKEY 1 is the Key Signing
+ Key. DNSKEY 10 is used to sign all the data of the zone, the Zone
+ Signing Key.
+
+ new DNSKEY: DNSKEY 11 is introduced into the key set. Note that no
+ signatures are generated with this key yet, but this does not
+ secure against brute force attacks on the public key. The minimum
+ duration of this pre-roll phase is the time it takes for the data
+ to propagate to the authoritative servers plus TTL value of the
+ key set.
+
+ new RRSIGs: At the "new RRSIGs" stage (SOA serial 2), DNSKEY 11 is
+ used to sign the data in the zone exclusively (i.e., all the
+ signatures from DNSKEY 10 are removed from the zone). DNSKEY 10
+ remains published in the key set. This way data that was loaded
+
+
+
+Kolkman & Gieben Informational [Page 15]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ into caches from version 1 of the zone can still be verified with
+ key sets fetched from version 2 of the zone. The minimum time
+ that the key set including DNSKEY 10 is to be published is the
+ time that it takes for zone data from the previous version of the
+ zone to expire from old caches, i.e., the time it takes for this
+ zone to propagate to all authoritative servers plus the Maximum
+ Zone TTL value of any of the data in the previous version of the
+ zone.
+
+ DNSKEY removal: DNSKEY 10 is removed from the zone. The key set, now
+ only containing DNSKEY 1 and DNSKEY 11, is re-signed with the
+ DNSKEY 1.
+
+ The above scheme can be simplified by always publishing the "future"
+ key immediately after the rollover. The scheme would look as follows
+ (we show two rollovers); the future key is introduced in "new DNSKEY"
+ as DNSKEY 12 and again a newer one, numbered 13, in "new DNSKEY
+ (II)":
+
+ ----------------------------------------------------------------
+ initial new RRSIGs new DNSKEY
+ ----------------------------------------------------------------
+ SOA0 SOA1 SOA2
+ RRSIG10(SOA0) RRSIG11(SOA1) RRSIG11(SOA2)
+
+ DNSKEY1 DNSKEY1 DNSKEY1
+ DNSKEY10 DNSKEY10 DNSKEY11
+ DNSKEY11 DNSKEY11 DNSKEY12
+ RRSIG1(DNSKEY) RRSIG1 (DNSKEY) RRSIG1(DNSKEY)
+ RRSIG10(DNSKEY) RRSIG11(DNSKEY) RRSIG11(DNSKEY)
+ ----------------------------------------------------------------
+
+ ----------------------------------------------------------------
+ new RRSIGs (II) new DNSKEY (II)
+ ----------------------------------------------------------------
+ SOA3 SOA4
+ RRSIG12(SOA3) RRSIG12(SOA4)
+
+ DNSKEY1 DNSKEY1
+ DNSKEY11 DNSKEY12
+ DNSKEY12 DNSKEY13
+ RRSIG1(DNSKEY) RRSIG1(DNSKEY)
+ RRSIG12(DNSKEY) RRSIG12(DNSKEY)
+ ----------------------------------------------------------------
+
+ Pre-Publish Key Rollover, Showing Two Rollovers
+
+
+
+
+
+Kolkman & Gieben Informational [Page 16]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ Note that the key introduced in the "new DNSKEY" phase is not used
+ for production yet; the private key can thus be stored in a
+ physically secure manner and does not need to be 'fetched' every time
+ a zone needs to be signed.
+
+4.2.1.2. Double Signature Zone Signing Key Rollover
+
+ This section shows how to perform a ZSK key rollover using the double
+ zone data signature scheme, aptly named "double signature rollover".
+
+ During the "new DNSKEY" stage the new version of the zone file will
+ need to propagate to all authoritative servers and the data that
+ exists in (distant) caches will need to expire, requiring at least
+ the Maximum Zone TTL.
+
+ Double signature ZSK rollover involves three stages as follows:
+
+ ----------------------------------------------------------------
+ initial new DNSKEY DNSKEY removal
+ ----------------------------------------------------------------
+ SOA0 SOA1 SOA2
+ RRSIG10(SOA0) RRSIG10(SOA1) RRSIG11(SOA2)
+ RRSIG11(SOA1)
+
+ DNSKEY1 DNSKEY1 DNSKEY1
+ DNSKEY10 DNSKEY10 DNSKEY11
+ DNSKEY11
+ RRSIG1(DNSKEY) RRSIG1(DNSKEY) RRSIG1(DNSKEY)
+ RRSIG10(DNSKEY) RRSIG10(DNSKEY) RRSIG11(DNSKEY)
+ RRSIG11(DNSKEY)
+ ----------------------------------------------------------------
+
+ Double Signature Zone Signing Key Rollover
+
+ initial: Initial Version of the zone: DNSKEY 1 is the Key Signing
+ Key. DNSKEY 10 is used to sign all the data of the zone, the Zone
+ Signing Key.
+
+ new DNSKEY: At the "New DNSKEY" stage (SOA serial 1) DNSKEY 11 is
+ introduced into the key set and all the data in the zone is signed
+ with DNSKEY 10 and DNSKEY 11. The rollover period will need to
+ continue until all data from version 0 of the zone has expired
+ from remote caches. This will take at least the Maximum Zone TTL
+ of version 0 of the zone.
+
+ DNSKEY removal: DNSKEY 10 is removed from the zone. All the
+ signatures from DNSKEY 10 are removed from the zone. The key set,
+ now only containing DNSKEY 11, is re-signed with DNSKEY 1.
+
+
+
+Kolkman & Gieben Informational [Page 17]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ At every instance, RRSIGs from the previous version of the zone can
+ be verified with the DNSKEY RRSet from the current version and the
+ other way around. The data from the current version can be verified
+ with the data from the previous version of the zone. The duration of
+ the "new DNSKEY" phase and the period between rollovers should be at
+ least the Maximum Zone TTL.
+
+ Making sure that the "new DNSKEY" phase lasts until the signature
+ expiration time of the data in initial version of the zone is
+ recommended. This way all caches are cleared of the old signatures.
+ However, this duration could be considerably longer than the Maximum
+ Zone TTL, making the rollover a lengthy procedure.
+
+ Note that in this example we assumed that the zone was not modified
+ during the rollover. New data can be introduced in the zone as long
+ as it is signed with both keys.
+
+4.2.1.3. Pros and Cons of the Schemes
+
+ Pre-publish key rollover: This rollover does not involve signing the
+ zone data twice. Instead, before the actual rollover, the new key
+ is published in the key set and thus is available for
+ cryptanalysis attacks. A small disadvantage is that this process
+ requires four steps. Also the pre-publish scheme involves more
+ parental work when used for KSK rollovers as explained in Section
+ 4.2.3.
+
+ Double signature ZSK rollover: The drawback of this signing scheme is
+ that during the rollover the number of signatures in your zone
+ doubles; this may be prohibitive if you have very big zones. An
+ advantage is that it only requires three steps.
+
+4.2.2. Key Signing Key Rollovers
+
+ For the rollover of a Key Signing Key, the same considerations as for
+ the rollover of a Zone Signing Key apply. However, we can use a
+ double signature scheme to guarantee that old data (only the apex key
+ set) in caches can be verified with a new key set and vice versa.
+ Since only the key set is signed with a KSK, zone size considerations
+ do not apply.
+
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 18]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ --------------------------------------------------------------------
+ initial new DNSKEY DS change DNSKEY removal
+ --------------------------------------------------------------------
+ Parent:
+ SOA0 --------> SOA1 -------->
+ RRSIGpar(SOA0) --------> RRSIGpar(SOA1) -------->
+ DS1 --------> DS2 -------->
+ RRSIGpar(DS) --------> RRSIGpar(DS) -------->
+
+
+ Child:
+ SOA0 SOA1 --------> SOA2
+ RRSIG10(SOA0) RRSIG10(SOA1) --------> RRSIG10(SOA2)
+ -------->
+ DNSKEY1 DNSKEY1 --------> DNSKEY2
+ DNSKEY2 -------->
+ DNSKEY10 DNSKEY10 --------> DNSKEY10
+ RRSIG1 (DNSKEY) RRSIG1 (DNSKEY) --------> RRSIG2 (DNSKEY)
+ RRSIG2 (DNSKEY) -------->
+ RRSIG10(DNSKEY) RRSIG10(DNSKEY) --------> RRSIG10(DNSKEY)
+ --------------------------------------------------------------------
+
+ Stages of Deployment for a Double Signature Key Signing Key Rollover
+
+ initial: Initial version of the zone. The parental DS points to
+ DNSKEY1. Before the rollover starts, the child will have to
+ verify what the TTL is of the DS RR that points to DNSKEY1 -- it
+ is needed during the rollover and we refer to the value as TTL_DS.
+
+ new DNSKEY: During the "new DNSKEY" phase, the zone administrator
+ generates a second KSK, DNSKEY2. The key is provided to the
+ parent, and the child will have to wait until a new DS RR has been
+ generated that points to DNSKEY2. After that DS RR has been
+ published on all servers authoritative for the parent's zone, the
+ zone administrator has to wait at least TTL_DS to make sure that
+ the old DS RR has expired from caches.
+
+ DS change: The parent replaces DS1 with DS2.
+
+ DNSKEY removal: DNSKEY1 has been removed.
+
+ The scenario above puts the responsibility for maintaining a valid
+ chain of trust with the child. It also is based on the premise that
+ the parent only has one DS RR (per algorithm) per zone. An
+ alternative mechanism has been considered. Using an established
+ trust relation, the interaction can be performed in-band, and the
+ removal of the keys by the child can possibly be signaled by the
+ parent. In this mechanism, there are periods where there are two DS
+
+
+
+Kolkman & Gieben Informational [Page 19]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ RRs at the parent. Since at the moment of writing the protocol for
+ this interaction has not been developed, further discussion is out of
+ scope for this document.
+
+4.2.3. Difference Between ZSK and KSK Rollovers
+
+ Note that KSK rollovers and ZSK rollovers are different in the sense
+ that a KSK rollover requires interaction with the parent (and
+ possibly replacing of trust anchors) and the ensuing delay while
+ waiting for it.
+
+ A zone key rollover can be handled in two different ways: pre-publish
+ (Section 4.2.1.1) and double signature (Section 4.2.1.2).
+
+ As the KSK is used to validate the key set and because the KSK is not
+ changed during a ZSK rollover, a cache is able to validate the new
+ key set of the zone. The pre-publish method would also work for a
+ KSK rollover. The records that are to be pre-published are the
+ parental DS RRs. The pre-publish method has some drawbacks for KSKs.
+ We first describe the rollover scheme and then indicate these
+ drawbacks.
+
+ --------------------------------------------------------------------
+ initial new DS new DNSKEY DS/DNSKEY removal
+ --------------------------------------------------------------------
+ Parent:
+ SOA0 SOA1 --------> SOA2
+ RRSIGpar(SOA0) RRSIGpar(SOA1) --------> RRSIGpar(SOA2)
+ DS1 DS1 --------> DS2
+ DS2 -------->
+ RRSIGpar(DS) RRSIGpar(DS) --------> RRSIGpar(DS)
+
+
+ Child:
+ SOA0 --------> SOA1 SOA1
+ RRSIG10(SOA0) --------> RRSIG10(SOA1) RRSIG10(SOA1)
+ -------->
+ DNSKEY1 --------> DNSKEY2 DNSKEY2
+ -------->
+ DNSKEY10 --------> DNSKEY10 DNSKEY10
+ RRSIG1 (DNSKEY) --------> RRSIG2(DNSKEY) RRSIG2 (DNSKEY)
+ RRSIG10(DNSKEY) --------> RRSIG10(DNSKEY) RRSIG10(DNSKEY)
+ --------------------------------------------------------------------
+
+ Stages of Deployment for a Pre-Publish Key Signing Key Rollover
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 20]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ When the child zone wants to roll, it notifies the parent during the
+ "new DS" phase and submits the new key (or the corresponding DS) to
+ the parent. The parent publishes DS1 and DS2, pointing to DNSKEY1
+ and DNSKEY2, respectively. During the rollover ("new DNSKEY" phase),
+ which can take place as soon as the new DS set propagated through the
+ DNS, the child replaces DNSKEY1 with DNSKEY2. Immediately after that
+ ("DS/DNSKEY removal" phase), it can notify the parent that the old DS
+ record can be deleted.
+
+ The drawbacks of this scheme are that during the "new DS" phase the
+ parent cannot verify the match between the DS2 RR and DNSKEY2 using
+ the DNS -- as DNSKEY2 is not yet published. Besides, we introduce a
+ "security lame" key (see Section 4.4.3). Finally, the child-parent
+ interaction consists of two steps. The "double signature" method
+ only needs one interaction.
+
+4.2.4. Automated Key Rollovers
+
+ As keys must be renewed periodically, there is some motivation to
+ automate the rollover process. Consider the following:
+
+ o ZSK rollovers are easy to automate as only the child zone is
+ involved.
+
+ o A KSK rollover needs interaction between parent and child. Data
+ exchange is needed to provide the new keys to the parent;
+ consequently, this data must be authenticated and integrity must
+ be guaranteed in order to avoid attacks on the rollover.
+
+4.3. Planning for Emergency Key Rollover
+
+ This section deals with preparation for a possible key compromise.
+ Our advice is to have a documented procedure ready for when a key
+ compromise is suspected or confirmed.
+
+ When the private material of one of your keys is compromised it can
+ be used for as long as a valid trust chain exists. A trust chain
+ remains intact for
+
+ o as long as a signature over the compromised key in the trust chain
+ is valid,
+
+ o as long as a parental DS RR (and signature) points to the
+ compromised key,
+
+ o as long as the key is anchored in a resolver and is used as a
+ starting point for validation (this is generally the hardest to
+ update).
+
+
+
+Kolkman & Gieben Informational [Page 21]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ While a trust chain to your compromised key exists, your namespace is
+ vulnerable to abuse by anyone who has obtained illegitimate
+ possession of the key. Zone operators have to make a trade-off if
+ the abuse of the compromised key is worse than having data in caches
+ that cannot be validated. If the zone operator chooses to break the
+ trust chain to the compromised key, data in caches signed with this
+ key cannot be validated. However, if the zone administrator chooses
+ to take the path of a regular rollover, the malicious key holder can
+ spoof data so that it appears to be valid.
+
+4.3.1. KSK Compromise
+
+ A zone containing a DNSKEY RRSet with a compromised KSK is vulnerable
+ as long as the compromised KSK is configured as trust anchor or a
+ parental DS points to it.
+
+ A compromised KSK can be used to sign the key set of an attacker's
+ zone. That zone could be used to poison the DNS.
+
+ Therefore, when the KSK has been compromised, the trust anchor or the
+ parental DS should be replaced as soon as possible. It is local
+ policy whether to break the trust chain during the emergency
+ rollover. The trust chain would be broken when the compromised KSK
+ is removed from the child's zone while the parent still has a DS
+ pointing to the compromised KSK (the assumption is that there is only
+ one DS at the parent. If there are multiple DSes this does not apply
+ -- however the chain of trust of this particular key is broken).
+
+ Note that an attacker's zone still uses the compromised KSK and the
+ presence of a parental DS would cause the data in this zone to appear
+ as valid. Removing the compromised key would cause the attacker's
+ zone to appear as valid and the child's zone as Bogus. Therefore, we
+ advise not to remove the KSK before the parent has a DS to a new KSK
+ in place.
+
+4.3.1.1. Keeping the Chain of Trust Intact
+
+ If we follow this advice, the timing of the replacement of the KSK is
+ somewhat critical. The goal is to remove the compromised KSK as soon
+ as the new DS RR is available at the parent. And also make sure that
+ the signature made with a new KSK over the key set with the
+ compromised KSK in it expires just after the new DS appears at the
+ parent, thus removing the old cruft in one swoop.
+
+ The procedure is as follows:
+
+ 1. Introduce a new KSK into the key set, keep the compromised KSK in
+ the key set.
+
+
+
+Kolkman & Gieben Informational [Page 22]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ 2. Sign the key set, with a short validity period. The validity
+ period should expire shortly after the DS is expected to appear
+ in the parent and the old DSes have expired from caches.
+
+ 3. Upload the DS for this new key to the parent.
+
+ 4. Follow the procedure of the regular KSK rollover: Wait for the DS
+ to appear in the authoritative servers and then wait as long as
+ the TTL of the old DS RRs. If necessary re-sign the DNSKEY RRSet
+ and modify/extend the expiration time.
+
+ 5. Remove the compromised DNSKEY RR from the zone and re-sign the
+ key set using your "normal" validity interval.
+
+ An additional danger of a key compromise is that the compromised key
+ could be used to facilitate a legitimate DNSKEY/DS rollover and/or
+ nameserver changes at the parent. When that happens, the domain may
+ be in dispute. An authenticated out-of-band and secure notify
+ mechanism to contact a parent is needed in this case.
+
+ Note that this is only a problem when the DNSKEY and or DS records
+ are used for authentication at the parent.
+
+4.3.1.2. Breaking the Chain of Trust
+
+ There are two methods to break the chain of trust. The first method
+ causes the child zone to appear 'Bogus' to validating resolvers. The
+ other causes the child zone to appear 'insecure'. These are
+ described below.
+
+ In the method that causes the child zone to appear 'Bogus' to
+ validating resolvers, the child zone replaces the current KSK with a
+ new one and re-signs the key set. Next it sends the DS of the new
+ key to the parent. Only after the parent has placed the new DS in
+ the zone is the child's chain of trust repaired.
+
+ An alternative method of breaking the chain of trust is by removing
+ the DS RRs from the parent zone altogether. As a result, the child
+ zone would become insecure.
+
+4.3.2. ZSK Compromise
+
+ Primarily because there is no parental interaction required when a
+ ZSK is compromised, the situation is less severe than with a KSK
+ compromise. The zone must still be re-signed with a new ZSK as soon
+ as possible. As this is a local operation and requires no
+ communication between the parent and child, this can be achieved
+ fairly quickly. However, one has to take into account that just as
+
+
+
+Kolkman & Gieben Informational [Page 23]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ with a normal rollover the immediate disappearance of the old
+ compromised key may lead to verification problems. Also note that as
+ long as the RRSIG over the compromised ZSK is not expired the zone
+ may be still at risk.
+
+4.3.3. Compromises of Keys Anchored in Resolvers
+
+ A key can also be pre-configured in resolvers. For instance, if
+ DNSSEC is successfully deployed the root key may be pre-configured in
+ most security aware resolvers.
+
+ If trust-anchor keys are compromised, the resolvers using these keys
+ should be notified of this fact. Zone administrators may consider
+ setting up a mailing list to communicate the fact that a SEP key is
+ about to be rolled over. This communication will of course need to
+ be authenticated, e.g., by using digital signatures.
+
+ End-users faced with the task of updating an anchored key should
+ always validate the new key. New keys should be authenticated out-
+ of-band, for example, through the use of an announcement website that
+ is secured using secure sockets (TLS) [21].
+
+4.4. Parental Policies
+
+4.4.1. Initial Key Exchanges and Parental Policies Considerations
+
+ The initial key exchange is always subject to the policies set by the
+ parent. When designing a key exchange policy one should take into
+ account that the authentication and authorization mechanisms used
+ during a key exchange should be as strong as the authentication and
+ authorization mechanisms used for the exchange of delegation
+ information between parent and child. That is, there is no implicit
+ need in DNSSEC to make the authentication process stronger than it
+ was in DNS.
+
+ Using the DNS itself as the source for the actual DNSKEY material,
+ with an out-of-band check on the validity of the DNSKEY, has the
+ benefit that it reduces the chances of user error. A DNSKEY query
+ tool can make use of the SEP bit [3] to select the proper key from a
+ DNSSEC key set, thereby reducing the chance that the wrong DNSKEY is
+ sent. It can validate the self-signature over a key; thereby
+ verifying the ownership of the private key material. Fetching the
+ DNSKEY from the DNS ensures that the chain of trust remains intact
+ once the parent publishes the DS RR indicating the child is secure.
+
+ Note: the out-of-band verification is still needed when the key
+ material is fetched via the DNS. The parent can never be sure
+ whether or not the DNSKEY RRs have been spoofed.
+
+
+
+Kolkman & Gieben Informational [Page 24]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+4.4.2. Storing Keys or Hashes?
+
+ When designing a registry system one should consider which of the
+ DNSKEYs and/or the corresponding DSes to store. Since a child zone
+ might wish to have a DS published using a message digest algorithm
+ not yet understood by the registry, the registry can't count on being
+ able to generate the DS record from a raw DNSKEY. Thus, we recommend
+ that registry systems at least support storing DS records.
+
+ It may also be useful to store DNSKEYs, since having them may help
+ during troubleshooting and, as long as the child's chosen message
+ digest is supported, the overhead of generating DS records from them
+ is minimal. Having an out-of-band mechanism, such as a registry
+ directory (e.g., Whois), to find out which keys are used to generate
+ DS Resource Records for specific owners and/or zones may also help
+ with troubleshooting.
+
+ The storage considerations also relate to the design of the customer
+ interface and the method by which data is transferred between
+ registrant and registry; Will the child zone administrator be able to
+ upload DS RRs with unknown hash algorithms or does the interface only
+ allow DNSKEYs? In the registry-registrar model, one can use the
+ DNSSEC extensions to the Extensible Provisioning Protocol (EPP) [15],
+ which allows transfer of DS RRs and optionally DNSKEY RRs.
+
+4.4.3. Security Lameness
+
+ Security lameness is defined as what happens when a parent has a DS
+ RR pointing to a non-existing DNSKEY RR. When this happens, the
+ child's zone may be marked "Bogus" by verifying DNS clients.
+
+ As part of a comprehensive delegation check, the parent could, at key
+ exchange time, verify that the child's key is actually configured in
+ the DNS. However, if a parent does not understand the hashing
+ algorithm used by child, the parental checks are limited to only
+ comparing the key id.
+
+ Child zones should be very careful in removing DNSKEY material,
+ specifically SEP keys, for which a DS RR exists.
+
+ Once a zone is "security lame", a fix (e.g., removing a DS RR) will
+ take time to propagate through the DNS.
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 25]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+4.4.4. DS Signature Validity Period
+
+ Since the DS can be replayed as long as it has a valid signature, a
+ short signature validity period over the DS minimizes the time a
+ child is vulnerable in the case of a compromise of the child's
+ KSK(s). A signature validity period that is too short introduces the
+ possibility that a zone is marked "Bogus" in case of a configuration
+ error in the signer. There may not be enough time to fix the
+ problems before signatures expire. Something as mundane as operator
+ unavailability during weekends shows the need for DS signature
+ validity periods longer than 2 days. We recommend an absolute
+ minimum for a DS signature validity period of a few days.
+
+ The maximum signature validity period of the DS record depends on how
+ long child zones are willing to be vulnerable after a key compromise.
+ On the other hand, shortening the DS signature validity interval
+ increases the operational risk for the parent. Therefore, the parent
+ may have policy to use a signature validity interval that is
+ considerably longer than the child would hope for.
+
+ A compromise between the operational constraints of the parent and
+ minimizing damage for the child may result in a DS signature validity
+ period somewhere between a week and months.
+
+ In addition to the signature validity period, which sets a lower
+ bound on the number of times the zone owner will need to sign the
+ zone data and which sets an upper bound to the time a child is
+ vulnerable after key compromise, there is the TTL value on the DS
+ RRs. Shortening the TTL means that the authoritative servers will
+ see more queries. But on the other hand, a short TTL lowers the
+ persistence of DS RRSets in caches thereby increasing the speed with
+ which updated DS RRSets propagate through the DNS.
+
+5. Security Considerations
+
+ DNSSEC adds data integrity to the DNS. This document tries to assess
+ the operational considerations to maintain a stable and secure DNSSEC
+ service. Not taking into account the 'data propagation' properties
+ in the DNS will cause validation failures and may make secured zones
+ unavailable to security-aware resolvers.
+
+6. Acknowledgments
+
+ Most of the ideas in this document were the result of collective
+ efforts during workshops, discussions, and tryouts.
+
+ At the risk of forgetting individuals who were the original
+ contributors of the ideas, we would like to acknowledge people who
+
+
+
+Kolkman & Gieben Informational [Page 26]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ were actively involved in the compilation of this document. In
+ random order: Rip Loomis, Olafur Gudmundsson, Wesley Griffin, Michael
+ Richardson, Scott Rose, Rick van Rein, Tim McGinnis, Gilles Guette
+ Olivier Courtay, Sam Weiler, Jelte Jansen, Niall O'Reilly, Holger
+ Zuleger, Ed Lewis, Hilarie Orman, Marcos Sanz, and Peter Koch.
+
+ Some material in this document has been copied from RFC 2541 [12].
+
+ Mike StJohns designed the key exchange between parent and child
+ mentioned in the last paragraph of Section 4.2.2
+
+ Section 4.2.4 was supplied by G. Guette and O. Courtay.
+
+ Emma Bretherick, Adrian Bedford, and Lindy Foster corrected many of
+ the spelling and style issues.
+
+ Kolkman and Gieben take the blame for introducing all miscakes (sic).
+
+ While working on this document, Kolkman was employed by the RIPE NCC
+ and Gieben was employed by NLnet Labs.
+
+7. References
+
+7.1. Normative References
+
+ [1] Mockapetris, P., "Domain names - concepts and facilities", STD
+ 13, RFC 1034, November 1987.
+
+ [2] Mockapetris, P., "Domain names - implementation and
+ specification", STD 13, RFC 1035, November 1987.
+
+ [3] Kolkman, O., Schlyter, J., and E. Lewis, "Domain Name System
+ KEY (DNSKEY) Resource Record (RR) Secure Entry Point (SEP)
+ Flag", RFC 3757, May 2004.
+
+ [4] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "DNS Security Introduction and Requirements", RFC 4033, March
+ 2005.
+
+ [5] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "Resource Records for the DNS Security Extensions", RFC 4034,
+ March 2005.
+
+ [6] Arends, R., Austein, R., Larson, M., Massey, D., and S. Rose,
+ "Protocol Modifications for the DNS Security Extensions", RFC
+ 4035, March 2005.
+
+
+
+
+
+Kolkman & Gieben Informational [Page 27]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+7.2. Informative References
+
+ [7] Bradner, S., "Key words for use in RFCs to Indicate Requirement
+ Levels", BCP 14, RFC 2119, March 1997.
+
+ [8] Ohta, M., "Incremental Zone Transfer in DNS", RFC 1995, August
+ 1996.
+
+ [9] Vixie, P., "A Mechanism for Prompt Notification of Zone Changes
+ (DNS NOTIFY)", RFC 1996, August 1996.
+
+ [10] Wellington, B., "Secure Domain Name System (DNS) Dynamic
+ Update", RFC 3007, November 2000.
+
+ [11] Andrews, M., "Negative Caching of DNS Queries (DNS NCACHE)",
+ RFC 2308, March 1998.
+
+ [12] Eastlake, D., "DNS Security Operational Considerations", RFC
+ 2541, March 1999.
+
+ [13] Orman, H. and P. Hoffman, "Determining Strengths For Public
+ Keys Used For Exchanging Symmetric Keys", BCP 86, RFC 3766,
+ April 2004.
+
+ [14] Eastlake, D., Schiller, J., and S. Crocker, "Randomness
+ Requirements for Security", BCP 106, RFC 4086, June 2005.
+
+ [15] Hollenbeck, S., "Domain Name System (DNS) Security Extensions
+ Mapping for the Extensible Provisioning Protocol (EPP)", RFC
+ 4310, December 2005.
+
+ [16] Lenstra, A. and E. Verheul, "Selecting Cryptographic Key
+ Sizes", The Journal of Cryptology 14 (255-293), 2001.
+
+ [17] Schneier, B., "Applied Cryptography: Protocols, Algorithms, and
+ Source Code in C", ISBN (hardcover) 0-471-12845-7, ISBN
+ (paperback) 0-471-59756-2, Published by John Wiley & Sons Inc.,
+ 1996.
+
+ [18] Rose, S., "NIST DNSSEC workshop notes", June 2001.
+
+ [19] Jansen, J., "Use of RSA/SHA-256 DNSKEY and RRSIG Resource
+ Records in DNSSEC", Work in Progress, January 2006.
+
+ [20] Hardaker, W., "Use of SHA-256 in DNSSEC Delegation Signer (DS)
+ Resource Records (RRs)", RFC 4509, May 2006.
+
+
+
+
+
+Kolkman & Gieben Informational [Page 28]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ [21] Blake-Wilson, S., Nystrom, M., Hopwood, D., Mikkelsen, J., and
+ T. Wright, "Transport Layer Security (TLS) Extensions", RFC
+ 4366, April 2006.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 29]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+Appendix A. Terminology
+
+ In this document, there is some jargon used that is defined in other
+ documents. In most cases, we have not copied the text from the
+ documents defining the terms but have given a more elaborate
+ explanation of the meaning. Note that these explanations should not
+ be seen as authoritative.
+
+ Anchored key: A DNSKEY configured in resolvers around the globe.
+ This key is hard to update, hence the term anchored.
+
+ Bogus: Also see Section 5 of [4]. An RRSet in DNSSEC is marked
+ "Bogus" when a signature of an RRSet does not validate against a
+ DNSKEY.
+
+ Key Signing Key or KSK: A Key Signing Key (KSK) is a key that is used
+ exclusively for signing the apex key set. The fact that a key is
+ a KSK is only relevant to the signing tool.
+
+ Key size: The term 'key size' can be substituted by 'modulus size'
+ throughout the document. It is mathematically more correct to use
+ modulus size, but as this is a document directed at operators we
+ feel more at ease with the term key size.
+
+ Private and public keys: DNSSEC secures the DNS through the use of
+ public key cryptography. Public key cryptography is based on the
+ existence of two (mathematically related) keys, a public key and a
+ private key. The public keys are published in the DNS by use of
+ the DNSKEY Resource Record (DNSKEY RR). Private keys should
+ remain private.
+
+ Key rollover: A key rollover (also called key supercession in some
+ environments) is the act of replacing one key pair with another at
+ the end of a key effectivity period.
+
+ Secure Entry Point (SEP) key: A KSK that has a parental DS record
+ pointing to it or is configured as a trust anchor. Although not
+ required by the protocol, we recommend that the SEP flag [3] is
+ set on these keys.
+
+ Self-signature: This only applies to signatures over DNSKEYs; a
+ signature made with DNSKEY x, over DNSKEY x is called a self-
+ signature. Note: without further information, self-signatures
+ convey no trust. They are useful to check the authenticity of the
+ DNSKEY, i.e., they can be used as a hash.
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 30]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ Singing the zone file: The term used for the event where an
+ administrator joyfully signs its zone file while producing melodic
+ sound patterns.
+
+ Signer: The system that has access to the private key material and
+ signs the Resource Record sets in a zone. A signer may be
+ configured to sign only parts of the zone, e.g., only those RRSets
+ for which existing signatures are about to expire.
+
+ Zone Signing Key (ZSK): A key that is used for signing all data in a
+ zone. The fact that a key is a ZSK is only relevant to the
+ signing tool.
+
+ Zone administrator: The 'role' that is responsible for signing a zone
+ and publishing it on the primary authoritative server.
+
+Appendix B. Zone Signing Key Rollover How-To
+
+ Using the pre-published signature scheme and the most conservative
+ method to assure oneself that data does not live in caches, here
+ follows the "how-to".
+
+ Step 0: The preparation: Create two keys and publish both in your key
+ set. Mark one of the keys "active" and the other "published".
+ Use the "active" key for signing your zone data. Store the
+ private part of the "published" key, preferably off-line. The
+ protocol does not provide for attributes to mark a key as active
+ or published. This is something you have to do on your own,
+ through the use of a notebook or key management tool.
+
+ Step 1: Determine expiration: At the beginning of the rollover make a
+ note of the highest expiration time of signatures in your zone
+ file created with the current key marked as active. Wait until
+ the expiration time marked in Step 1 has passed.
+
+ Step 2: Then start using the key that was marked "published" to sign
+ your data (i.e., mark it "active"). Stop using the key that was
+ marked "active"; mark it "rolled".
+
+ Step 3: It is safe to engage in a new rollover (Step 1) after at
+ least one signature validity period.
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 31]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+Appendix C. Typographic Conventions
+
+ The following typographic conventions are used in this document:
+
+ Key notation: A key is denoted by DNSKEYx, where x is a number or an
+ identifier, x could be thought of as the key id.
+
+ RRSet notations: RRs are only denoted by the type. All other
+ information -- owner, class, rdata, and TTL--is left out. Thus:
+ "example.com 3600 IN A 192.0.2.1" is reduced to "A". RRSets are a
+ list of RRs. A example of this would be "A1, A2", specifying the
+ RRSet containing two "A" records. This could again be abbreviated to
+ just "A".
+
+ Signature notation: Signatures are denoted as RRSIGx(RRSet), which
+ means that RRSet is signed with DNSKEYx.
+
+ Zone representation: Using the above notation we have simplified the
+ representation of a signed zone by leaving out all unnecessary
+ details such as the names and by representing all data by "SOAx"
+
+ SOA representation: SOAs are represented as SOAx, where x is the
+ serial number.
+
+ Using this notation the following signed zone:
+
+ example.net. 86400 IN SOA ns.example.net. bert.example.net. (
+ 2006022100 ; serial
+ 86400 ; refresh ( 24 hours)
+ 7200 ; retry ( 2 hours)
+ 3600000 ; expire (1000 hours)
+ 28800 ) ; minimum ( 8 hours)
+ 86400 RRSIG SOA 5 2 86400 20130522213204 (
+ 20130422213204 14 example.net.
+ cmL62SI6iAX46xGNQAdQ... )
+ 86400 NS a.iana-servers.net.
+ 86400 NS b.iana-servers.net.
+ 86400 RRSIG NS 5 2 86400 20130507213204 (
+ 20130407213204 14 example.net.
+ SO5epiJei19AjXoUpFnQ ... )
+ 86400 DNSKEY 256 3 5 (
+ EtRB9MP5/AvOuVO0I8XDxy0... ) ; id = 14
+ 86400 DNSKEY 257 3 5 (
+ gsPW/Yy19GzYIY+Gnr8HABU... ) ; id = 15
+ 86400 RRSIG DNSKEY 5 2 86400 20130522213204 (
+ 20130422213204 14 example.net.
+ J4zCe8QX4tXVGjV4e1r9... )
+
+
+
+
+Kolkman & Gieben Informational [Page 32]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+ 86400 RRSIG DNSKEY 5 2 86400 20130522213204 (
+ 20130422213204 15 example.net.
+ keVDCOpsSeDReyV6O... )
+ 86400 RRSIG NSEC 5 2 86400 20130507213204 (
+ 20130407213204 14 example.net.
+ obj3HEp1GjnmhRjX... )
+ a.example.net. 86400 IN TXT "A label"
+ 86400 RRSIG TXT 5 3 86400 20130507213204 (
+ 20130407213204 14 example.net.
+ IkDMlRdYLmXH7QJnuF3v... )
+ 86400 NSEC b.example.com. TXT RRSIG NSEC
+ 86400 RRSIG NSEC 5 3 86400 20130507213204 (
+ 20130407213204 14 example.net.
+ bZMjoZ3bHjnEz0nIsPMM... )
+ ...
+
+ is reduced to the following representation:
+
+ SOA2006022100
+ RRSIG14(SOA2006022100)
+ DNSKEY14
+ DNSKEY15
+
+ RRSIG14(KEY)
+ RRSIG15(KEY)
+
+ The rest of the zone data has the same signature as the SOA record,
+ i.e., an RRSIG created with DNSKEY 14.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 33]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+Authors' Addresses
+
+ Olaf M. Kolkman
+ NLnet Labs
+ Kruislaan 419
+ Amsterdam 1098 VA
+ The Netherlands
+
+ EMail: olaf@nlnetlabs.nl
+ URI: http://www.nlnetlabs.nl
+
+
+ R. (Miek) Gieben
+
+ EMail: miek@miek.nl
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 34]
+
+RFC 4641 DNSSEC Operational Practices September 2006
+
+
+Full Copyright Statement
+
+ Copyright (C) The Internet Society (2006).
+
+ This document is subject to the rights, licenses and restrictions
+ contained in BCP 78, and except as set forth therein, the authors
+ retain all their rights.
+
+ This document and the information contained herein are provided on an
+ "AS IS" basis and THE CONTRIBUTOR, THE ORGANIZATION HE/SHE REPRESENTS
+ OR IS SPONSORED BY (IF ANY), THE INTERNET SOCIETY AND THE INTERNET
+ ENGINEERING TASK FORCE DISCLAIM ALL WARRANTIES, EXPRESS OR IMPLIED,
+ INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE
+ INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED
+ WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.
+
+Intellectual Property
+
+ The IETF takes no position regarding the validity or scope of any
+ Intellectual Property Rights or other rights that might be claimed to
+ pertain to the implementation or use of the technology described in
+ this document or the extent to which any license under such rights
+ might or might not be available; nor does it represent that it has
+ made any independent effort to identify any such rights. Information
+ on the procedures with respect to rights in RFC documents can be
+ found in BCP 78 and BCP 79.
+
+ Copies of IPR disclosures made to the IETF Secretariat and any
+ assurances of licenses to be made available, or the result of an
+ attempt made to obtain a general license or permission for the use of
+ such proprietary rights by implementers or users of this
+ specification can be obtained from the IETF on-line IPR repository at
+ http://www.ietf.org/ipr.
+
+ The IETF invites any interested party to bring to its attention any
+ copyrights, patents or patent applications, or other proprietary
+ rights that may cover technology that may be required to implement
+ this standard. Please address the information to the IETF at
+ ietf-ipr@ietf.org.
+
+Acknowledgement
+
+ Funding for the RFC Editor function is provided by the IETF
+ Administrative Support Activity (IASA).
+
+
+
+
+
+
+
+Kolkman & Gieben Informational [Page 35]
+