#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