Files
rosenpass/analysis/01_secrecy.entry.mpv
Karolin Varner 137cd5e85a add proverif analysis of Rosenpass, the protocol
The analysis was conducted as joint effort between @koraa and @blipp.

Co-authored-by: Benjamin Lipp <blipp@mailbox.org>
2023-02-23 20:46:22 +01:00

181 lines
10 KiB
Plaintext

#define CHAINING_KEY_EVENTS 1
#define MESSAGE_TRANSMISSION_EVENTS 0
#define SESSION_START_EVENTS 0
#define RANDOMIZED_CALL_IDS 0
#include "config.mpv"
#include "prelude/basic.mpv"
#include "crypto/key.mpv"
#include "crypto/kem.mpv"
#include "rosenpass/oracles.mpv"
let main = rosenpass_main.
@lemma "state coherence, initiator: Initiator accepting a RespHello message implies they also generated the associated InitHello message"
lemma ini:key, ih:key, rh:key, any_psk:key, any_sski:kem_sk, any_spkr:kem_pk, any_sptr:key;
event(OskOresp_hello(ini, ih, rh))
==> event(OskOinitiator(ini, any_psk, any_sski, any_spkr, any_sptr)).
@lemma "state coherence, responder: Responder accepting an InitConf message implies they also generated the associated RespHello message"
lemma ini:key, rh:key, ic:key, any_psk:key, any_sskr:kem_sk, any_spki:kem_pk, any_epki:kem_pk, any_epti:key, any_spti:key;
event(OskOinit_conf(rh, ic))
==> event(OskOinit_hello(ini, rh, any_psk, any_sskr, any_spki, any_epki, any_epti, any_spti)).
@reachable "functionality: Key exchange can be achieved"
query ini:key, ih1:key, ih2:key, rh:key;
event(OskOresp_hello(ini, ih1, rh)) && event(OskOinit_conf(ih2, rh)).
@lemma "secrecy: Adv can not learn shared secret key"
lemma kp:key_prec, skp:kem_sk_prec;
attacker(trusted_key(kp)).
@lemma "secrecy: There is no way for an attacker to learn a trusted kem secret key"
lemma skp:kem_sk_prec;
attacker(trusted_kem_sk(skp)).
@lemma "secrecy: The adversary can learn a trusted kem pk only by using the reveal oracle"
lemma skp:kem_sk_prec;
attacker(kem_pub(trusted_kem_sk(skp)))
==> event(RevealPk(kem_pub(trusted_kem_sk(skp)))).
@reachable "non-secrecy: The attacker can learn the value of a shared key" // (by using a malicious/non-trusted key)
query k:key;
attacker(prepare_key(k)) && attacker(k).
@reachable "non-secrecy: The attacker can learn the value of a kem secret key" // (by using a malicious/non-trusted key)
query sk:kem_sk;
attacker(prepare_kem_sk(sk)) && attacker(sk).
// Demonstrates how to check that a key is malicious in a lemma
@lemma "secrecy: Attacker knowledge of a shared key implies the key is not trusted"
lemma k:key, kp:key_prec;
attacker(prepare_key(k)) && attacker(k) ==> k <> trusted_key(kp).
@lemma "secrecy: Attacker knowledge of a kem sk implies the key is not trusted"
lemma k:kem_sk, kp:kem_sk_prec;
attacker(prepare_kem_sk(k)) && attacker(k) ==> k <> trusted_kem_sk(kp).
// Actual in-protocol secrecy queries
@lemma "symmetric secrecy: Secure PSK is sufficient for ck secrecy after trusted InitHello transmission from initiator perspective"
lemma ck:key, Ppsk:key_prec, any_sski:kem_sk, any_spkr:kem_pk, any_sptr:key;
let secure_psk = trusted_key(Ppsk) in
event(OskOinitiator(ck, secure_psk, any_sski, any_spkr, any_sptr)) && attacker(ck).
@lemma "asymmetric secrecy: Secure SSKR is sufficient for ck secrecy after trusted InitHello transmission from initiator perspective"
lemma ck:key, any_psk:key, any_sski:kem_sk, Psskr:kem_sk_prec, Psptr:seed_prec;
let secure_spkr = kem_pub(trusted_kem_sk(Psskr)) in
let secure_sptr = rng_key(trusted_seed(Psptr)) in // to account for a captured RNG
event(OskOinitiator(ck, any_psk, any_sski, secure_spkr, secure_sptr)) && attacker(ck).
@lemma "symmetric secrecy: Secure PSK is sufficient for ck secrecy after trusted RespHello transmission from responder perspective"
lemma ck_ini:key, ck:key, Ppsk:key_prec, any_sskr:kem_sk, any_spki:kem_pk, any_epki:kem_pk, any_epti:key, any_spti:key;
let secure_psk = trusted_key(Ppsk) in
attacker(ck)
&& event(OskOinit_hello(ck_ini, ck, secure_psk, any_sskr, any_spki, any_epki, any_epti, any_spti)).
@lemma "asymmetric secrecy: Secure SSKI is sufficient for ck secrecy after trusted InitHello transmission from responder perspective"
lemma ck_ini:key, ck:key, any_psk:key, any_sskr:kem_sk, PSsski:kem_sk_prec, any_epki:kem_pk, any_epti:key, PSspti:seed_prec;
let secure_spki = kem_pub(trusted_kem_sk(PSsski)) in
let secure_spti = rng_key(trusted_seed(PSspti)) in /* Accounting for captured RNG */
attacker(ck)
&& event(OskOinit_hello(ck_ini, ck, any_psk, any_sskr, secure_spki, any_epki, any_epti, secure_spti)).
@lemma "forward, asymmetric secrecy: Secure ESKI is sufficient for ck secrecy after trusted InitHello transmission from responder perspective"
lemma ck_ini:key, ck:key, any_psk:key, any_sskr:kem_sk, any_spki:kem_pk, Peski:kem_sk_prec, Pepti:seed_prec, any_spti:key;
let secure_epki = kem_pub(trusted_kem_sk(Peski)) in
let secure_epti = rng_key(trusted_seed(Pepti)) in /* Accounting for captured RNG */
attacker(ck)
&& event(OskOinit_hello(ck_ini, ck, any_psk, any_sskr, any_spki, secure_epki, secure_epti, any_spti)).
// TODO: Do not mention OskOinitiator
@lemma "symmetric secrecy: Secure PSK is sufficient for ck secrecy after trusted InitConf transmission from initiator perspective"
// (Follows directly from the same property on Oinitiator)
lemma ini:key, ih:key, rh:key, Ppsk:key_prec, any_sski:kem_sk, any_spkr:kem_pk, any_sptr:key;
let secure_psk = trusted_key(Ppsk) in
attacker(rh)
&& event(OskOinitiator(ini, secure_psk, any_sski, any_spkr, any_sptr))
&& event(OskOresp_hello(ini, ih, rh)).
// TODO: Do not mention OskOinitiator
@lemma "asymmetric secrecy: Secure SSKR is sufficient for ck secrecy after trusted RespHello transmission from initiator perspective"
// (Follows directly from the same property on Oinitiator)
lemma ini:key, ih:key, rh:key, any_psk:key, any_sski:kem_sk, Psskr:kem_sk_prec, Psptr:seed_prec;
let secure_spkr = kem_pub(trusted_kem_sk(Psskr)) in
let secure_sptr = rng_key(trusted_seed(Psptr)) in // to account for a captured RNG
attacker(rh)
&& event(OskOinitiator(ini, any_psk, any_sski, secure_spkr, secure_sptr))
&& event(OskOresp_hello(ini, ih, rh)).
@lemma "passive asymmetric secrecy: Secure SSKI is sufficient for ck secrecy after trusted RespHello transmission from initiator perspective"
// (Follows directly from the same property on Oinitiator)
lemma ini:key, ih:key, rh:key, any_psk:key, any_psk2:key, Psski:kem_sk_prec,
any_sskr:kem_sk, any_spki:kem_pk, any_epki:kem_pk, any_spkr:kem_pk,
any_sptr:key, any_epti:key, Pspti:seed_prec;
let secure_sski = trusted_kem_sk(Psski) in
let secure_spti = rng_key(trusted_seed(Pspti)) in // to account for a captured RNG
// That spki must be must bee derived from secure_sski follows from the same chaining key
// being put out, since spki is mixed into the chaining key. Specifying it speeds up the
// validation though. TODO: Turn this into a lemma?
// TODO: Do we event need SPKI in the initiator event?
#if SIMPLE_MODEL
let ih_spki = kem_pub(secure_sski) in
#else
let ih_spki = any_spki in
#endif
attacker(rh)
&& event(OskOinitiator(ini, any_psk, secure_sski, any_spkr, any_sptr))
&& event(OskOinit_hello(ini, ih, any_psk2, any_sskr, ih_spki, any_epki, any_epti, secure_spti))
&& event(OskOresp_hello(ini, ih, rh)).
@lemma "forward asymmetric secrecy: Secure SSKI is sufficient for ck secrecy after trusted RespHello transmission from initiator perspective"
// (Follows directly from the same property on Oinitiator)
lemma ini:key, ih:key, rh:key, any_psk:key, any_psk2:key, Peski:kem_sk_prec,
any_sskr:kem_sk, any_sski:kem_sk, any_spki:kem_pk, any_epki:kem_pk, any_spkr:kem_pk,
any_sptr:key, Pepti:seed_prec, any_spti:key;
let secure_epki = kem_pub(trusted_kem_sk(Peski)) in
let secure_epti = rng_key(trusted_seed(Pepti)) in // to account for a captured RNG
attacker(rh)
&& event(OskOinitiator(ini, any_psk, any_sski, any_spkr, any_sptr))
&& event(OskOinit_hello(ini, ih, any_psk2, any_sskr, any_spki, secure_epki, secure_epti, any_spti))
&& event(OskOresp_hello(ini, ih, rh)).
// TODO: Add continuity queries: InitConf acceptance implies that there was a InitHello acceptance and so on
@lemma "symmetric secrecy: Secure PSK is sufficient for ck secrecy after trusted InitConf acceptance from responder perspective"
lemma ini:key, rh:key, ic:key, Ppsk:key_prec, any_sskr:kem_sk, any_spki:kem_pk, any_epki:kem_pk, any_epti:key, any_spti:key;
let secure_psk = trusted_key(Ppsk) in
attacker(ic)
&& event(OskOinit_hello(ini, rh, secure_psk, any_sskr, any_spki, any_epki, any_epti, any_spti))
&& event(OskOinit_conf(rh, ic)).
@lemma "asymmetric secrecy: Secure SSKI is sufficient for ck secrecy after InitConf acceptance from responder perspective"
lemma ini:key, rh:key, ic:key, any_psk:key, any_sskr:kem_sk, PSsski:kem_sk_prec, any_epki:kem_pk, any_epti:key, PSspti:seed_prec;
let secure_spki = kem_pub(trusted_kem_sk(PSsski)) in
let secure_spti = rng_key(trusted_seed(PSspti)) in /* Accounting for captured RNG */
attacker(ic)
&& event(OskOinit_hello(ini, rh, any_psk, any_sskr, secure_spki, any_epki, any_epti, secure_spti))
&& event(OskOinit_conf(rh, ic)).
@lemma "forward, asymmetric secrecy: Secure ESKI is sufficient for ck secrecy after InitConf acceptance from responder perspective"
lemma ini:key, rh:key, ic:key, any_psk:key, any_sskr:kem_sk, any_spki:kem_pk, Peski:kem_sk_prec, Pepti:seed_prec, any_spti:key;
let secure_epki = kem_pub(trusted_kem_sk(Peski)) in
let secure_epti = rng_key(trusted_seed(Pepti)) in /* Accounting for captured RNG */
attacker(ic)
&& event(OskOinit_hello(ini, rh, any_psk, any_sskr, any_spki, secure_epki, secure_epti, any_spti))
&& event(OskOinit_conf(rh, ic)).
@lemma "passive asymmetric secrecy: Secure SSKR is sufficient for ck secrecy after InitConf acceptance from responder perspective"
lemma ini:key, rh:key, ic:key, any_psk1:key, any_psk2:key, any_sski:kem_sk, any_sskr:kem_sk,
any_spki:kem_pk, any_epki:kem_pk, Psskr:kem_sk_prec, Psptr:seed_prec, any_epti:key, any_spti:key;
let secure_spkr = kem_pub(trusted_kem_sk(Psskr)) in
let secure_sptr = rng_key(trusted_seed(Psptr)) in /* Accounting for captured RNG */
attacker(ic)
&& event(OskOinitiator(ini, any_psk1, any_sski, secure_spkr, secure_sptr))
&& event(OskOinit_hello(ini, rh, any_psk2, any_sskr, any_spki, any_epki, any_epti, any_spti))
&& event(OskOinit_conf(rh, ic)).
// TODO: Anonymity queries (under which circumstances can adv identify the participants?)
// TODO: Model CPAKEM, etc