This profile is based on the algorithms used during the telehash v2 development process in 2013.
The required algorithms in this set are:
- RSA 2048 - selected as a well known and highly trusted public key algorithm and size, used as the long-lived identity
- ECC P-256 - a well known curve with many implementations, used for the ephemeral identity
- AES 256-GCM - trusted common implementations available
When generating an endpoint including CS2a
, the public/private keypair is RSA 2048.
Binary public keys are encoded in DER as X.509 SubjectPublicKeyInfo structures. (Most cryptographic libraries support this encoding; see RFC 5280 section 4.1 and RFC 3279 section 2.3.1 for more details.)
The exchange ephemeral key is generated using ECC and the p-256 curve, the resulting binary public key is uncompressed (65 bytes).
BODY bytes:
KEYS
- 256 bytes, PKCS1 OAEP (v2) RSA encrpyted ciphertext of the 65 byte uncompressed ECC P-256 ephemeral public key and a 32 byte random AES keyIV
- 12 bytes, a random but unique value determined by the sender for each messageCIPHERTEXT
- AES-256-GCM encrypted inner packet and sender signatureMAC
- 16 bytes, GCM 128-bit MAC/tag digest (some GCM implementations auto-append this)
The CIPHERTEXT
once deciphered contains:
INNER
- inner packet raw bytesSIG
- 256 bytes, PKCS1 v1.5 RSA signature of the KEYS+IV+INNER
The KEYS
is created by first generating a new ephemeral elliptic (ECC) public key for this exchange and a random 32 byte AES KEY
, and then using the endpoint's RSA key to encrypt it to the recipient's RSA public key. The ECC keypair should be generated using the P-256 (nistp256/secp256r/X9.62 prime256v1) curve. The ECC public key should be in the uncompressed form 65 bytes in length (ANSI X9.63 format) followed by the 32 byte AES KEY
bytes. The RSA encryption should use PKCS1 OAEP (v2) padding. The result is always padded to 256 bytes by OAEP.
The SIG is calculated from the concatenation of the KEYS
(256 bytes of ciphertext), IV
(12 bytes), and INNER
(raw packet) together and then using the sender's RSA public key (SHA-256 hash and PKCS1 v1.5 padding) to create a signature of it, resulting in a 256 byte SIG
value.
The CIPHERTEXT
is created by encrypting the INNER
and SIG
(concatenated together) using AES-256-GCM. The GCM IV/nonce parameter is the 12 byte (96-bit) IV
value, and the key parameter is the 32 byte secret value following the ECC public key from the decrypted KEYS
. The "tag" size for GCM is 16 bytes (128 bits), and the additional/auth data used to compute it is the 256 KEYS
bytes, resulting in the MAC
value appended to the original packet.
The channel encryption/decryption secret keys are generated by using ECDH with the local ephemeral ECC private key, and the remote ephemeral ECC public key. Two secret keys are generated by performing a SHA-256 hash with the derived ECDH derived secret (32 bytes) and sent/received decrypted secret keys from the KEYS
value (32 bytes each):
- channel encryption key: SHA256(ecdh-secret, sent-KEY, received-KEY)
- channel decryption key: SHA256(ecdh-secret, received-KEY, sent-KEY)
Channel packet binary BODY
is defined as:
TOKEN
- 16 bytes, from the handshake, required for all channel packetsIV
- 12 bytes, a random but unique value determined by the sender for each messageCHANNEL CIPHERTEXT
- the AES-256-GCM encrypted channel packetGCM TAG/MAC
- (GMAC) - 16 bytes, GCM MAC digest (some GCM libraries auto-append this with the AES-256-GCM cipher output)
The IV is 12 random bytes that must be different for every channel packet sent (incremented from a random seed) and used as the input to the GCM calculation, along with the appropriate encryption/decryption keys calculated for the exchange during setup. The tag size for GCM is 12 bytes (96 bits) and no additiona/auth data is included as input to it.