| 1 | #* Design of new, multi-subnet secnet protocol |
| 2 | |
| 3 | Like the first version, we're tunnelling IP packets inside UDP |
| 4 | packets. To defeat various restrictions which may be imposed on us by |
| 5 | network providers (like the prohibition of incoming TCP connections) |
| 6 | we're sticking with UDP for everything this time, including key setup. |
| 7 | |
| 8 | Other new features include being able to deal with subnets hidden |
| 9 | behind changing 'real' IP addresses, and the ability to choose |
| 10 | algorithms and keys per pair of communicating sites. |
| 11 | |
| 12 | ** Configuration and structure |
| 13 | |
| 14 | The network is made up from a number of 'sites'. These are collections |
| 15 | of machines with private IP addresses. The new secnet code runs on |
| 16 | machines which have interfaces on the private site network and some |
| 17 | way of accessing the 'real' internet. |
| 18 | |
| 19 | Each end of a tunnel is identified by a name. Often it will be |
| 20 | convenient for every gateway machine to use the same name for each |
| 21 | tunnel endpoint, but this is not vital. Individual tunnels are |
| 22 | identified by their two endpoint names. |
| 23 | |
| 24 | |
| 25 | The configuration is held in memory as a data structure as follows: |
| 26 | |
| 27 | The root is a Dictionary. Dictionaries hold (key,value) pairs. Keys |
| 28 | are atoms. Values are lists, dictionaries or closures. Lists can hold |
| 29 | the following types: string, number. |
| 30 | |
| 31 | Closures cannot be constructed directly; they are added to the |
| 32 | 'default' dictionary before the configuration file is read. Invocation |
| 33 | of a closure can return any type of value. |
| 34 | |
| 35 | |
| 36 | Configuration file format: the file describes a dictionary. |
| 37 | |
| 38 | key value; |
| 39 | |
| 40 | value is item[,item...] |
| 41 | |
| 42 | item can be "string", number, path (looks up in dictionary), |
| 43 | {dictionary}, value(value), value{dictionary}. If item is a list it |
| 44 | is copied into the list - we can't have lists of lists. |
| 45 | |
| 46 | A path is [/]key[\[index\]][/key[\[index\]]...], defining a lookup |
| 47 | from the current dictionary (or parents) or the root. If a key refers |
| 48 | to a list of more than one item then an index number (base 0) in |
| 49 | square brackets can be used to specify the list item number. |
| 50 | |
| 51 | Items of the form value1(value2) invoke executable value1 with an |
| 52 | argument of value2. The return value can be a string or dictionary, |
| 53 | but not a list. (Invocation happens after the entire configuration |
| 54 | file has been read.) |
| 55 | |
| 56 | Items of the form value{dict} invoke executable value with an argument |
| 57 | of a single-element list, containing dict. It's just syntactic sugar |
| 58 | for value({dict}). |
| 59 | |
| 60 | |
| 61 | When a key is used (rather than defined) it is looked up in the |
| 62 | current dictionary, and if it isn't found it is looked up in the |
| 63 | (lexical) parent, until the root is reached. |
| 64 | |
| 65 | |
| 66 | |
| 67 | |
| 68 | What sorts of crypto-related things do we need to define? |
| 69 | |
| 70 | sources of randomness |
| 71 | block algorithms |
| 72 | block cipher modes? |
| 73 | hash functions |
| 74 | padding functions |
| 75 | public key signature algorithms |
| 76 | public key crypto key stores |
| 77 | key setup algorithms |
| 78 | |
| 79 | |
| 80 | ** Protocols |
| 81 | |
| 82 | *** Protocol environment: |
| 83 | |
| 84 | Each gateway machine serves a particular, well-known set of private IP |
| 85 | addresses (i.e. the agreement over which addresses it serves is |
| 86 | outside the scope of this discussion). Each gateway machine has an IP |
| 87 | address on the interconnecting network (usually the Internet), which |
| 88 | may be dynamically allocated and may change at any point. |
| 89 | |
| 90 | Each gateway knows the RSA public keys of the other gateways with |
| 91 | which it wishes to communicate. The mechanism by which this happens is |
| 92 | outside the scope of this discussion. There exists a means by which |
| 93 | each gateway can look up the probable IP address of any other. |
| 94 | |
| 95 | *** Protocol goals: |
| 96 | |
| 97 | The ultimate goal of the protocol is for the originating gateway |
| 98 | machine to be able to forward packets from its section of the private |
| 99 | network to the appropriate gateway machine for the destination |
| 100 | machine, in such a way that it can be sure that the packets are being |
| 101 | sent to the correct destination machine, the destination machine can |
| 102 | be sure that the source of the packets is the originating gateway |
| 103 | machine, and the contents of the packets cannot be understood other |
| 104 | than by the two communicating gateways. |
| 105 | |
| 106 | XXX not sure about the address-change stuff; leave it out of the first |
| 107 | version of the protocol. From experience, IP addresses seem to be |
| 108 | quite stable so the feature doesn't gain us much. |
| 109 | |
| 110 | **** Protocol sub-goal 1: establish a shared key |
| 111 | |
| 112 | Definitions: |
| 113 | |
| 114 | A is the originating gateway machine |
| 115 | B is the destination gateway machine |
| 116 | PK_A is the public RSA key of A |
| 117 | PK_B is the public RSA key of B |
| 118 | PK_A^-1 is the private RSA key of A |
| 119 | PK_B^-1 is the private RSA key of B |
| 120 | x is the fresh private DH key of A |
| 121 | y is the fresh private DH key of B |
| 122 | k is g^xy mod m |
| 123 | g and m are generator and modulus for Diffie-Hellman |
| 124 | nA is a nonce generated by A |
| 125 | nB is a nonce generated by B |
| 126 | iA is an index generated by A, to be used in packets sent from B to A |
| 127 | iB is an index generated by B, to be used in packets sent from A to B |
| 128 | i? is appropriate index for receiver |
| 129 | |
| 130 | Note that 'i' may be re-used from one session to the next, whereas 'n' |
| 131 | is always fresh. |
| 132 | |
| 133 | Messages: |
| 134 | |
| 135 | 1) A->B: *,iA,msg1,A,B,nA |
| 136 | |
| 137 | 2) B->A: iA,iB,msg2,B,A,nB,nA |
| 138 | |
| 139 | (The order of B and A reverses in alternate messages so that the same |
| 140 | code can be used to construct them...) |
| 141 | |
| 142 | 3) A->B: {iB,iA,msg3,A,B,nA,nB,g^x mod m}_PK_A^-1 |
| 143 | |
| 144 | If message 1 was a replay then A will not generate message 3, because |
| 145 | it doesn't recognise nA. |
| 146 | |
| 147 | If message 2 was from an attacker then B will not generate message 4, |
| 148 | because it doesn't recognise nB. |
| 149 | |
| 150 | 4) B->A: {iA,iB,msg4,B,A,nB,nA,g^y mod m}_PK_B^-1 |
| 151 | |
| 152 | At this point, A and B share a key, k. B must keep retransmitting |
| 153 | message 4 until it receives a packet encrypted using key k. |
| 154 | |
| 155 | 5) A: iB,iA,msg5,(ping/msg5)_k |
| 156 | |
| 157 | 6) B: iA,iB,msg6,(pong/msg6)_k |
| 158 | |
| 159 | (Note that these are encrypted using the same transform that's used |
| 160 | for normal traffic, so they include sequence number, MAC, etc.) |
| 161 | |
| 162 | The ping and pong messages can be used by either end of the tunnel at |
| 163 | any time, but using msg0 as the unencrypted message type indicator. |
| 164 | |
| 165 | **** Protocol sub-goal 2: end the use of a shared key |
| 166 | |
| 167 | 7) i?,i?,msg0,(end-session/msg7,A,B)_k |
| 168 | |
| 169 | This message can be sent by either party. Once sent, k can be |
| 170 | forgotten. Once received and checked, k can be forgotten. No need to |
| 171 | retransmit or confirm reception. It is suggested that this message be |
| 172 | sent when a key times out, or the tunnel is forcibly terminated for |
| 173 | some reason. |
| 174 | |
| 175 | 8) i?,i?,NAK/msg8 |
| 176 | |
| 177 | If the link-layer can't work out what to do with a packet (session has |
| 178 | gone away, etc.) it can transmit a NAK back to the sender. The sender |
| 179 | can then try to verify whether the session is alive by sending ping |
| 180 | packets, and forget the key if it isn't. Potential denial-of-service |
| 181 | if the attacker can stop the ping/pong packets getting through (the |
| 182 | key will be forgotten and another key setup must take place), but if |
| 183 | they can delete packets then we've lost anyway... |
| 184 | |
| 185 | The attacker can of course forge NAKs since they aren't protected. But |
| 186 | if they can only forge packets then they won't be able to stop the |
| 187 | ping/pong working. Trust in NAKs can be rate-limited... |
| 188 | |
| 189 | Alternative idea: if you receive a packet you can't decode, because |
| 190 | there's no key established, then initiate key setup... |
| 191 | |
| 192 | **** Protocol sub-goal 3: send a packet |
| 193 | |
| 194 | 9) i?,i?,msg0,(send-packet/msg9,packet)_k |