Skip to content
This repository has been archived by the owner on Feb 18, 2021. It is now read-only.

Latest commit

 

History

History
60 lines (34 loc) · 4.57 KB

2a.md

File metadata and controls

60 lines (34 loc) · 4.57 KB

Cipher Set 2a

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

Keys

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).

Message BODY

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 key
  • IV - 12 bytes, a random but unique value determined by the sender for each message
  • CIPHERTEXT - AES-256-GCM encrypted inner packet and sender signature
  • MAC - 16 bytes, GCM 128-bit MAC/tag digest (some GCM implementations auto-append this)

The CIPHERTEXT once deciphered contains:

  • INNER - inner packet raw bytes
  • SIG - 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.

Channel Setup

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 BODY

Channel packet binary BODY is defined as:

  • TOKEN - 16 bytes, from the handshake, required for all channel packets
  • IV - 12 bytes, a random but unique value determined by the sender for each message
  • CHANNEL CIPHERTEXT - the AES-256-GCM encrypted channel packet
  • GCM 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.