Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[WIP] Add PQC support to the Proton branch #231

Draft
wants to merge 32 commits into
base: Proton
Choose a base branch
from
Draft

[WIP] Add PQC support to the Proton branch #231

wants to merge 32 commits into from

Conversation

lubux
Copy link
Contributor

@lubux lubux commented Sep 20, 2024

Adds PQC support to the Proton branch.
https://datatracker.ietf.org/doc/draft-ietf-openpgp-pqc/

TODO:

  • Avoid dependency on circl fork
  • ML-DSA is currently not working as expected
  • Interoperability testing
  • Remove go 1.17 check form CI. Requires Go 1.20
  • Add test vectors for ML-DSA (once they exist)

twiss and others added 28 commits August 28, 2024 09:10
It is sometimes useful to encrypt data under some symmetric key.
While this was possible to do using passphrase-derived keys, there was
no support for long-term storage of the keys that was used to encrypt
the key packets.

To solve this, a new type of key is introduced. This key will hold a
symmetric key, and will be used for both encryption and decryption of
data. Specifically, as with asymmetric keys, the actual data will be
encrypted using a session key, generated ad-hoc for these data.
Then, instead of using a public key to encrypt the session key, the
persistent symmetric key will be used instead, to produce a, so to say,
Key Encrypted Key Packet.

Conversly, instead of using a private key to decrypt the session key,
the same symmetric key will be used. Then, the decrypted session key
can be used to decrypt the data packet, as usual.

As with the case of AEAD keys, it is sometimes useful to "sign"
data with a persistent, symmetric key.

This key holds a symmetric key, which can be used for both signing and
verifying the integrity of data. While not strictly needed, the
signature process will first generate a digest of the data-to-be-signed,
and then the key will be used to sign the digest, using an HMAC
construction.

For technical reasons, related to this implenetation of the openpgp
protocol, the secret key material is also stored in the newly defined
public key types. Future contributors must take note of this, and not
export or serialize that key in a way that it will be publicly availabe.

Since symmetric keys do not have a public and private part, there is no
point serializing the internal "public key" structures. Thus, symmetric
keys are skipped when serialing the public part of a keyring.
Generate an AEAD subkey when requesting an HMAC primary key.
Squashed commits:
Update KDF to use SHA3-256
[5ff62f7] WIP: bump to draft-ietf-openpgp-pqc-01
[3949477] Import CIRCL fork with ML-KEM and ML-DSA
[5033a18] Update implementation from draft v1 to v3
- Remove v6 binding for PQC KEMs
- Update KDF
- Update reference comments
- Rename SPHINCS+ to SLH-DSA
- Rename Dilithium to ML-DSA
- Rename Kyber to ML-KEM
- Add vectors generated with RNP
- Fix misc bugs and improve tests
[c53e2e3] Add benchmarking
[d832873] Add read-write tests
[8254a42] Bind PQC packets to v6
[21f33d3] Change testdata for Kyber keys and prepare for v6 PKESK
[fa295de] Change domain separation
[c5bc3c1] Add SPHINCS+ signature support
[603ced6] Add references and clean code
[9b26049] Prefer PQ keys
[6e5ec9c] Add hybrid Kyber + ECDH, Dilithium + EC/EdDSA support
- Update to Fips compliant algorithms
openpgp/v2/write.go Outdated Show resolved Hide resolved
@lubux lubux requested a review from wussler September 23, 2024 13:58
@lubux lubux requested a review from twiss September 23, 2024 13:58
openpgp/key_generation.go Show resolved Hide resolved
openpgp/key_generation.go Outdated Show resolved Hide resolved
openpgp/keys_test.go Outdated Show resolved Hide resolved

// buildKey implements the composite KDF as specified in
// https://www.ietf.org/archive/id/draft-ietf-openpgp-pqc-04.html#name-key-combiner
func buildKey(pub *PublicKey, eccSecretPoint, eccEphemeral, eccPublicKey, mlkemKeyShare, mlkemEphemeral []byte, mlkemPublicKey kem.PublicKey) ([]byte, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also about to be updated, I'd wait to merge until it's ready

openpgp/packet/encrypted_key.go Outdated Show resolved Hide resolved
@@ -1209,6 +1347,9 @@ func (pk *PublicKey) BitLength() (bitLength uint16, err error) {
bitLength = ed448.PublicKeySize * 8
case ExperimentalPubKeyAlgoAEAD:
bitLength = 32
case PubKeyAlgoMlkem768X25519, PubKeyAlgoMlkem1024X448, PubKeyAlgoMldsa65Ed25519,
PubKeyAlgoMldsa87Ed448:
bitLength = pk.q.BitLength() // Very questionable
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be discussed before we merge it

openpgp/packet/public_key.go Outdated Show resolved Hide resolved
openpgp/packet/signature.go Outdated Show resolved Hide resolved
openpgp/v2/key_generation.go Show resolved Hide resolved
dumpTestVector(t, filename, serializedArmoredMessage.String())
}

func TestV4EddsaPqKey(t *testing.T) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is to be completely re-adapted (I commented out some code to generate the vectors), definitely not ready for merge

Copy link
Contributor Author

@lubux lubux Sep 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed the test vector generator files.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants