A Cryptographically Generated Address (CGA) is an Internet Protocol Version 6 (IPv6) address that has a host identifier computed from a cryptographic hash function. [1] This procedure is a method for binding a public signature key to an IPv6 address in the Secure Neighbor Discovery Protocol (SEND). [2]
A Cryptographically Generated Address is an IPv6 address whose interface identifier has been generated according to the CGA generation method. The interface identifier is formed by the least-significant 64 bits of an IPv6 address and is used to identify the host's network interface on its subnet. The subnet is determined by the most-significant 64 bits, the subnet prefix.
Apart from the public key that is to be bound to the CGA, the CGA generation method takes several other input parameters including the predefined subnet prefix. These parameters, along with other parameters that are generated during the execution of the CGA generation method, form a set of parameters called the CGA Parameters data structure. The complete set of CGA Parameters has to be known in order to be able to verify the corresponding CGA.
The CGA Parameters data structure consists of:
modifier
: a random 128-bit unsigned integer;subnetPrefix
: the 64-bit prefix that defines to which subnet the CGA belongs;collCount
: an 8-bit unsigned integer that must be 0, 1, or 2;publicKey
: the public key as a DER-encoded ASN.1 structure of the type SubjectPublicKeyInfo;extFields
: an optional variable-length field (default length 0).Additionally, a security parameter Sec
determines the CGA's strength against brute-force attacks. This is a 3-bit unsigned integer that can have any value from 0 up to (and including) 7 and is encoded in the three leftmost bits of the CGA's interface identifier. The higher the value of Sec
, the higher the level of security, but also the longer it generally takes to generate a CGA. For convenience, the intermediate Sec
values in the pseudocode below are assumed to be stored as 8-bit unsigned integers that cannot have a value greater than 7.
The following piece of pseudocode represents the CGA generation method, which is used to create a new Cryptographically Generated Address.
1 procedure generateCGA(Sec, subnetPrefix, publicKey, extFields): 2 modifier := random(0x00000000000000000000000000000000, // 16 octets (128 bits) 3 0xffffffffffffffffffffffffffffffff) 4 5 label1: 6 concat := concatenate(modifier, 0x000000000000000000, // 9 zero octets 7 publicKey, extFields) 8 9 digest := SHA1(concat) 10 Hash2 := digest[0:14] // 14*8 = 112 leftmost bits 11 12 ifSec ≠ 0 andHash2[0:2*Sec] ≠ 0: // 2*Sec*8 = 16*Sec leftmost bits 13 modifier := modifier + 1 14 goto label1 15 end if 16 17 collCount := 0x00 // 8-bit collision count 18 19 label2: 20 concat := concatenate(modifier, subnetPrefix, collCount, 21 publicKey, extFields) 22 23 digest := SHA1(concat) 24 Hash1 := digest[0:8] // 8*8 = 64 leftmost bits 25 26 intID := Hash1 // Hash1 becomes interface identifier... 27 intID[0] := intID[0] binary and 0x1c binary or (Sec << 5) // ...after writing Sec and u/g bits 28 29 CGA := concatenate(subnetPrefix, intID) // concatenate to form the CGA 30 31 if duplicate(CGA): 32 collCount := collCount + 1 33 34 ifcollCount = 3: 35 abort 36 end if 37 38 goto label2 39 end if 40 41 return [CGA, [modifier, subnetPrefix, collCount, publicKey, extFields]] 42 end procedure
The CGA's interface identifier is largely formed by Hash1
, which is taken from the first 64 bits of the digested CGA Parameters data structure (lines 20 to 24). On line 27, the first three bits are overwritten by the Sec
value and the reserved "u" and "g" bits (the seventh and eighth bit) are set to 0.
The Sec
parameter implements a hash extension by enforcing the first 16 times Sec
bits of another hash, Hash2
, to be 0. This hash is the result of the digested CGA Parameters data structure with subnetPrefix
and collCount
essentially set to 0. A brute-force search is performed to find a suitable Hash2
, incrementing the modifier
by 1 each iteration (lines 6 to 15). Because more bits need to be 0 with a higher Sec
value, the average time required to perform the search increases exponentially with the value of Sec
.
After concatenating the subnet prefix and the generated interface identifier to create the CGA, duplicate address detection may be performed. If the address is already in use, then the collision counter collCount
is incremented by 1 and a new interface identifier is generated (lines 20 to 39). Because collCount
is not used in calculating Hash2
, it is not necessary to search for a new Hash2
when an address collision occurs. For a similar reason, subnetPrefix
is not used either so that if the subnet prefix of the address changes but the host's public key does not, then the same modifier could be reused and there is no need to search for a new Hash2
.
On line 41 the CGA is returned, along with the CGA Parameters data structure.
A Cryptographically Generated Address is used to verify that received signed messages were sent by the host to which that address has been assigned. This is done by verifying that the key pair used for signing has been bound to the CGA. Because the authenticity of the public key can be verified this way, there is no need for a public key infrastructure. If the host itself is required to be authenticated as well, however, then the CGA itself needs to be authenticated beforehand since the bound public key cannot be trusted if the address is not trusted in such a case (assuming it has not been verified by other methods than CGA).
The CGA verification method, in which a public key is verified to be bound to a CGA, requires the corresponding CGA Parameters data structure as input and can be implemented as follows.
1 procedure verifyCGA(CGA, [modifier, subnetPrefix, collCount, publicKey, extFields]): 2 ifcollCount > 2 orCGA[0:8] ≠ subnetPrefix: 3 return false 4 end if 5 6 concat := concatenate(modifier, subnetPrefix, collCount, 7 publicKey, extFields) 8 9 digest := SHA1(concat) 10 Hash1 := digest[0:8] // 8*8 = 64 leftmost bits 11 Hash1[0] := Hash1[0] binary and 0x1c // ignore Sec and u/g bits 12 13 intID := CGA[8:16] // interface identifier (64 rightmost bits) 14 intID[0] := intID[0] binary and 0x1c // ignore Sec and u/g bits 15 16 ifHash1 ≠ intID: 17 return false 18 end if 19 20 Sec := CGA[8] >> 5 // extract Sec from interface identifier 21 22 concat := concatenate(modifier, 0x000000000000000000, // 9 zero octets 23 publicKey, extFields) 24 25 digest := SHA1(concat) 26 Hash2 := digest[0:14] // 14*8 = 112 leftmost bits 27 28 ifSec ≠ 0 andHash2[0:2*Sec] ≠ 0: // 2*Sec*8 = 16*Sec leftmost bits 29 return false 30 end if 31 32 return true // verification succeeded 33 end procedure
The method starts with checking if collCount
from the CGA Parameters data structure has a valid value and if subnetPrefix
from the same data structure matches the CGA's subnet prefix (on line 2). This is done for security reasons.
From line 6 to 18, Hash1
is calculated from the CGA Parameters data structure (which includes the public key and the subnet prefix) and the relevant bits are compared to those of the CGA's interface identifier. In this case, this is done by setting the first three bits (Sec
) and the seventh and eighth bit ("u" and "g" bits) of both Hash1
and the interface identifier to 0 on lines 11 and 14 for easy comparison.
After extracting Sec
from the CGA's interface identifier, Hash2
is calculated and the first 16 times Sec
bits of the hash are compared to 0 (lines 22 to 30). If all checks turn out well, then the public key has been verified to be bound to (i.e. to be valid for) that CGA.
In order for an attacker to make a client believe it received a valid message from a certain CGA that isn't owned by the attacker, the attacker must find a hash collision for the relevant bits of Hash1
and Hash2
by performing a brute-force attack. If the attacker finds a set of CGA Parameters (including a public key for which the attacker knows the private key) that can be used to generate the same CGA as the target CGA, then the attacker can impersonate the host who actually owns the CGA without being detected (except perhaps when the client has contacted the host before and notices that the public key has changed but the CGA has not).
Of the 64 bits of Hash1
, only 59 are used in the interface identifier since 5 bits are being overwritten. For a CGA with Sec
equal to 0, this means that the cost of finding a set of CGA Parameters that yield the desired 59 bits is approximately (in big O notation). A larger value of Sec
, however, increases this cost by a factor of to because the first 16 times Sec
bits of Hash2
then become relevant (i.e. it implements a hash extension by demanding those bits to be equal to 0). In the CGA generation process, the cost of generating an address is increased by the same factor depending on the value of Sec
, but the cost of using and verifying a CGA remains constant.
Because Sec
is not part of the CGA Parameters data structure but of the address itself, an attacker cannot use a Sec
value smaller than that of the target address (like 0) in an attempt to skip (or scale down) the brute-force attack on Hash2
. This would namely yield a different CGA from the target CGA since at least one of the three leftmost bits of the interface identifier would not match. If the target Sec
value is written to the interface identifier anyway, then Hash2
will (almost certainly) be found to lack the required amount of leftmost 0-bits during the verification process.
During the CGA generation process, it is very unlikely that three address collisions occur. If a duplicate address would be detected for the third time, then this would most likely be due to a configuration or implementation error or a denial-of-service attack. For this reason, the number of valid values for collCount
is limited to the range from 0 to 2. This parameter must be verified to be in this range during the CGA verification process in order to prevent an attacker from exploiting it and trying all different values without the need to perform another brute-force search for Hash2
each time a different value is tried.
By including the subnet prefix in the digest operation that results in Hash1
, it can be prevented that an attacker is able to use a single pre-computed database to attack addresses with different subnet prefixes. A verifier can also be sure that the public key has been bound to this exact address and not possibly to an address with the same interface identifier but a different subnet prefix. Since the CGA specification prescribes to use the subnetPrefix
from the CGA Parameters data structure for the digest operations, it must be verified that it matches the subnet prefix of the CGA during the CGA verification process.
The Dynamic Host Configuration Protocol (DHCP) is a network management protocol used on Internet Protocol (IP) networks for automatically assigning IP addresses and other communication parameters to devices connected to the network using a client–server architecture.
An Internet Protocol address is a numerical label such as 192.0.2.1 that is connected to a computer network that uses the Internet Protocol for communication. An IP address serves two main functions: network interface identification, and location addressing.
Internet Protocol version 4 (IPv4) is the fourth version of the Internet Protocol (IP). It is one of the core protocols of standards-based internetworking methods in the Internet and other packet-switched networks. IPv4 was the first version deployed for production on SATNET in 1982 and on the ARPANET in January 1983. It is still used to route most Internet traffic today, even with the ongoing deployment of Internet Protocol version 6 (IPv6), its successor.
In cryptography, SHA-1 is a hash function which takes an input and produces a 160-bit (20-byte) hash value known as a message digest – typically rendered as 40 hexadecimal digits. It was designed by the United States National Security Agency, and is a U.S. Federal Information Processing Standard. The algorithm has been cryptographically broken but is still widely used.
Classless Inter-Domain Routing is a method for allocating IP addresses and for IP routing. The Internet Engineering Task Force introduced CIDR in 1993 to replace the previous classful network addressing architecture on the Internet. Its goal was to slow the growth of routing tables on routers across the Internet, and to help slow the rapid exhaustion of IPv4 addresses.
A subnetwork or subnet is a logical subdivision of an IP network. The practice of dividing a network into two or more networks is called subnetting.
A Universally Unique Identifier (UUID) is a 128-bit label used for information in computer systems. The term Globally Unique Identifier (GUID) is also used, mostly in Microsoft systems.
Dot-decimal notation is a presentation format for numerical data. It consists of a string of decimal numbers, using the full stop (dot) as a separation character.
A cryptographic hash function (CHF) is a hash algorithm that has special properties desirable for a cryptographic application:
In cryptography, the Elliptic Curve Digital Signature Algorithm (ECDSA) offers a variant of the Digital Signature Algorithm (DSA) which uses elliptic-curve cryptography.
In cryptography, a message authentication code (MAC), sometimes known as an authentication tag, is a short piece of information used for authenticating a message. In other words, to confirm that the message came from the stated sender and has not been changed. The MAC value protects a message's data integrity, as well as its authenticity, by allowing verifiers to detect any changes to the message content.
Magnet is a URI scheme that defines the format of magnet links, a de facto standard for identifying files (URN) by their content, via cryptographic hash value rather than by their location.
In cryptography, PBKDF1 and PBKDF2 are key derivation functions with a sliding computational cost, used to reduce vulnerability to brute-force attacks.
In cryptography, a message authentication code based on universal hashing, or UMAC, is a type of message authentication code (MAC) calculated choosing a hash function from a class of hash functions according to some secret (random) process and applying it to the message. The resulting digest or fingerprint is then encrypted to hide the identity of the hash function used. As with any MAC, it may be used to simultaneously verify both the data integrity and the authenticity of a message.
The Neighbor Discovery Protocol (NDP), or simply Neighbor Discovery (ND), is a protocol of the Internet protocol suite used with Internet Protocol Version 6 (IPv6). It operates at the link layer of the Internet model, and is responsible for gathering various information required for network communication, including the configuration of local connections and the domain name servers and gateways.
In public-key cryptography, a public key fingerprint is a short sequence of bytes used to identify a longer public key. Fingerprints are created by applying a cryptographic hash function to a public key. Since fingerprints are shorter than the keys they refer to, they can be used to simplify certain key management tasks. In Microsoft software, "thumbprint" is used instead of "fingerprint."
An Internet Protocol Version 6 address is a numeric label that is used to identify and locate a network interface of a computer or a network node participating in a computer network using IPv6. IP addresses are included in the packet header to indicate the source and the destination of each packet. The IP address of the destination is used to make decisions about routing IP packets to other networks.
The IBM System/360 architecture is the model independent architecture for the entire S/360 line of mainframe computers, including but not limited to the instruction set architecture. The elements of the architecture are documented in the IBM System/360 Principles of Operation and the IBM System/360 I/O Interface Channel to Control Unit Original Equipment Manufacturers' Information manuals.
crypt is a POSIX C library function. It is typically used to compute the hash of user account passwords. The function outputs a text string which also encodes the salt, and identifies the hash algorithm used. This output string forms a password record, which is usually stored in a text file.
Argon2 is a key derivation function that was selected as the winner of the 2015 Password Hashing Competition. It was designed by Alex Biryukov, Daniel Dinu, and Dmitry Khovratovich from the University of Luxembourg. The reference implementation of Argon2 is released under a Creative Commons CC0 license or the Apache License 2.0, and provides three related versions: