Skip to main content

Appendix B. Key Tag Calculation

The Key Tag field in the RRSIG and DS resource record types provides a mechanism for selecting a public key efficiently. In most cases, the combination of owner name, algorithm, and key tag can efficiently identify the DNSKEY record. Both the RRSIG and DS resource records have corresponding DNSKEY records. The Key Tag field in the RRSIG and DS records can be used to help select the corresponding DNSKEY RR efficiently when more than one candidate DNSKEY RR is available.

However, it is essential to note that the key tag is not a unique identifier. It is possible for two distinct DNSKEY RRs to have the same owner name, the same algorithm, and the same key tag. The key tag is used to limit the possible candidate keys, but it does not uniquely identify a DNSKEY record. Implementations MUST NOT assume that the key tag uniquely identifies a DNSKEY RR.

The key tag is the same for all DNSKEY algorithm types except algorithm 1 (see Appendix B.1 for the definition of the key tag for algorithm 1). The key tag algorithm is the sum of the wire format of the DNSKEY RDATA broken into 2 octet groups. First, the RDATA (in wire format) is treated as a series of 2 octet groups. These groups are then added together, ignoring any carry bits.

A reference implementation of the key tag algorithm, in the form of an ANSI C function, is given below, using the RDATA portion of the DNSKEY RR as input. It is not necessary to use this reference code verbatim, but the numerical value of the Key Tag MUST be identical to the value generated by the reference implementation for the same input.

Note that the algorithm used to calculate the Key Tag is almost but not quite the one's complement checksum used in many other Internet protocols. The algorithm described here MUST be used rather than the one's complement checksum to calculate the Key Tag.

The following ANSI C reference implementation calculates the value of a Key Tag. This reference implementation applies to all algorithm types except algorithm 1 (see Appendix B.1). The input is the wire format of the RDATA portion of the DNSKEY RR. The code is written for clarity, not efficiency.

/*
* Assumes that int is at least 16 bits.
* First octet of the key tag is the most significant 8 bits of the
* return value;
* Second octet of the key tag is the least significant 8 bits of the
* return value.
*/

unsigned int
keytag (
unsigned char key[], /* the RDATA part of the DNSKEY RR */
unsigned int keysize /* the RDLENGTH */
)
{
unsigned long ac; /* assumed to be 32 bits or larger */
int i; /* loop index */

for ( ac = 0, i = 0; i < keysize; ++i )
ac += (i & 1) ? key[i] : key[i] << 8;
ac += (ac >> 16) & 0xFFFF;
return ac & 0xFFFF;
}

B.1. Key Tag for Algorithm 1 (RSA/MD5) \

The key tag for algorithm 1 (RSA/MD5) is defined differently from the key tag for all other algorithms, for historical reasons. For a DNSKEY RR with algorithm 1, the key tag is defined to be the most significant 16 bits of the least significant 24 bits in the public key modulus (in other words, the 4th and 5th to last octets of the public key modulus).

Note that use of algorithm 1 is NOT RECOMMENDED.


Related Chapter Navigation: