- Much work for the skeleton of the Hidelevel lemma.
This commit is contained in:
parent
bb7259a1ad
commit
5d2d836d07
@ -1,5 +1,6 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <limits.h>
|
||||||
#include "tac.h"
|
#include "tac.h"
|
||||||
#include "term.h"
|
#include "term.h"
|
||||||
#include "termlist.h"
|
#include "termlist.h"
|
||||||
@ -12,6 +13,7 @@
|
|||||||
#include "compiler.h"
|
#include "compiler.h"
|
||||||
#include "switches.h"
|
#include "switches.h"
|
||||||
#include "specialterm.h"
|
#include "specialterm.h"
|
||||||
|
#include "hidelevel.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Simple sys pointer as a global. Yields cleaner code although it's against programming standards.
|
Simple sys pointer as a global. Yields cleaner code although it's against programming standards.
|
||||||
@ -372,6 +374,10 @@ levelTacDeclaration (Tac tc, int isVar)
|
|||||||
termlistAdd (thisRole->declaredconsts, t);
|
termlistAdd (thisRole->declaredconsts, t);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (level == 0)
|
||||||
|
{
|
||||||
|
sys->globalconstants = termlistAdd (sys->globalconstants, t);
|
||||||
|
}
|
||||||
tscan = tscan->next;
|
tscan = tscan->next;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1790,4 +1796,8 @@ preprocess (const System sys)
|
|||||||
* check for ununsed variables
|
* check for ununsed variables
|
||||||
*/
|
*/
|
||||||
checkUnusedVariables (sys);
|
checkUnusedVariables (sys);
|
||||||
|
/*
|
||||||
|
* compute hidelevels
|
||||||
|
*/
|
||||||
|
hidelevelCompute (sys);
|
||||||
}
|
}
|
||||||
|
180
src/hidelevel.c
Normal file
180
src/hidelevel.c
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
/** @file hidelevel.c \brief Hidelevel lemma base functions.
|
||||||
|
*
|
||||||
|
* The Hidelevel lemma is fairly complex and so it requires some buffering,
|
||||||
|
* instead of fully recomputing the required data each time again.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <limits.h>
|
||||||
|
#include "hidelevel.h"
|
||||||
|
#include "system.h"
|
||||||
|
#include "memory.h"
|
||||||
|
|
||||||
|
//! hide level within protocol
|
||||||
|
unsigned int
|
||||||
|
protocolHidelevel (const System sys, const Term t)
|
||||||
|
{
|
||||||
|
unsigned int minlevel;
|
||||||
|
|
||||||
|
minlevel = INT_MAX;
|
||||||
|
|
||||||
|
int itsends (const System sys, const Protocol p, const Role r)
|
||||||
|
{
|
||||||
|
int sends(Roledef rd)
|
||||||
|
{
|
||||||
|
if (rd->type == SEND)
|
||||||
|
{
|
||||||
|
unsigned int l;
|
||||||
|
|
||||||
|
l = termHidelevel (t, rd->from);
|
||||||
|
if (l < minlevel) minlevel = l;
|
||||||
|
l = termHidelevel (t, rd->to);
|
||||||
|
if (l < minlevel) minlevel = l;
|
||||||
|
l = termHidelevel (t, rd->message);
|
||||||
|
if (l < minlevel) minlevel = l;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
roledef_iterate_events (r->roledef, sends);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
system_iterate_roles (sys, itsends);
|
||||||
|
|
||||||
|
return minlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! hide level within initial knowledge
|
||||||
|
unsigned int
|
||||||
|
knowledgeHidelevel (const System sys, const Term t)
|
||||||
|
{
|
||||||
|
unsigned int minlevel;
|
||||||
|
Termlist tl;
|
||||||
|
|
||||||
|
minlevel = INT_MAX;
|
||||||
|
tl = knowledgeSet (sys->know);
|
||||||
|
while (tl != NULL)
|
||||||
|
{
|
||||||
|
unsigned int l;
|
||||||
|
|
||||||
|
l = termHidelevel (t, tl->term);
|
||||||
|
if (l < minlevel)
|
||||||
|
{
|
||||||
|
minlevel = l;
|
||||||
|
}
|
||||||
|
tl = tl->next;
|
||||||
|
}
|
||||||
|
termlistDelete (tl);
|
||||||
|
|
||||||
|
return minlevel;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Check hide levels
|
||||||
|
void
|
||||||
|
hidelevelCompute (const System sys)
|
||||||
|
{
|
||||||
|
Termlist tl;
|
||||||
|
|
||||||
|
sys->hidden = NULL;
|
||||||
|
tl = sys->globalconstants;
|
||||||
|
eprintf ("Global constants: ");
|
||||||
|
termlistPrint (tl);
|
||||||
|
eprintf ("\n");
|
||||||
|
|
||||||
|
while (tl != NULL)
|
||||||
|
{
|
||||||
|
unsigned int l1,l2,l;
|
||||||
|
|
||||||
|
l1 = knowledgeHidelevel (sys, tl->term);
|
||||||
|
l2 = protocolHidelevel (sys, tl->term);
|
||||||
|
if (l1 < l2)
|
||||||
|
{
|
||||||
|
l = l1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
l = l2;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interesting only if higher than zero
|
||||||
|
if (l > 0)
|
||||||
|
{
|
||||||
|
Hiddenterm ht;
|
||||||
|
|
||||||
|
ht = (Hiddenterm) memAlloc (sizeof (struct hiddenterm));
|
||||||
|
ht->term = tl->term;
|
||||||
|
ht->hideminimum = l;
|
||||||
|
ht->hideprotocol = l2;
|
||||||
|
ht->hideknowledge = l1;
|
||||||
|
ht->next = sys->hidden;
|
||||||
|
sys->hidden = ht;
|
||||||
|
|
||||||
|
#ifdef DEBUG
|
||||||
|
eprintf ("Added possibly interesting term: ");
|
||||||
|
termPrint (tl->term);
|
||||||
|
eprintf ("; know %i, prot %i\n", l1,l2);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
tl = tl->next;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//! Given a term, iterate over all factors
|
||||||
|
int iterate_interesting (const System sys, const Term goalterm, int (*func) ())
|
||||||
|
{
|
||||||
|
Hiddenterm ht;
|
||||||
|
|
||||||
|
ht = sys->hidden;
|
||||||
|
while (ht != NULL)
|
||||||
|
{
|
||||||
|
unsigned int l;
|
||||||
|
// Test the goalterm for occurrences of this
|
||||||
|
|
||||||
|
l = termHidelevel (ht->term, goalterm);
|
||||||
|
if (l < INT_MAX)
|
||||||
|
{
|
||||||
|
if (!func (l, ht->hideminimum, ht->hideprotocol, ht->hideknowledge))
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ht = ht->next;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Determine whether a goal might be interesting from the viewpoint of hide levels (the highest minimum is best)
|
||||||
|
int hidelevelInteresting (const System sys, const Term goalterm)
|
||||||
|
{
|
||||||
|
int uninteresting (unsigned int l, unsigned int lmin, unsigned int lprot, unsigned int lknow)
|
||||||
|
{
|
||||||
|
if (lmin > 0)
|
||||||
|
{
|
||||||
|
// anything higher than usual is interesting :)
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !iterate_interesting (sys, goalterm, uninteresting);
|
||||||
|
}
|
||||||
|
|
||||||
|
//! Determine whether a goal is impossible to satisfy because of the hidelevel lemma.
|
||||||
|
int hidelevelImpossible (const System sys, const Term goalterm)
|
||||||
|
{
|
||||||
|
int possible (unsigned int l, unsigned int lmin, unsigned int lprot, unsigned int lknow)
|
||||||
|
{
|
||||||
|
if (l < lmin)
|
||||||
|
{
|
||||||
|
// impossible, abort!
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return !iterate_interesting (sys, goalterm, possible);
|
||||||
|
}
|
||||||
|
|
16
src/hidelevel.h
Normal file
16
src/hidelevel.h
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
#ifndef HIDELEVELS
|
||||||
|
#define HIDELEVELS
|
||||||
|
|
||||||
|
#include "term.h"
|
||||||
|
#include "system.h"
|
||||||
|
|
||||||
|
/*
|
||||||
|
* The structure hiddenterm/Hiddenterm is defined in system.h
|
||||||
|
*/
|
||||||
|
|
||||||
|
void hidelevelCompute (const System sys);
|
||||||
|
int hidelevelInteresting (const System sys, const Term goalterm);
|
||||||
|
int hidelevelImpossible (const System sys, const Term goalterm);
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
31
src/hidelevel.txt
Normal file
31
src/hidelevel.txt
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
Implemented:
|
||||||
|
|
||||||
|
- scans
|
||||||
|
- test functions (in hidelevel.c)
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
|
||||||
|
- use test functions (impossible for pruning, interesting for goal selection heuristic)
|
||||||
|
- state count display switch for comparisons
|
||||||
|
- consider adding info for goal stuff (only from M_0, not by create)
|
||||||
|
|
||||||
|
*******************************************************************
|
||||||
|
|
||||||
|
roivas:~scyther% ./scyther ccitt509-1c.spdl
|
||||||
|
Global constants: [te, ne, Eve, Bob, Alice, unhash, sk, hash, pk]
|
||||||
|
|
||||||
|
Possibly interesting term: unhash; know 2147483647, prot 2147483647
|
||||||
|
Possibly interesting term: sk; know 1, prot 2
|
||||||
|
|
||||||
|
|
||||||
|
roivas:~scyther% ./scyther yahalom.spdl
|
||||||
|
warning: variable T was declared in role yahalom,R but never used in a read event.
|
||||||
|
Global constants: [Simon, Bob, Alice, Compromised, Fresh, k]
|
||||||
|
|
||||||
|
Possibly interesting term: k; know 2147483647, prot 2
|
||||||
|
|
||||||
|
|
||||||
|
roivas:~scyther% ./scyther ns3.spdl
|
||||||
|
Global constants: [Eve, sk, pk]
|
||||||
|
|
||||||
|
Possibly interesting term: sk; know 1, prot 2147483647
|
@ -67,6 +67,8 @@ systemInit ()
|
|||||||
sys->locals = NULL;
|
sys->locals = NULL;
|
||||||
sys->variables = NULL;
|
sys->variables = NULL;
|
||||||
sys->untrusted = NULL;
|
sys->untrusted = NULL;
|
||||||
|
sys->globalconstants = NULL;
|
||||||
|
sys->hidden = NULL;
|
||||||
sys->secrets = NULL; // list of claimed secrets
|
sys->secrets = NULL; // list of claimed secrets
|
||||||
sys->synchronising_labels = NULL;
|
sys->synchronising_labels = NULL;
|
||||||
sys->attack = NULL; // clash with prev. attack declaration TODO
|
sys->attack = NULL; // clash with prev. attack declaration TODO
|
||||||
|
16
src/system.h
16
src/system.h
@ -100,6 +100,19 @@ struct tracebuf
|
|||||||
Varbuf variables;
|
Varbuf variables;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
//! Structure for information on special terms (cacheing)
|
||||||
|
struct hiddenterm
|
||||||
|
{
|
||||||
|
Term term;
|
||||||
|
unsigned int hideminimum;
|
||||||
|
unsigned int hideprotocol;
|
||||||
|
unsigned int hideknowledge;
|
||||||
|
struct hiddenterm *next;
|
||||||
|
};
|
||||||
|
|
||||||
|
//! Pointer shorthand
|
||||||
|
typedef struct hiddenterm *Hiddenterm;
|
||||||
|
|
||||||
//! The main state structure.
|
//! The main state structure.
|
||||||
struct system
|
struct system
|
||||||
{
|
{
|
||||||
@ -136,6 +149,8 @@ struct system
|
|||||||
Termlist locals; //!< List of local terms
|
Termlist locals; //!< List of local terms
|
||||||
Termlist variables; //!< List of all variables
|
Termlist variables; //!< List of all variables
|
||||||
Termlist untrusted; //!< List of untrusted agent names
|
Termlist untrusted; //!< List of untrusted agent names
|
||||||
|
Termlist globalconstants; //!< List of global constants
|
||||||
|
Hiddenterm hidden; //!< List of hiddenterm constructs for Hidelevel lemma
|
||||||
|
|
||||||
/* protocol preprocessing */
|
/* protocol preprocessing */
|
||||||
int rolecount; //!< Number of roles in the system
|
int rolecount; //!< Number of roles in the system
|
||||||
@ -166,6 +181,7 @@ struct system
|
|||||||
|
|
||||||
typedef struct system *System;
|
typedef struct system *System;
|
||||||
|
|
||||||
|
|
||||||
System systemInit ();
|
System systemInit ();
|
||||||
void systemReset (const System sys);
|
void systemReset (const System sys);
|
||||||
void systemRuns (const System sys);
|
void systemRuns (const System sys);
|
||||||
|
49
src/term.c
49
src/term.c
@ -1378,3 +1378,52 @@ getTermFunction (Term t)
|
|||||||
}
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//! Return hidelevel for a single term within another
|
||||||
|
unsigned int
|
||||||
|
termHidelevel (const Term tsmall, Term tbig)
|
||||||
|
{
|
||||||
|
tbig = deVar (tbig);
|
||||||
|
if (isTermEqual (tsmall, tbig))
|
||||||
|
{
|
||||||
|
// It's simply here: not hidden at any level
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (realTermLeaf (tbig))
|
||||||
|
{
|
||||||
|
// Not here: infinitely hidden
|
||||||
|
return INT_MAX;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Nested term
|
||||||
|
unsigned int t1, t2;
|
||||||
|
|
||||||
|
if (realTermTuple (tbig))
|
||||||
|
{
|
||||||
|
// Tupling
|
||||||
|
t1 = termHidelevel (tsmall, TermOp1 (tbig));
|
||||||
|
t2 = termHidelevel (tsmall, TermOp2 (tbig));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Encryption
|
||||||
|
t1 = termHidelevel (tsmall, TermOp (tbig));
|
||||||
|
t2 = termHidelevel (tsmall, TermKey (tbig));
|
||||||
|
if (t2 < INT_MAX)
|
||||||
|
t2++;
|
||||||
|
}
|
||||||
|
// Return minimum
|
||||||
|
if (t1 < t2)
|
||||||
|
{
|
||||||
|
return t1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return t2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -201,6 +201,7 @@ int isLeafNameEqual (Term t1, Term t2);
|
|||||||
Term freshTermPrefix (Term prefixterm);
|
Term freshTermPrefix (Term prefixterm);
|
||||||
int isTermFunctionName (Term t);
|
int isTermFunctionName (Term t);
|
||||||
Term getTermFunction (Term t);
|
Term getTermFunction (Term t);
|
||||||
|
unsigned int termHidelevel (const Term tsmall, Term tbig);
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user