Rati Gelashvili reported a rare but annoying bug in the hash function handling.

The fix requires a significant reworking of the function handling. This
is a first attempt.

Conflicts:
	src/knowledge.c
	src/knowledge.h

Regression test suggests that the Hashfunction fix works.
This commit is contained in:
Cas Cremers 2013-04-26 11:36:41 +02:00
parent 4a1898db92
commit 7658644295
27 changed files with 225 additions and 226 deletions

View File

@ -787,7 +787,7 @@ createDecryptionChain (const Binding b, const int run, const int index,
indentDepth++; indentDepth++;
tdecr = keylist->term; tdecr = keylist->term;
tkey = inverseKey (sys->know->inverses, TermKey (tdecr)); tkey = inverseKey (sys->know, TermKey (tdecr));
smallrun = create_decryptor (tdecr, tkey); smallrun = create_decryptor (tdecr, tkey);
{ {
Roledef rddecrypt; Roledef rddecrypt;

View File

@ -1101,7 +1101,7 @@ hashfunctions (Tac tcstart)
error error
("Bug in hashfunction generation code. Please contact the authors.\n"); ("Bug in hashfunction generation code. Please contact the authors.\n");
} }
knowledgeAddInverse (sys->know, hfuncs->term, hinvs->term); knowledgeAddInverseKeys (sys->know, hfuncs->term, hinvs->term);
hfuncs->term->stype = termlistAdd (NULL, TERM_Function); hfuncs->term->stype = termlistAdd (NULL, TERM_Function);
hinvs->term->stype = termlistAdd (NULL, TERM_Function); hinvs->term->stype = termlistAdd (NULL, TERM_Function);
hfuncs = hfuncs->next; hfuncs = hfuncs->next;
@ -1157,8 +1157,12 @@ normalDeclaration (Tac tc)
knowledgeAddTermlist (sys->know, tacTermlist (tc->t1.tac)); knowledgeAddTermlist (sys->know, tacTermlist (tc->t1.tac));
break; break;
case TAC_INVERSEKEYS: case TAC_INVERSEKEYS:
knowledgeAddInverse (sys->know, tacTerm (tc->t1.tac), knowledgeAddInverseKeys (sys->know, tacTerm (tc->t1.tac),
tacTerm (tc->t2.tac)); tacTerm (tc->t2.tac));
break;
case TAC_INVERSEKEYFUNCTIONS:
knowledgeAddInverseKeyFunctions (sys->know, tacTerm (tc->t1.tac),
tacTerm (tc->t2.tac));
break; break;
case TAC_HASHFUNCTION: case TAC_HASHFUNCTION:
hashfunctions (tc); hashfunctions (tc);
@ -1568,8 +1572,14 @@ tacProcess (Tac tc)
Term Term
tacTerm (Tac tc) tacTerm (Tac tc)
{ {
Term t;
switch (tc->op) switch (tc->op)
{ {
case TAC_FCALL:
t = makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac));
t->helper.fcall = true;
return t;
case TAC_ENCRYPT: case TAC_ENCRYPT:
return makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac)); return makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac));
case TAC_TUPLE: case TAC_TUPLE:

View File

@ -96,7 +96,7 @@ isIntruderChoice (const Term t)
{ {
// Chosen by intruder // Chosen by intruder
// However, if it is a rolename, this is not really what we mean // However, if it is a rolename, this is not really what we mean
if (!(t->roleVar || isAgentType (t->stype))) if (!(t->helper.roleVar || isAgentType (t->stype)))
{ {
// Not a role variable, and chosen by the intruder: that's it // Not a role variable, and chosen by the intruder: that's it
return true; return true;
@ -187,12 +187,12 @@ explainVariable (Term t)
if (realTermVariable (t)) if (realTermVariable (t))
{ {
eprintf ("any "); eprintf ("any ");
if (t->roleVar) if (t->helper.roleVar)
{ {
eprintf ("agent "); eprintf ("agent ");
} }
termPrintRemap (t); termPrintRemap (t);
if (!t->roleVar) if (!t->helper.roleVar)
{ {
if (switches.match == 0 && t->stype != NULL) if (switches.match == 0 && t->stype != NULL)
{ {

View File

@ -30,19 +30,10 @@
#include "system.h" #include "system.h"
#include "debug.h" #include "debug.h"
#include "error.h" #include "error.h"
#include "specialterm.h"
/* /*
* Knowledge stuff * Knowledge stuff
*
* Note that a really weird thing is going on involving unpropagated substitutions.
* Idea:
*
* 1. Substitute terms by filling in ->subst.
* Now, either:
* 2a. Undo this by knowledgeUndo.
* 2b. Propagate it, modifying the knowledge beyond repair by knowledgeSubstDo. Now inKnowledge works again.
* 2c. inKnowledge/knowledgeSet if something is in the knowledge: this does not consider the substitutions!, and
* they now have some overhead.
*/ */
//! Open knowledge code. //! Open knowledge code.
@ -81,7 +72,8 @@ emptyKnowledge ()
know = makeKnowledge (); know = makeKnowledge ();
know->basic = NULL; know->basic = NULL;
know->encrypt = NULL; know->encrypt = NULL;
know->inverses = NULL; know->inversekeys = NULL;
know->inversekeyfunctions = NULL;
know->vars = NULL; know->vars = NULL;
know->publicfunctions = NULL; know->publicfunctions = NULL;
return know; return know;
@ -110,7 +102,8 @@ knowledgeDuplicate (Knowledge know)
newknow->basic = termlistShallow (know->basic); newknow->basic = termlistShallow (know->basic);
newknow->encrypt = termlistShallow (know->encrypt); newknow->encrypt = termlistShallow (know->encrypt);
newknow->vars = termlistShallow (know->vars); newknow->vars = termlistShallow (know->vars);
newknow->inverses = know->inverses; newknow->inversekeys = know->inversekeys;
newknow->inversekeyfunctions = know->inversekeyfunctions;
newknow->publicfunctions = termlistShallow (know->publicfunctions); newknow->publicfunctions = termlistShallow (know->publicfunctions);
return newknow; return newknow;
} }
@ -147,7 +140,8 @@ knowledgeDestroy (Knowledge know)
termlistDestroy (know->basic); termlistDestroy (know->basic);
termlistDestroy (know->encrypt); termlistDestroy (know->encrypt);
termlistDestroy (know->vars); termlistDestroy (know->vars);
// termlistDestroy(know->inverses); // termlistDestroy(know->inversekeys);
// termlistDestroy(know->inversekeyfunctions);
termlistDestroy (know->publicfunctions); termlistDestroy (know->publicfunctions);
free (know); free (know);
} }
@ -195,7 +189,7 @@ knowledgeAddTerm (Knowledge know, Term term)
} }
if (term->type == ENCRYPT) if (term->type == ENCRYPT)
{ {
Term invkey = inverseKey (know->inverses, TermKey (term)); Term invkey = inverseKey (know, TermKey (term));
if (inKnowledge (know, invkey)) if (inKnowledge (know, invkey))
{ {
/* we can decrypt it */ /* we can decrypt it */
@ -227,7 +221,7 @@ knowledgeSimplify (Knowledge know, Term key)
{ {
Termlist tldecrypts = NULL; Termlist tldecrypts = NULL;
Termlist scan = know->encrypt; Termlist scan = know->encrypt;
Term invkey = inverseKey (know->inverses, key); Term invkey = inverseKey (know, key);
while (scan != NULL) while (scan != NULL)
{ {
@ -257,6 +251,7 @@ knowledgeAddTermlist (Knowledge know, Termlist tl)
while (tl != NULL) while (tl != NULL)
{ {
// Evil old fashioned code relies on lazy left-to-right parsing. Get rid of it.
flag = knowledgeAddTerm (know, tl->term) || flag; flag = knowledgeAddTerm (know, tl->term) || flag;
tl = tl->next; tl = tl->next;
} }
@ -265,21 +260,18 @@ knowledgeAddTermlist (Knowledge know, Termlist tl)
//! Add an inverse pair to the knowledge //! Add an inverse pair to the knowledge
void void
knowledgeAddInverse (Knowledge know, Term t1, Term t2) knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2)
{ {
know->inverses = termlistAdd (know->inverses, t1); know->inversekeys = termlistAdd (know->inversekeys, t1);
know->inverses = termlistAdd (know->inverses, t2); know->inversekeys = termlistAdd (know->inversekeys, t2);
return;
} }
//! Set an inverse pair list for the knowledge. //! Add an inverse pair to the knowledge
/**
* List pointer is simply copied, so don't delete it later!
*/
void void
knowledgeSetInverses (Knowledge know, Termlist tl) knowledgeAddInverseKeyFunctions (Knowledge know, Term t1, Term t2)
{ {
know->inverses = tl; know->inversekeyfunctions = termlistAdd (know->inversekeyfunctions, t1);
know->inversekeyfunctions = termlistAdd (know->inversekeyfunctions, t2);
} }
//! Is a term a part of the knowledge? //! Is a term a part of the knowledge?
@ -341,6 +333,15 @@ knowledgePrint (Knowledge know)
eprintf (" [Vars]: "); eprintf (" [Vars]: ");
termlistPrint (know->vars); termlistPrint (know->vars);
eprintf ("\n"); eprintf ("\n");
eprintf (" [Inversekeys]: ");
termlistPrint (know->inversekeys);
eprintf ("\n");
eprintf (" [Inversekeyfunctions]: ");
termlistPrint (know->inversekeyfunctions);
eprintf ("\n");
eprintf (" [Publicfunctions]: ");
termlistPrint (know->publicfunctions);
eprintf ("\n");
} }
//! Print a knowledge set, short version (no newline) //! Print a knowledge set, short version (no newline)
@ -368,43 +369,6 @@ knowledgePrintShort (const Knowledge know)
} }
} }
//! Print the inverses list of a knowledge set.
void
knowledgeInversesPrint (Knowledge know)
{
Termlist tl;
int after = 0;
if (know == NULL)
{
eprintf ("Empty knowledge.");
return;
}
tl = knowledgeGetInverses (know);
if (tl == NULL)
{
eprintf ("None.");
}
else
{
while (tl != NULL && tl->next != NULL)
{
if (after)
{
eprintf (",");
}
eprintf ("(");
termPrint (tl->term);
eprintf (",");
termPrint (tl->next->term);
eprintf (")");
after = 1;
tl = tl->next->next;
}
}
}
//! Yield the set of representatives for the knowledge. //! Yield the set of representatives for the knowledge.
/** /**
* Note: this is a shallow copy, and needs to be termlistDelete'd. * Note: this is a shallow copy, and needs to be termlistDelete'd.
@ -420,17 +384,11 @@ knowledgeSet (const Knowledge know)
return termlistConcat (tl1, tl2); return termlistConcat (tl1, tl2);
} }
//! Get the inverses pointer of the knowledge. //! Check for elements in the knowledge set
/** int
* Essentially the inverse function of knowledgeSetInverses() inKnowledgeSet (const Knowledge know, Term t)
*/
Termlist
knowledgeGetInverses (const Knowledge know)
{ {
if (know == NULL) return (inTermlist (know->basic, t) || inTermlist (know->encrypt, t));
return NULL;
else
return know->inverses;
} }
//! check whether any substitutions where made in a knowledge set. //! check whether any substitutions where made in a knowledge set.
@ -457,37 +415,6 @@ knowledgeSubstNeeded (const Knowledge know)
return 0; return 0;
} }
//! Reconstruct a knowledge set.
/**
* This is useful after e.g. substitutions.
* Just rebuilds the knowledge in a new (shallow) copy.
*@return The pointer to the new knowledge.
*\sa knowledgeSubstNeeded()
*/
Knowledge
knowledgeReconstruction (const Knowledge know)
{
Knowledge newknow = emptyKnowledge ();
newknow->inverses = know->inverses;
knowledgeAddTermlist (newknow, know->basic);
knowledgeAddTermlist (newknow, know->encrypt);
return newknow;
}
//! Propagate any substitutions just made.
/**
* This usually involves reconstruction of the complete knowledge, which is
* 'cheaper' than a thorough analysis, so we always make a copy.
*\sa knowledgeReconstruction()
*/
Knowledge
knowledgeSubstDo (const Knowledge know)
{
/* otherwise a copy (for deletion) is returned. */
return knowledgeReconstruction (know);
}
//! Add public function //! Add public function
void void
knowledgeAddPublicFunction (const Knowledge know, const Term f) knowledgeAddPublicFunction (const Knowledge know, const Term f)
@ -502,3 +429,62 @@ isKnowledgePublicFunction (const Knowledge know, const Term f)
{ {
return inTermlist (know->publicfunctions, f); return inTermlist (know->publicfunctions, f);
} }
//! Give the inverse key term of a term.
/**
* Gives a duplicate of the inverse Key of some term (which is used to encrypt something), as is defined
* by the termlist, which is a list of key1,key1inv, key2, key2inv, etc...
*@param inverses The list of inverses, typically from the knowledge.
*@param key Any term of which the inverse will be determined.
*@return A pointer to a duplicate of the inverse key term. Use termDelete to remove it.
*\sa termDuplicate(), knowledge::inverses
*/
Term
inverseKey (Knowledge know, Term key)
{
Term f;
key = deVar (key);
/* inverse key function? */
f = getTermFunction (key);
if (f != NULL)
{
Termlist tl;
Term funKey (Term orig, Term f)
{
/* in: f'{op}, f
* out: f{op'} */
return makeTermFcall (termDuplicate (TermOp (orig)),
termDuplicate (f));
}
tl = know->inversekeyfunctions;
while (tl != NULL && tl->next != NULL)
{
if (isTermEqual (TermKey (key), tl->term))
return funKey (key, tl->next->term);
if (isTermEqual (TermKey (key), tl->next->term))
return funKey (key, tl->term);
tl = tl->next->next;
}
}
else
{
/* scanning for a direct inverse */
Termlist tl;
/* scan the list */
tl = know->inversekeys;
while (tl != NULL && tl->next != NULL)
{
if (isTermEqual (key, tl->term))
return termDuplicate (tl->next->term);
if (isTermEqual (key, tl->next->term))
return termDuplicate (tl->term);
tl = tl->next->next;
}
}
return termDuplicate (key); /* defaults to symmetrical */
}

View File

@ -33,8 +33,10 @@ struct knowledge
Termlist basic; Termlist basic;
//! A list of terms encrypted, such that the inverse is not in the knowledge set. //! A list of terms encrypted, such that the inverse is not in the knowledge set.
Termlist encrypt; Termlist encrypt;
//! List of inverse pairs (thus length of list is even) //! List of inverse pairs (thus length of list is even) (add,sub)
Termlist inverses; Termlist inversekeys;
//! List of inverse pairs (thus length of list is even) (pk,sk)
Termlist inversekeyfunctions;
//! List of open variables in the knowledge set. //! List of open variables in the knowledge set.
/** /**
* This list is used to determine whether the knowledge needs to be rewritten. * This list is used to determine whether the knowledge needs to be rewritten.
@ -42,7 +44,7 @@ struct knowledge
* and we need to reconstruct the knowledge set. * and we need to reconstruct the knowledge set.
*/ */
Termlist vars; // special: denotes unsubstituted variables Termlist vars; // special: denotes unsubstituted variables
//! A list of public functions //! A list of hash functions
Termlist publicfunctions; Termlist publicfunctions;
}; };
@ -58,19 +60,19 @@ void knowledgeDelete (Knowledge know);
void knowledgeDestroy (Knowledge know); void knowledgeDestroy (Knowledge know);
int knowledgeAddTerm (Knowledge know, Term term); int knowledgeAddTerm (Knowledge know, Term term);
int knowledgeAddTermlist (Knowledge know, Termlist tl); int knowledgeAddTermlist (Knowledge know, Termlist tl);
void knowledgeAddInverse (Knowledge know, Term t1, Term t2); void knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2);
void knowledgeSetInverses (Knowledge know, Termlist tl); void knowledgeAddInverseKeyFunctions (Knowledge know, Term t1, Term t2);
int inKnowledgeSet (const Knowledge know, Term t);
void knowledgeSimplify (Knowledge know, Term decryptkey); void knowledgeSimplify (Knowledge know, Term decryptkey);
int inKnowledge (const Knowledge know, Term term); int inKnowledge (const Knowledge know, Term term);
void knowledgePrint (Knowledge know); void knowledgePrint (Knowledge know);
void knowledgePrintShort (const Knowledge know); void knowledgePrintShort (const Knowledge know);
void knowledgeInversesPrint (Knowledge know);
Termlist knowledgeSet (const Knowledge know); Termlist knowledgeSet (const Knowledge know);
Termlist knowledgeGetInverses (const Knowledge know);
int knowledgeSubstNeeded (const Knowledge know); int knowledgeSubstNeeded (const Knowledge know);
Knowledge knowledgeSubstDo (const Knowledge know); Knowledge knowledgeSubstDo (const Knowledge know);
void knowledgeAddPublicFunction (const Knowledge know, const Term f); void knowledgeAddPublicFunction (const Knowledge know, const Term f);
int isKnowledgePublicFunction (const Knowledge know, const Term f); int isKnowledgePublicFunction (const Knowledge know, const Term f);
Term inverseKey (Knowledge know, Term key);
//! Harnass macro for recursive procedures. //! Harnass macro for recursive procedures.
#define mindwipe(k,recurse) \ #define mindwipe(k,recurse) \

View File

@ -149,9 +149,6 @@ main (int argc, char **argv)
termlistPrint (sys->untrusted); termlistPrint (sys->untrusted);
printf ("\n"); printf ("\n");
knowledgePrint (sys->know); knowledgePrint (sys->know);
printf ("inverses: ");
knowledgeInversesPrint (sys->know);
printf ("\n");
locVarPrint (sys->locals); locVarPrint (sys->locals);
protocolsPrint (sys->protocols); protocolsPrint (sys->protocols);

View File

@ -82,6 +82,7 @@ List findMacroDefinition(Symbol s)
%token SECRET %token SECRET
%token COMPROMISED %token COMPROMISED
%token INVERSEKEYS %token INVERSEKEYS
%token INVERSEKEYFUNCTIONS
%token UNTRUSTED %token UNTRUSTED
%token USERTYPE %token USERTYPE
%token SINGULAR %token SINGULAR
@ -356,6 +357,12 @@ declaration : secretpref CONST basictermlist typeinfo1 ';'
t->t2.tac = $5; t->t2.tac = $5;
$$ = t; $$ = t;
} }
| INVERSEKEYFUNCTIONS '(' term ',' term ')' ';'
{ Tac t = tacCreate(TAC_INVERSEKEYFUNCTIONS);
t->t1.tac = $3;
t->t2.tac = $5;
$$ = t;
}
| COMPROMISED termlist ';' | COMPROMISED termlist ';'
{ Tac t = tacCreate(TAC_COMPROMISED); { Tac t = tacCreate(TAC_COMPROMISED);
t->t1.tac= $2; t->t1.tac= $2;
@ -456,7 +463,7 @@ term : ID '(' termlist ')'
{ {
Tac t = tacCreate(TAC_STRING); Tac t = tacCreate(TAC_STRING);
t->t1.sym = $1; t->t1.sym = $1;
$$ = tacJoin(TAC_ENCRYPT,tacTuple($3),t,NULL); $$ = tacJoin(TAC_FCALL,tacTuple($3),t,NULL);
} }
| '{' termlist '}' key | '{' termlist '}' key
{ {

View File

@ -1,2 +0,0 @@
Passed wall time in seconds:
0

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
14 15

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
23 24

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
28 29

View File

@ -1,6 +1,6 @@
claim spliceAS-HC,I Secret_7 N2 Ok [no attack within bounds] time=60 claim spliceAS-HC,I Secret_7 N2 Fail [at least 7 attacks]
claim spliceAS-HC,I Niagree_9 - Ok [does not occur] time=60 claim spliceAS-HC,I Niagree_9 - Fail [at least 1 attack]
claim spliceAS-HC,I Nisynch_10 - Ok [does not occur] time=60 claim spliceAS-HC,I Nisynch_10 - Fail [at least 1 attack]
claim spliceAS-HC,R Secret_8 N2 Ok [no attack within bounds] time=60 claim spliceAS-HC,R Secret_8 N2 Fail [at least 7 attacks]
claim spliceAS-HC,R Niagree_11 - Ok [does not occur] time=60 claim spliceAS-HC,R Niagree_11 - Fail [at least 1 attack]
claim spliceAS-HC,R Nisynch_12 - Ok [does not occur] time=60 claim spliceAS-HC,R Nisynch_12 - Fail [at least 1 attack]

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
60 6

View File

@ -1,6 +1,6 @@
claim spliceAS,I Secret_7 N2 Ok [no attack within bounds] time=60 claim spliceAS,I Secret_7 N2 Fail [at least 7 attacks]
claim spliceAS,I Niagree_9 - Ok [does not occur] time=60 claim spliceAS,I Niagree_9 - Fail [at least 1 attack]
claim spliceAS,I Nisynch_10 - Ok [does not occur] time=60 claim spliceAS,I Nisynch_10 - Fail [at least 1 attack]
claim spliceAS,R Secret_8 N2 Ok [no attack within bounds] time=60 claim spliceAS,R Secret_8 N2 Fail [at least 7 attacks]
claim spliceAS,R Niagree_11 - Ok [does not occur] time=60 claim spliceAS,R Niagree_11 - Fail [at least 1 attack]
claim spliceAS,R Nisynch_12 - Ok [does not occur] time=60 claim spliceAS,R Nisynch_12 - Fail [at least 1 attack]

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
60 6

View File

@ -1,2 +1,2 @@
Passed wall time in seconds: Passed wall time in seconds:
36 37

View File

@ -415,7 +415,7 @@ Readable (Knowledge know, Term t)
return true; return true;
} }
// Right disjunct // Right disjunct
inv = inverseKey (know->inverses, TermKey (t)); inv = inverseKey (know, TermKey (t));
either = false; either = false;
if (inKnowledge (know, inv)) if (inKnowledge (know, inv))
{ {

View File

@ -171,6 +171,7 @@ claim { return CLAIMT; }
run { return RUN; } run { return RUN; }
secret { return SECRET; } secret { return SECRET; }
inversekeys { return INVERSEKEYS; } inversekeys { return INVERSEKEYS; }
inversekeyfunctions { return INVERSEKEYFUNCTIONS; }
untrusted { return UNTRUSTED; } untrusted { return UNTRUSTED; }
compromised { return COMPROMISED; } compromised { return COMPROMISED; }
usertype { return USERTYPE; } usertype { return USERTYPE; }

View File

@ -119,7 +119,7 @@ specialTermInit (const System sys)
langcons (TERM_PK, "pk", TERM_Function); langcons (TERM_PK, "pk", TERM_Function);
langcons (TERM_SK, "sk", TERM_Function); langcons (TERM_SK, "sk", TERM_Function);
langcons (TERM_K, "k", TERM_Function); langcons (TERM_K, "k", TERM_Function);
knowledgeAddInverse (sys->know, TERM_PK, TERM_SK); knowledgeAddInverseKeyFunctions (sys->know, TERM_PK, TERM_SK);
knowledgeAddTerm (sys->know, TERM_PK); knowledgeAddTerm (sys->know, TERM_PK);
/* Define a prefix for labels for the match function */ /* Define a prefix for labels for the match function */

View File

@ -504,7 +504,7 @@ roleInstanceArachne (const System sys, const Protocol protocol,
newt = makeTermType (GLOBAL, TermSymb (oldt), rid); newt = makeTermType (GLOBAL, TermSymb (oldt), rid);
} }
newt->stype = oldt->stype; // copy list of types newt->stype = oldt->stype; // copy list of types
newt->roleVar = isrole; // set role status newt->helper.roleVar = isrole; // set role status
// Add to copy list // Add to copy list
TERMLISTADD (fromlist, oldt); TERMLISTADD (fromlist, oldt);

View File

@ -32,6 +32,7 @@ enum tactypes
TAC_SYM, TAC_SYM,
TAC_TUPLE, TAC_TUPLE,
TAC_ENCRYPT, TAC_ENCRYPT,
TAC_FCALL,
TAC_VAR, TAC_VAR,
TAC_CONST, TAC_CONST,
TAC_FRESH, TAC_FRESH,
@ -48,6 +49,7 @@ enum tactypes
TAC_ROLEREF, TAC_ROLEREF,
TAC_SECRET, TAC_SECRET,
TAC_INVERSEKEYS, TAC_INVERSEKEYS,
TAC_INVERSEKEYFUNCTIONS,
TAC_HASHFUNCTION, TAC_HASHFUNCTION,
TAC_UNTRUSTED, TAC_UNTRUSTED,
TAC_COMPROMISED, TAC_COMPROMISED,

View File

@ -84,6 +84,9 @@ makeTerm ()
//! Create a fresh encrypted term from two existing terms. //! Create a fresh encrypted term from two existing terms.
/** /**
* The first argument is the message,
* the second argument is the key.
*
*@return A pointer to the new term. *@return A pointer to the new term.
*/ */
Term Term
@ -92,11 +95,32 @@ makeTermEncrypt (Term t1, Term t2)
Term term = makeTerm (); Term term = makeTerm ();
term->type = ENCRYPT; term->type = ENCRYPT;
term->stype = NULL; term->stype = NULL;
term->helper.fcall = false;
term->subst = NULL;
TermOp (term) = t1; TermOp (term) = t1;
TermKey (term) = t2; TermKey (term) = t2;
return term; return term;
} }
Term
makeTermFcall (Term t1, Term t2)
//! Create a fresh function application term from two existing terms.
/**
* The first argument is the function argument,
* the second argument is the function (name).
*
* These behave like encryptions in most cases.
*
*@return A pointer to the new term.
*/
{
Term t;
t = makeTermEncrypt (t1, t2);
t->helper.fcall = true;
return t;
}
//! Create a fresh term tuple from two existing terms. //! Create a fresh term tuple from two existing terms.
/** /**
*@return A pointer to the new term. *@return A pointer to the new term.
@ -128,7 +152,8 @@ makeTermTuple (Term t1, Term t2)
tt = makeTerm (); tt = makeTerm ();
tt->type = TUPLE; tt->type = TUPLE;
tt->stype = NULL; tt->stype = NULL;
tt->roleVar = 0; tt->helper.roleVar = 0;
tt->subst = NULL;
TermOp1 (tt) = t1; TermOp1 (tt) = t1;
TermOp2 (tt) = t2; TermOp2 (tt) = t2;
return tt; return tt;
@ -145,7 +170,16 @@ makeTermType (const int type, const Symbol symb, const int runid)
Term term = makeTerm (); Term term = makeTerm ();
term->type = type; term->type = type;
term->stype = NULL; term->stype = NULL;
term->roleVar = 0; if ((type == ENCRYPT) || (type == TUPLE))
{
// Non-leaf
term->helper.fcall = false;
}
else
{
// Leaf
term->helper.roleVar = 0;
}
term->subst = NULL; term->subst = NULL;
TermSymb (term) = symb; TermSymb (term) = symb;
TermRunid (term) = runid; TermRunid (term) = runid;
@ -381,8 +415,7 @@ termPrintCustom (Term term, char *leftvar, char *rightvar, char *lefttup,
} }
if (realTermEncrypt (term)) if (realTermEncrypt (term))
{ {
if (isTermLeaf (TermKey (term)) if (term->helper.fcall)
&& inTermlist (TermKey (term)->stype, TERM_Function))
{ {
/* function application */ /* function application */
termPrintCustom (TermKey (term), leftvar, rightvar, lefttup, termPrintCustom (TermKey (term), leftvar, rightvar, lefttup,
@ -695,8 +728,12 @@ termRunid (Term term, int runid)
/* anything else, recurse */ /* anything else, recurse */
if (realTermEncrypt (term)) if (realTermEncrypt (term))
{ {
return makeTermEncrypt (termRunid (TermOp (term), runid), Term t;
termRunid (TermKey (term), runid));
t = makeTermEncrypt (termRunid (TermOp (term), runid),
termRunid (TermKey (term), runid));
t->helper.fcall = term->helper.fcall;
return t;
} }
else else
{ {
@ -1159,22 +1196,23 @@ term_encryption_level (const Term term)
} }
else else
{ {
int l, r;
if (realTermTuple (t)) if (realTermTuple (t))
{ {
int l, r;
l = iter_maxencrypt (TermOp1 (t)); l = iter_maxencrypt (TermOp1 (t));
r = iter_maxencrypt (TermOp2 (t)); r = iter_maxencrypt (TermOp2 (t));
if (l > r)
return l;
else
return r;
} }
else else
{ {
// encrypt // encrypt
return 1 + iter_maxencrypt (TermOp (t)); l = 1 + iter_maxencrypt (TermOp (t));
r = iter_maxencrypt (TermKey (t));
} }
if (l > r)
return l;
else
return r;
} }
} }
@ -1418,9 +1456,9 @@ Term
getTermFunction (Term t) getTermFunction (Term t)
{ {
t = deVar (t); t = deVar (t);
if (t != NULL) if (realTermEncrypt (t))
{ {
if (realTermEncrypt (t) && isTermFunctionName (TermKey (t))) if (t->helper.fcall)
{ {
return TermKey (t); return TermKey (t);
} }

View File

@ -47,7 +47,11 @@ struct term
//! Data Type termlist (e.g. agent or nonce) //! Data Type termlist (e.g. agent or nonce)
/** Only for leaves. */ /** Only for leaves. */
void *stype; // list of types void *stype; // list of types
int roleVar; //!< only for leaf, arachne engine: role variable flag union
{
int roleVar; //!< only for leaf, arachne engine: role variable flag
int fcall; //!< only for 'encryption' to mark actual function call f(t)
} helper;
//! Substitution term. //! Substitution term.
/** /**
@ -96,6 +100,7 @@ typedef struct term *Term;
void termsInit (void); void termsInit (void);
void termsDone (void); void termsDone (void);
Term makeTermEncrypt (Term t1, Term t2); Term makeTermEncrypt (Term t1, Term t2);
Term makeTermFcall (Term t1, Term t2);
Term makeTermTuple (Term t1, Term t2); Term makeTermTuple (Term t1, Term t2);
Term makeTermType (const int type, const Symbol symb, const int runid); Term makeTermType (const int type, const Symbol symb, const int runid);
__inline__ Term deVarScan (Term t); __inline__ Term deVarScan (Term t);

View File

@ -24,6 +24,7 @@
#include "debug.h" #include "debug.h"
#include "error.h" #include "error.h"
#include "switches.h" #include "switches.h"
#include "knowledge.h"
/* /*
* Shared stuff * Shared stuff
@ -618,68 +619,6 @@ termlistLength (Termlist tl)
return i; return i;
} }
//! Give the inverse key term of a term.
/**
* Gives a duplicate of the inverse Key of some term (which is used to encrypt something), as is defined
* by the termlist, which is a list of key1,key1inv, key2, key2inv, etc...
*@param inverses The list of inverses, typically from the knowledge.
*@param key Any term of which the inverse will be determined.
*@return A pointer to a duplicate of the inverse key term. Use termDelete to remove it.
*\sa termDuplicate(), knowledge::inverses
*/
Term
inverseKey (Termlist inverses, Term key)
{
key = deVar (key);
/* is this a function application? i.e. hash? */
if (isTermLeaf (key) && inTermlist (key->stype, TERM_Function))
{
/* functions cannot be inverted by default */
return termDuplicate (TERM_Hidden);
}
/* check for the special case first: when it is effectively a function application */
if (isTermEncrypt (key) && isTermLeaf (TermKey (key))
&& inTermlist (deVar (TermKey (key))->stype, TERM_Function))
{
/* we are scanning for functions */
/* scan the list */
/* key is function application kk(op), or {op}kk */
Term funKey (Term orig, Term newk)
{
/* in: {op}kk, nk
* out: {op'}nk */
return makeTermEncrypt (termDuplicate (TermOp (orig)),
termDuplicate (newk));
}
while (inverses != NULL && inverses->next != NULL)
{
if (isTermEqual (TermKey (key), inverses->term))
return funKey (key, inverses->next->term);
if (isTermEqual (TermKey (key), inverses->next->term))
return funKey (key, inverses->term);
inverses = inverses->next->next;
}
}
else
{
/* scanning for a direct inverse */
/* scan the list */
while (inverses != NULL && inverses->next != NULL)
{
if (isTermEqual (key, inverses->term))
return termDuplicate (inverses->next->term);
if (isTermEqual (key, inverses->next->term))
return termDuplicate (inverses->term);
inverses = inverses->next->next;
}
}
return termDuplicate (key); /* defaults to symmetrical */
}
//! Create a term local to a run. //! Create a term local to a run.
/* /*
* We assume that at this point, no variables have been instantiated yet that occur in this term. * We assume that at this point, no variables have been instantiated yet that occur in this term.

View File

@ -66,7 +66,6 @@ Termlist termlistAddBasic (Termlist tl, Term t);
Termlist termlistAddBasics (Termlist tl, Termlist scan); Termlist termlistAddBasics (Termlist tl, Termlist scan);
Termlist termlistMinusTerm (Termlist tl, Term t); Termlist termlistMinusTerm (Termlist tl, Term t);
int termlistLength (Termlist tl); int termlistLength (Termlist tl);
Term inverseKey (Termlist inverses, Term key);
Term termLocal (const Term t, Termlist fromlist, Termlist tolist); Term termLocal (const Term t, Termlist fromlist, Termlist tolist);
Termlist termlistLocal (Termlist tl, const Termlist fromlist, Termlist termlistLocal (Termlist tl, const Termlist fromlist,
const Termlist tolist); const Termlist tolist);

View File

@ -438,7 +438,7 @@ xmlInverses (const System sys)
xmlPrint ("<inversekeys>"); xmlPrint ("<inversekeys>");
xmlindent++; xmlindent++;
invlist = sys->know->inverses; invlist = sys->know->inversekeys;
while (invlist != NULL && invlist->next != NULL) while (invlist != NULL && invlist->next != NULL)
{ {
xmlPrint ("<keypair>"); xmlPrint ("<keypair>");
@ -452,6 +452,23 @@ xmlInverses (const System sys)
} }
xmlindent--; xmlindent--;
xmlPrint ("</inversekeys>"); xmlPrint ("</inversekeys>");
xmlPrint ("<inversekeyfunctions>");
xmlindent++;
invlist = sys->know->inversekeyfunctions;
while (invlist != NULL && invlist->next != NULL)
{
xmlPrint ("<keypair>");
xmlindent++;
xmlOutTerm (NULL, invlist->term);
xmlOutTerm (NULL, invlist->next->term);
xmlindent--;
xmlPrint ("</keypair>");
invlist = invlist->next->next;
}
xmlindent--;
xmlPrint ("</inversekeyfunctions>");
} }
//! Show initial knowledge //! Show initial knowledge