otrv4.m 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. --------------------------------------------------------------------------------
  2. --
  3. -- Murphi Model of the OTRv4 Draft Protocol State Machine and SMP State Machine
  4. --
  5. --------------------------------------------------------------------------------
  6. --
  7. -- Written by Nik Unger and Sofía Celi in 2018
  8. --
  9. -- This is free and unencumbered software released into the public domain.
  10. -- See the UNLICENSE file for the full license / public domain declaration.
  11. --
  12. -- The structure of this Murphi description is heavily inspired by the
  13. -- Needham-Schroeder description by Ulrich Stern, 1998 (bundled with CMurphi),
  14. -- and the OTRv2 description by Andrew Morrison and Joe Bonneau, 2006.
  15. --
  16. --------------------------------------------------------------------------------
  17. --------------------------------------------------------------------------------
  18. -- Declarations
  19. --------------------------------------------------------------------------------
  20. const
  21. NumClients: 2; -- number of clients in the system
  22. NetworkSize: 1; -- maximum number of in-flight messages in network
  23. MaxMessages: 10; -- maximum number of messages sent in a conversation
  24. MaxKnowledge: 10; -- maximum number of messages intruder can remember
  25. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  26. type
  27. InstanceTag: scalarset (NumClients);
  28. MessageType : enum { -- Types of messages that can be sent
  29. M_Plaintext, -- Ordinary plaintext without special values
  30. M_WSpTaggedPlaintext, -- Plaintext with a whitespace tag
  31. M_QueryMessage, -- OTR query message
  32. M_ErrorMessage, -- OTR error message
  33. M_IdentityMessage, -- Identity message (DAKEZ flow 1)
  34. M_AuthR, -- Auth-R message (DAKEZ flow 2)
  35. M_AuthI, -- Auth-I message (DAKEZ flow 3)
  36. M_NonInteractiveAuth, -- Non-Interactive-Auth message (XZDH flow 2)
  37. M_DataMessage -- Encrypted message with text and optionally TLV(s)
  38. };
  39. TLVType : enum { -- Types of encoded TLVs inside data messages
  40. T_Padding, -- Data to ignore (to hide message lengths)
  41. T_Disconnected, -- States that the conversation is over
  42. T_SMP1, -- SMP flow 1
  43. T_SMP2, -- SMP flow 2
  44. T_SMP3, -- SMP flow 3
  45. T_SMP4, -- SMP flow 4
  46. T_SMPAbort, -- States that the SMP has failed
  47. T_ExtraSymmetric -- Request for an extra symmetric key
  48. };
  49. Message : record
  50. msgType: MessageType;
  51. src, dst: InstanceTag; -- The actual sender & receiver clients
  52. -- TODO
  53. endrecord;
  54. ClientProfile : record
  55. owner: InstanceTag; -- Instance tag of creating client
  56. -- TODO
  57. expired: boolean;
  58. endrecord;
  59. -- Not modeled: fragmented messages
  60. -- Not modeled: OTRv3 transitions
  61. ProtocolState : enum { -- Main protocol states for OTRv4 clients
  62. S_Start, -- Initial client state
  63. S_WaitingAuthR, -- Waiting for M_AuthR
  64. S_WaitingAuthI, -- Waiting for M_AuthI
  65. S_EncryptedMessages, -- DAKE is finished, ready for encrypted messages
  66. S_Finished -- Received a disconnected message
  67. };
  68. SMPState : enum { -- SMP state, which expects an S_EncryptedMessages state
  69. SMP_Expect1, -- Initial SMP state, waiting for a T_SMP1 TLV
  70. SMP_Expect2, -- Waiting for a T_SMP2 TLV
  71. SMP_Expect3, -- Waiting for a T_SMP3 TLV
  72. SMP_Expect4 -- Waiting for a T_SMP4 TLV
  73. };
  74. Conversation : record
  75. protoState: ProtocolState; -- Overall protocol state machine
  76. smpState: SMPState; -- SMP state machine
  77. -- TODO
  78. endrecord;
  79. msgCount: 0 .. MaxMessages;
  80. Client : record
  81. conv: array[InstanceTag] of Conversation;
  82. msgCount: msgCount
  83. endrecord;
  84. -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
  85. -- The global state of the system
  86. var
  87. net: multiset[NetworkSize] of Message; -- In-flight messages
  88. clients: array[InstanceTag] of Client; -- Honest clients
  89. -- Adversarial knowledge:
  90. -- TODO
  91. --------------------------------------------------------------------------------
  92. -- Helper procedures and functions
  93. --------------------------------------------------------------------------------
  94. function transmittable(src, dst: InstanceTag) : boolean;
  95. begin
  96. return src != dst
  97. & multisetcount(l:net, true) < NetworkSize
  98. & clients[src].msgCount < MaxMessages;
  99. endfunction;
  100. procedure transmitMessage(src, dst: InstanceTag; var msg: Message);
  101. begin
  102. msg.src := src;
  103. msg.dst := dst;
  104. multisetadd(msg, net);
  105. clients[src].msgCount := clients[src].msgCount + 1
  106. endprocedure;
  107. procedure receiveMessage(src, dst: InstanceTag; var msg: Message);
  108. begin
  109. msg.src := src;
  110. msg.dst := dst;
  111. multisetadd(msg, net);
  112. clients[src].msgCount := clients[src].msgCount + 1
  113. endprocedure;
  114. --------------------------------------------------------------------------------
  115. -- Client and user rules
  116. --------------------------------------------------------------------------------
  117. ruleset a : InstanceTag; b : InstanceTag do
  118. rule "User requests a new OTR conversation with a query message"
  119. transmittable(a, b)
  120. & clients[a].conv[b].protoState != S_EncryptedMessages
  121. ==>
  122. var msg: Message;
  123. begin
  124. undefine msg;
  125. msg.msgType := M_QueryMessage;
  126. transmitMessage(a, b, msg)
  127. endrule;
  128. endruleset;
  129. ruleset a : InstanceTag; b : InstanceTag do
  130. rule "User requests a new OTR conversation with a whitespace tag"
  131. transmittable(a, b)
  132. & clients[a].conv[b].protoState != S_EncryptedMessages
  133. ==>
  134. var msg: Message;
  135. begin
  136. undefine msg;
  137. msg.msgType := M_WSpTaggedPlaintext;
  138. transmitMessage(a, b, msg)
  139. endrule;
  140. endruleset;
  141. ruleset a : InstanceTag; b : InstanceTag do
  142. rule "User reacts to a Query message and sends Identity message"
  143. transmittable(a, b)
  144. & (clients[a].conv[b].protoState = S_Start
  145. | clients[a].conv[b].protoState = S_WaitingAuthR
  146. | clients[a].conv[b].protoState = S_WaitingAuthI
  147. | clients[a].conv[b].protoState = S_EncryptedMessages
  148. | clients[a].conv[b].protoState = S_Finished)
  149. ==>
  150. var msg: Message;
  151. begin
  152. undefine msg;
  153. msg.msgType := M_QueryMessage;
  154. receiveMessage(a, b, msg)
  155. endrule;
  156. endruleset;
  157. --------------------------------------------------------------------------------
  158. -- Starting state
  159. --------------------------------------------------------------------------------
  160. startstate
  161. undefine net;
  162. undefine clients;
  163. for i : InstanceTag do
  164. clients[i].msgCount := 0;
  165. for j : InstanceTag do
  166. alias
  167. c : clients[i].conv[j]
  168. do
  169. c.protoState := S_Start;
  170. c.smpState := SMP_Expect1
  171. endalias;
  172. endfor;
  173. endfor;
  174. endstartstate;