# Lowe modified KSL
#
# Modelled after the description in the SPORE library
# http://www.lsv.ens-cachan.fr/spore/kslLowe.html
#
# Note:
# According to SPORE there are no attacks on this protocol, scyther
# finds one however. This has to be investigated further.

usertype Server, SessionKey, TimeStamp, TicketKey;
usertype ExpiredTimeStamp;
secret k: Function;

const a, b, e: Agent;
const s: Server;
const Fresh: Function;
const Compromised: Function;


const ne: Nonce;
const kee: SessionKey;
untrusted e;
compromised k(e,s);

protocol ksl-Lowe^KeyCompromise(C)
{
    // Read the names of 3 agents and disclose a session between them including
    // corresponding session key to simulate key compromise
    role C {
        const Ni,Nr,Nc,Ma,Mb: Nonce;
        const Kir: SessionKey;
        const Kbb: TicketKey;
        const Tr: ExpiredTimeStamp;
        var I,R,S: Agent;

        read_C1(C,C,    I,R,S);
        send_C2(C,C,    (Ni,I),
                        (Ni,I,Nr,R),
                        {I,Nr,Kir}k(R,S),{Ni,R,Kir}k(I,S),
                        {Tr,I,Kir}Kbb,Nc,{R,Ni}k(I,R),
                        {Nc}Kir,
                        Ma,
                        Mb,{Ma,R}Kir,
                        {I,Mb}Kir,
                        Kir,
                        Kbb
               );
        claim_C3(C,Empty, (Compromised,Kir));
        claim_C4(C,Empty, (Compromised,Kbb));
    }
}

protocol ksl-Lowe(I,R,S)
{
    role I
    {
        const Ni, Mi: Nonce;
        var Nc, Mr: Nonce;
        var T: Ticket;
        var Kir: SessionKey;
        
        send_1(I,R, Ni, I);
        read_4(R,I, { Ni,R,Kir }k(I,S), T, Nc, {R,Ni}Kir );
        send_5(I,R, { Nc }Kir );
        
        send_6(I,R, Mi,T );
        read_7(R,I, Mr,{Mi, R}Kir );
        send_8(I,R, {I,Mr}Kir );

        claim_I1(I,Secret, Kir);
        claim_I2(I,Niagree);
        claim_I3(I,Nisynch);
        claim_I4(I,Empty, (Fresh,Kir));
    }

    role R
    {
        var Ni,Mi: Nonce;
        const Nr,Nc,Mr: Nonce;
        var Kir: SessionKey;
        const Kbb: TicketKey;
        const Tr: TimeStamp;
        var T: Ticket;
        
        read_1(I,R, Ni, I);
        send_2(R,S, Ni, I, Nr, R );
        read_3(S,R, { I, Nr, Kir }k(R,S), T );
        send_4(R,I, T, { Tr, I, Kir }Kbb, Nc, {R, Ni}Kir );
        read_5(I,R, { Nc }Kir );
        
        read_6(I,R, Mi,{ Tr, I, Kir }Kbb );
        send_7(R,I, Mr,{Mi,R}Kir );
        read_8(I,R, {I,Mr}Kir );

        claim_R1(R,Secret, Kir);
        claim_R2(R,Niagree);
        claim_R3(R,Nisynch);
        claim_R4(R,Empty, (Fresh,Kir));
    }

    role S
    {
        var Ni, Nr: Nonce;
        const Kir: SessionKey;

        read_2(R,S, Ni, I, Nr, R );
        send_3(S,R, { I, Nr, Kir }k(R,S), { Ni,R,Kir }k(I,S) );
    }
}


