PQC in ZRTP (RFC6189)
Johan Pascal <[email protected]> Tue, 23 Nov 2021 23:50:26 +0100
| Newsgroups | gmane.ietf.saag,gmane.ietf.avt |
|---|---|
| Message-ID | <[email protected]> |
Dear Saag and AvtCore, as already discussed on Saag ( https://mailarchive.ietf.org/arch/msg/saag/HjxX-4QcqbgO6pshPsPozbhxTV0/ ) I'm working on introducing PQC in ZRTP. On Colin Perkins' advice, I post this also on avtcore. I'm not yet ready to publish an I-D, but eager to get external eyes on the solution I figured to solve the problem of substituting DH with PQC-KEM in ZRTP. For those not familiar with ZRTP, it's a key exchange protocol with authentication over a voice channel using a Short-Authentication-String(SAS). Stripping it to the very core of the key exchange it basically does: Alice and Bob generates DH key pairs (Pka, Ska) and (PKb, Skb). 1) Bob sends a Commit packet holding hash(Pkb) 2) Alice sends DH1 packet holding Pka 3) Bob sends DH2 packet holding PKb They both compute a shared secret DHab using the peer's public key and their secret one. They then derive s0 from DHab and a transcript of the exchange. From this, a 20bits hash is generated and turned into a human readable string(the SAS) to be compared over a voice channel. Bob sending hash(Pkb) prevent an attacker to put himself in a position of choosing the final SAS(by generating his key pair leading to the desired SAS) trying to find a collision (on 20 bits it is not difficult) starting from two different Pka. Whole details in the RFC: https://datatracker.ietf.org/doc/html/rfc6189 In order to introduce PQC to this scheme, it must be adapted to KEM interface: Pk,Sk = KEM_keyGen() Ct,Secret = KEM_encaps(Pk) Secret = KEM_decaps(Ct, Sk) This cannot be used directly in the current ZRTP scheme: if Alice sends her Pk in DH1 packet, Bob can't commit to Ct before receiving it. Two solutions to solve this problem : A - Both parties encapsulate a secret. Alice and Bob both generate a key pair (Pka,Ska) and (Pkb,Skb) 1) Bob sends Pkb 2) Alice generates Cta,Secreta = KEM_encaps(Pkb) then sends Pka and hash(Cta) 3) Bob generates Ctb,Secretb = KEM_encaps(Pka) then sends Ctb 4) Alice sends Cta They both derive s0 using Secreta, Secretb and a transcript of the exchange In this version there is one additional packet, Alice sending hash(Cta) plays the role of hash(Pkb) from the original ZRTP. B - Only Alice encapsulates a secret 1) Bob generates Pkb,Skb and a random nonce then sends Pkb and hash(nonce) to Alice 2) Alice generate Ct, Secret = KEM_encaps(Pkb) then sends Ct to Bob 3) Bob sends the nonce They both derive s0 using Secret, nonce and a transcript of the exchange. No extra packets, the exchange is still safe against simple wiretapping thanks to the KEM and no parties gets to choose the SAS after getting the other party material involved in its generation: Alice doesn't have the nonce when she generates Ct and Secret, Bob commits to use the nonce before receiving Ct. The second solution seems simpler and have my preference. Anyone read this long email until here and have comments on these schemes? Note: Hybrid key exchange would be addressed inside the KEM itself performing both a PQC-KEM and a DH-based KEM. Thanks Johan