diff --git a/src/arachne.c b/src/arachne.c index 35d0bcc..d6bca88 100644 --- a/src/arachne.c +++ b/src/arachne.c @@ -787,7 +787,7 @@ createDecryptionChain (const Binding b, const int run, const int index, indentDepth++; tdecr = keylist->term; - tkey = inverseKey (sys->know->inverses, TermKey (tdecr)); + tkey = inverseKey (sys->know, TermKey (tdecr)); smallrun = create_decryptor (tdecr, tkey); { Roledef rddecrypt; diff --git a/src/compiler.c b/src/compiler.c index cd8a726..d6c2a4c 100644 --- a/src/compiler.c +++ b/src/compiler.c @@ -1101,7 +1101,7 @@ hashfunctions (Tac tcstart) error ("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); hinvs->term->stype = termlistAdd (NULL, TERM_Function); hfuncs = hfuncs->next; @@ -1157,8 +1157,12 @@ normalDeclaration (Tac tc) knowledgeAddTermlist (sys->know, tacTermlist (tc->t1.tac)); break; case TAC_INVERSEKEYS: - knowledgeAddInverse (sys->know, tacTerm (tc->t1.tac), - tacTerm (tc->t2.tac)); + knowledgeAddInverseKeys (sys->know, tacTerm (tc->t1.tac), + tacTerm (tc->t2.tac)); + break; + case TAC_INVERSEKEYFUNCTIONS: + knowledgeAddInverseKeyFunctions (sys->know, tacTerm (tc->t1.tac), + tacTerm (tc->t2.tac)); break; case TAC_HASHFUNCTION: hashfunctions (tc); @@ -1568,8 +1572,14 @@ tacProcess (Tac tc) Term tacTerm (Tac tc) { + Term t; + 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: return makeTermEncrypt (tacTerm (tc->t1.tac), tacTerm (tc->t2.tac)); case TAC_TUPLE: diff --git a/src/dotout.c b/src/dotout.c index 555680c..e380fab 100644 --- a/src/dotout.c +++ b/src/dotout.c @@ -96,7 +96,7 @@ isIntruderChoice (const Term t) { // Chosen by intruder // 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 return true; @@ -187,12 +187,12 @@ explainVariable (Term t) if (realTermVariable (t)) { eprintf ("any "); - if (t->roleVar) + if (t->helper.roleVar) { eprintf ("agent "); } termPrintRemap (t); - if (!t->roleVar) + if (!t->helper.roleVar) { if (switches.match == 0 && t->stype != NULL) { diff --git a/src/knowledge.c b/src/knowledge.c index 2c2202a..51a0adb 100644 --- a/src/knowledge.c +++ b/src/knowledge.c @@ -30,19 +30,10 @@ #include "system.h" #include "debug.h" #include "error.h" +#include "specialterm.h" /* * 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. @@ -81,7 +72,8 @@ emptyKnowledge () know = makeKnowledge (); know->basic = NULL; know->encrypt = NULL; - know->inverses = NULL; + know->inversekeys = NULL; + know->inversekeyfunctions = NULL; know->vars = NULL; know->publicfunctions = NULL; return know; @@ -110,7 +102,8 @@ knowledgeDuplicate (Knowledge know) newknow->basic = termlistShallow (know->basic); newknow->encrypt = termlistShallow (know->encrypt); newknow->vars = termlistShallow (know->vars); - newknow->inverses = know->inverses; + newknow->inversekeys = know->inversekeys; + newknow->inversekeyfunctions = know->inversekeyfunctions; newknow->publicfunctions = termlistShallow (know->publicfunctions); return newknow; } @@ -147,7 +140,8 @@ knowledgeDestroy (Knowledge know) termlistDestroy (know->basic); termlistDestroy (know->encrypt); termlistDestroy (know->vars); - // termlistDestroy(know->inverses); + // termlistDestroy(know->inversekeys); + // termlistDestroy(know->inversekeyfunctions); termlistDestroy (know->publicfunctions); free (know); } @@ -195,7 +189,7 @@ knowledgeAddTerm (Knowledge know, Term term) } if (term->type == ENCRYPT) { - Term invkey = inverseKey (know->inverses, TermKey (term)); + Term invkey = inverseKey (know, TermKey (term)); if (inKnowledge (know, invkey)) { /* we can decrypt it */ @@ -227,7 +221,7 @@ knowledgeSimplify (Knowledge know, Term key) { Termlist tldecrypts = NULL; Termlist scan = know->encrypt; - Term invkey = inverseKey (know->inverses, key); + Term invkey = inverseKey (know, key); while (scan != NULL) { @@ -257,6 +251,7 @@ knowledgeAddTermlist (Knowledge know, Termlist tl) while (tl != NULL) { + // Evil old fashioned code relies on lazy left-to-right parsing. Get rid of it. flag = knowledgeAddTerm (know, tl->term) || flag; tl = tl->next; } @@ -265,21 +260,18 @@ knowledgeAddTermlist (Knowledge know, Termlist tl) //! Add an inverse pair to the knowledge void -knowledgeAddInverse (Knowledge know, Term t1, Term t2) +knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2) { - know->inverses = termlistAdd (know->inverses, t1); - know->inverses = termlistAdd (know->inverses, t2); - return; + know->inversekeys = termlistAdd (know->inversekeys, t1); + know->inversekeys = termlistAdd (know->inversekeys, t2); } -//! Set an inverse pair list for the knowledge. -/** - * List pointer is simply copied, so don't delete it later! - */ +//! Add an inverse pair to the knowledge 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? @@ -341,6 +333,15 @@ knowledgePrint (Knowledge know) eprintf (" [Vars]: "); termlistPrint (know->vars); 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) @@ -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. /** * Note: this is a shallow copy, and needs to be termlistDelete'd. @@ -420,17 +384,11 @@ knowledgeSet (const Knowledge know) return termlistConcat (tl1, tl2); } -//! Get the inverses pointer of the knowledge. -/** - * Essentially the inverse function of knowledgeSetInverses() - */ -Termlist -knowledgeGetInverses (const Knowledge know) +//! Check for elements in the knowledge set +int +inKnowledgeSet (const Knowledge know, Term t) { - if (know == NULL) - return NULL; - else - return know->inverses; + return (inTermlist (know->basic, t) || inTermlist (know->encrypt, t)); } //! check whether any substitutions where made in a knowledge set. @@ -457,37 +415,6 @@ knowledgeSubstNeeded (const Knowledge know) 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 void knowledgeAddPublicFunction (const Knowledge know, const Term f) @@ -502,3 +429,62 @@ isKnowledgePublicFunction (const Knowledge know, const Term 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 */ +} diff --git a/src/knowledge.h b/src/knowledge.h index 18d15d1..d9fa009 100644 --- a/src/knowledge.h +++ b/src/knowledge.h @@ -33,8 +33,10 @@ struct knowledge Termlist basic; //! A list of terms encrypted, such that the inverse is not in the knowledge set. Termlist encrypt; - //! List of inverse pairs (thus length of list is even) - Termlist inverses; + //! List of inverse pairs (thus length of list is even) (add,sub) + Termlist inversekeys; + //! List of inverse pairs (thus length of list is even) (pk,sk) + Termlist inversekeyfunctions; //! List of open variables in the knowledge set. /** * 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. */ Termlist vars; // special: denotes unsubstituted variables - //! A list of public functions + //! A list of hash functions Termlist publicfunctions; }; @@ -58,19 +60,19 @@ void knowledgeDelete (Knowledge know); void knowledgeDestroy (Knowledge know); int knowledgeAddTerm (Knowledge know, Term term); int knowledgeAddTermlist (Knowledge know, Termlist tl); -void knowledgeAddInverse (Knowledge know, Term t1, Term t2); -void knowledgeSetInverses (Knowledge know, Termlist tl); +void knowledgeAddInverseKeys (Knowledge know, Term t1, Term t2); +void knowledgeAddInverseKeyFunctions (Knowledge know, Term t1, Term t2); +int inKnowledgeSet (const Knowledge know, Term t); void knowledgeSimplify (Knowledge know, Term decryptkey); int inKnowledge (const Knowledge know, Term term); void knowledgePrint (Knowledge know); void knowledgePrintShort (const Knowledge know); -void knowledgeInversesPrint (Knowledge know); Termlist knowledgeSet (const Knowledge know); -Termlist knowledgeGetInverses (const Knowledge know); int knowledgeSubstNeeded (const Knowledge know); Knowledge knowledgeSubstDo (const Knowledge know); void knowledgeAddPublicFunction (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. #define mindwipe(k,recurse) \ diff --git a/src/main.c b/src/main.c index 8efbdd5..94b48f9 100644 --- a/src/main.c +++ b/src/main.c @@ -149,9 +149,6 @@ main (int argc, char **argv) termlistPrint (sys->untrusted); printf ("\n"); knowledgePrint (sys->know); - printf ("inverses: "); - knowledgeInversesPrint (sys->know); - printf ("\n"); locVarPrint (sys->locals); protocolsPrint (sys->protocols); diff --git a/src/parser.y b/src/parser.y index ad01666..4d8c01d 100644 --- a/src/parser.y +++ b/src/parser.y @@ -82,6 +82,7 @@ List findMacroDefinition(Symbol s) %token SECRET %token COMPROMISED %token INVERSEKEYS +%token INVERSEKEYFUNCTIONS %token UNTRUSTED %token USERTYPE %token SINGULAR @@ -356,6 +357,12 @@ declaration : secretpref CONST basictermlist typeinfo1 ';' t->t2.tac = $5; $$ = t; } + | INVERSEKEYFUNCTIONS '(' term ',' term ')' ';' + { Tac t = tacCreate(TAC_INVERSEKEYFUNCTIONS); + t->t1.tac = $3; + t->t2.tac = $5; + $$ = t; + } | COMPROMISED termlist ';' { Tac t = tacCreate(TAC_COMPROMISED); t->t1.tac= $2; @@ -456,7 +463,7 @@ term : ID '(' termlist ')' { Tac t = tacCreate(TAC_STRING); t->t1.sym = $1; - $$ = tacJoin(TAC_ENCRYPT,tacTuple($3),t,NULL); + $$ = tacJoin(TAC_FCALL,tacTuple($3),t,NULL); } | '{' termlist '}' key { diff --git a/src/regression-tests/results/test-gui-Protocols-ISO-9798-sasl.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-ISO-9798-sasl.spdl --timer=60 --plain.time deleted file mode 100644 index 80f32ca..0000000 --- a/src/regression-tests/results/test-gui-Protocols-ISO-9798-sasl.spdl --timer=60 --plain.time +++ /dev/null @@ -1,2 +0,0 @@ -Passed wall time in seconds: -0 diff --git a/src/regression-tests/results/test-gui-Protocols-andrew.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-andrew.spdl --timer=60 --plain.time index 97d01d7..afe3b53 100644 --- a/src/regression-tests/results/test-gui-Protocols-andrew.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-andrew.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -14 +15 diff --git a/src/regression-tests/results/test-gui-Protocols-needham-schroeder-lowe.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-needham-schroeder-lowe.spdl --timer=60 --plain.time index 37da462..0541820 100644 --- a/src/regression-tests/results/test-gui-Protocols-needham-schroeder-lowe.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-needham-schroeder-lowe.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -23 +24 diff --git a/src/regression-tests/results/test-gui-Protocols-needham-schroeder.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-needham-schroeder.spdl --timer=60 --plain.time index 27fb100..d1a00da 100644 --- a/src/regression-tests/results/test-gui-Protocols-needham-schroeder.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-needham-schroeder.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -28 +29 diff --git a/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.out b/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.out index cdd6305..20b5520 100644 --- a/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.out +++ b/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.out @@ -1,6 +1,6 @@ -claim spliceAS-HC,I Secret_7 N2 Ok [no attack within bounds] time=60 -claim spliceAS-HC,I Niagree_9 - Ok [does not occur] time=60 -claim spliceAS-HC,I Nisynch_10 - Ok [does not occur] time=60 -claim spliceAS-HC,R Secret_8 N2 Ok [no attack within bounds] time=60 -claim spliceAS-HC,R Niagree_11 - Ok [does not occur] time=60 -claim spliceAS-HC,R Nisynch_12 - Ok [does not occur] time=60 +claim spliceAS-HC,I Secret_7 N2 Fail [at least 7 attacks] +claim spliceAS-HC,I Niagree_9 - Fail [at least 1 attack] +claim spliceAS-HC,I Nisynch_10 - Fail [at least 1 attack] +claim spliceAS-HC,R Secret_8 N2 Fail [at least 7 attacks] +claim spliceAS-HC,R Niagree_11 - Fail [at least 1 attack] +claim spliceAS-HC,R Nisynch_12 - Fail [at least 1 attack] diff --git a/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.time index df21598..2eb5ce9 100644 --- a/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-splice-as-hc.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -60 +6 diff --git a/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.out b/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.out index a8474fb..a91f153 100644 --- a/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.out +++ b/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.out @@ -1,6 +1,6 @@ -claim spliceAS,I Secret_7 N2 Ok [no attack within bounds] time=60 -claim spliceAS,I Niagree_9 - Ok [does not occur] time=60 -claim spliceAS,I Nisynch_10 - Ok [does not occur] time=60 -claim spliceAS,R Secret_8 N2 Ok [no attack within bounds] time=60 -claim spliceAS,R Niagree_11 - Ok [does not occur] time=60 -claim spliceAS,R Nisynch_12 - Ok [does not occur] time=60 +claim spliceAS,I Secret_7 N2 Fail [at least 7 attacks] +claim spliceAS,I Niagree_9 - Fail [at least 1 attack] +claim spliceAS,I Nisynch_10 - Fail [at least 1 attack] +claim spliceAS,R Secret_8 N2 Fail [at least 7 attacks] +claim spliceAS,R Niagree_11 - Fail [at least 1 attack] +claim spliceAS,R Nisynch_12 - Fail [at least 1 attack] diff --git a/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.time index df21598..2eb5ce9 100644 --- a/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-splice-as.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -60 +6 diff --git a/src/regression-tests/results/test-gui-Protocols-woo-lam.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-woo-lam.spdl --timer=60 --plain.time index b449a72..7ec870e 100644 --- a/src/regression-tests/results/test-gui-Protocols-woo-lam.spdl --timer=60 --plain.time +++ b/src/regression-tests/results/test-gui-Protocols-woo-lam.spdl --timer=60 --plain.time @@ -1,2 +1,2 @@ Passed wall time in seconds: -36 +37 diff --git a/src/regression-tests/results/test-gui-Protocols-yahalom-ban-paulson-modified.spdl --timer=60 --plain.time b/src/regression-tests/results/test-gui-Protocols-yahalom-ban-paulson-modified.spdl --timer=60 --plain.time deleted file mode 100644 index 80f32ca..0000000 --- a/src/regression-tests/results/test-gui-Protocols-yahalom-ban-paulson-modified.spdl --timer=60 --plain.time +++ /dev/null @@ -1,2 +0,0 @@ -Passed wall time in seconds: -0 diff --git a/src/role.c b/src/role.c index 139fa5f..70d4413 100644 --- a/src/role.c +++ b/src/role.c @@ -415,7 +415,7 @@ Readable (Knowledge know, Term t) return true; } // Right disjunct - inv = inverseKey (know->inverses, TermKey (t)); + inv = inverseKey (know, TermKey (t)); either = false; if (inKnowledge (know, inv)) { diff --git a/src/scanner.l b/src/scanner.l index 7fd1570..df6152f 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -171,6 +171,7 @@ claim { return CLAIMT; } run { return RUN; } secret { return SECRET; } inversekeys { return INVERSEKEYS; } +inversekeyfunctions { return INVERSEKEYFUNCTIONS; } untrusted { return UNTRUSTED; } compromised { return COMPROMISED; } usertype { return USERTYPE; } diff --git a/src/specialterm.c b/src/specialterm.c index 774ae87..aa67649 100644 --- a/src/specialterm.c +++ b/src/specialterm.c @@ -119,7 +119,7 @@ specialTermInit (const System sys) langcons (TERM_PK, "pk", TERM_Function); langcons (TERM_SK, "sk", 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); /* Define a prefix for labels for the match function */ diff --git a/src/system.c b/src/system.c index f7fa2ad..9ea0a88 100644 --- a/src/system.c +++ b/src/system.c @@ -504,7 +504,7 @@ roleInstanceArachne (const System sys, const Protocol protocol, newt = makeTermType (GLOBAL, TermSymb (oldt), rid); } 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 TERMLISTADD (fromlist, oldt); diff --git a/src/tac.h b/src/tac.h index 0cbbaa0..2d303d1 100644 --- a/src/tac.h +++ b/src/tac.h @@ -32,6 +32,7 @@ enum tactypes TAC_SYM, TAC_TUPLE, TAC_ENCRYPT, + TAC_FCALL, TAC_VAR, TAC_CONST, TAC_FRESH, @@ -48,6 +49,7 @@ enum tactypes TAC_ROLEREF, TAC_SECRET, TAC_INVERSEKEYS, + TAC_INVERSEKEYFUNCTIONS, TAC_HASHFUNCTION, TAC_UNTRUSTED, TAC_COMPROMISED, diff --git a/src/term.c b/src/term.c index 6fb42bb..f9517b6 100644 --- a/src/term.c +++ b/src/term.c @@ -84,6 +84,9 @@ makeTerm () //! 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. */ Term @@ -92,11 +95,32 @@ makeTermEncrypt (Term t1, Term t2) Term term = makeTerm (); term->type = ENCRYPT; term->stype = NULL; + term->helper.fcall = false; + term->subst = NULL; TermOp (term) = t1; TermKey (term) = t2; 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. /** *@return A pointer to the new term. @@ -128,7 +152,8 @@ makeTermTuple (Term t1, Term t2) tt = makeTerm (); tt->type = TUPLE; tt->stype = NULL; - tt->roleVar = 0; + tt->helper.roleVar = 0; + tt->subst = NULL; TermOp1 (tt) = t1; TermOp2 (tt) = t2; return tt; @@ -145,7 +170,16 @@ makeTermType (const int type, const Symbol symb, const int runid) Term term = makeTerm (); term->type = type; 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; TermSymb (term) = symb; TermRunid (term) = runid; @@ -381,8 +415,7 @@ termPrintCustom (Term term, char *leftvar, char *rightvar, char *lefttup, } if (realTermEncrypt (term)) { - if (isTermLeaf (TermKey (term)) - && inTermlist (TermKey (term)->stype, TERM_Function)) + if (term->helper.fcall) { /* function application */ termPrintCustom (TermKey (term), leftvar, rightvar, lefttup, @@ -695,8 +728,12 @@ termRunid (Term term, int runid) /* anything else, recurse */ if (realTermEncrypt (term)) { - return makeTermEncrypt (termRunid (TermOp (term), runid), - termRunid (TermKey (term), runid)); + Term t; + + t = makeTermEncrypt (termRunid (TermOp (term), runid), + termRunid (TermKey (term), runid)); + t->helper.fcall = term->helper.fcall; + return t; } else { @@ -1159,22 +1196,23 @@ term_encryption_level (const Term term) } else { + int l, r; + if (realTermTuple (t)) { - int l, r; - l = iter_maxencrypt (TermOp1 (t)); r = iter_maxencrypt (TermOp2 (t)); - if (l > r) - return l; - else - return r; } else { // 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) { t = deVar (t); - if (t != NULL) + if (realTermEncrypt (t)) { - if (realTermEncrypt (t) && isTermFunctionName (TermKey (t))) + if (t->helper.fcall) { return TermKey (t); } diff --git a/src/term.h b/src/term.h index fa65a72..c919f2b 100644 --- a/src/term.h +++ b/src/term.h @@ -47,7 +47,11 @@ struct term //! Data Type termlist (e.g. agent or nonce) /** Only for leaves. */ 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. /** @@ -96,6 +100,7 @@ typedef struct term *Term; void termsInit (void); void termsDone (void); Term makeTermEncrypt (Term t1, Term t2); +Term makeTermFcall (Term t1, Term t2); Term makeTermTuple (Term t1, Term t2); Term makeTermType (const int type, const Symbol symb, const int runid); __inline__ Term deVarScan (Term t); diff --git a/src/termlist.c b/src/termlist.c index 7366eb1..7d25fdc 100644 --- a/src/termlist.c +++ b/src/termlist.c @@ -24,6 +24,7 @@ #include "debug.h" #include "error.h" #include "switches.h" +#include "knowledge.h" /* * Shared stuff @@ -618,68 +619,6 @@ termlistLength (Termlist tl) 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. /* * We assume that at this point, no variables have been instantiated yet that occur in this term. diff --git a/src/termlist.h b/src/termlist.h index 475e3c9..81189f7 100644 --- a/src/termlist.h +++ b/src/termlist.h @@ -66,7 +66,6 @@ Termlist termlistAddBasic (Termlist tl, Term t); Termlist termlistAddBasics (Termlist tl, Termlist scan); Termlist termlistMinusTerm (Termlist tl, Term t); int termlistLength (Termlist tl); -Term inverseKey (Termlist inverses, Term key); Term termLocal (const Term t, Termlist fromlist, Termlist tolist); Termlist termlistLocal (Termlist tl, const Termlist fromlist, const Termlist tolist); diff --git a/src/xmlout.c b/src/xmlout.c index 83ab337..5e541f0 100644 --- a/src/xmlout.c +++ b/src/xmlout.c @@ -438,7 +438,7 @@ xmlInverses (const System sys) xmlPrint (""); xmlindent++; - invlist = sys->know->inverses; + invlist = sys->know->inversekeys; while (invlist != NULL && invlist->next != NULL) { xmlPrint (""); @@ -452,6 +452,23 @@ xmlInverses (const System sys) } xmlindent--; xmlPrint (""); + + xmlPrint (""); + xmlindent++; + invlist = sys->know->inversekeyfunctions; + while (invlist != NULL && invlist->next != NULL) + { + xmlPrint (""); + xmlindent++; + xmlOutTerm (NULL, invlist->term); + xmlOutTerm (NULL, invlist->next->term); + xmlindent--; + xmlPrint (""); + + invlist = invlist->next->next; + } + xmlindent--; + xmlPrint (""); } //! Show initial knowledge