Skip to content

Integration Notes

xvzcf edited this page Jun 17, 2020 · 1 revision

= = = WORK IN PROGRESS = = =

This page describes how we integrated post-quantum cryptography (PQC) into the SSH2 protocol, and in particular, in the OpenSSH implementation. Note that further implementation notes can be found by grepping for "OQS note" in the code base.

Key exchange

TODO: describe PQ-only and hybrid KEX.

Authentication

TODO: describe PQ-only sig.

In addition to post-quantum (PQ) signatures; we also support classical/PQ hybrids. In that case, a classical and a PQ signature are generated on the same data, and the resulting signatures are concatenated. We combine RSA or ECDSA (using the NIST curves) with the supported OQS algorithm at an equivalent security level; this means using:

  • RSA3072 and NIST-P256 for L1 schemes, and
  • NIST-P384 for L3 schemes (RSA isn't supported above L1 for efficiency reasons)

New key types have been defined for the hybrid cases, identified by the ssh-<classical>-<pq> string, where <classical> is either p256, p384, or rsa3072 and <pq> is one of the supported PQ schemes.

Keys are serialized sequentially: the classical key is serialized first, followed by the PQ one. The SSH key encoding contains all the length and serialization information, so the OpenSSH serialization for each type is called sequentially.

The OpenSSH signature code is called sequentially: the classical handling is performed first (including hashing the signed data with the appropriate SHA2 functions (SHA256 for L1 schemes, SHA384 for L3 schemes)), followed by the PQ one (in which case the data is signed/verified directly). The resulting signatures are encoded as follows:

  • classical_sig_len: 4 bytes encoding the size of the classical signature
  • classical_sig: the classical signature of length classical_sig_len
  • pq_sig_len: 4 bytes encoding the size of the post-quantum signature
  • pq_sig: the post-quantum signature of length pq_sig_len

Implementation Limits

In order to support algorithms with large key/signature sizes, such as Rainbow, Picnic, or McEliece, we had to increase various limits throughout the code:

  • msg.c: We increased the maximum value of msg_len in ssh_msg_recv from 256 * 1024 to 65536 * 1024.
  • sshkey.h: We increased SSH_KEY_MAX_SIGN_DATA_SIZE from (1 << 20) to (1 << 25).
  • packet.c: We increased PACKET_MAX_SIZE from 256 * 1024 to 2048 * 1024.
  • authfile.c: We increased MAX_KEY_FILE_SIZE from 1024 * 1024 to 67108864
  • monitor_wrap.c: We increased the maximum value of msg_len in mm_request_receive from 256 * 1024 to 65536 * 1024.