| 1 | .\" -*-nroff-*- |
| 2 | .EQ |
| 3 | delim $$ |
| 4 | .EN |
| 5 | .de hP |
| 6 | .IP |
| 7 | \h'-\w'\fB\\$1\ \fP'u'\fB\\$1\ \fP\c |
| 8 | .. |
| 9 | .ie t .ds o \(bu |
| 10 | .el .ds o o |
| 11 | .ds DH Diffie\(enHellman |
| 12 | .TH udpkey 1 "2012-05-08" "Mark Wooding" "distorted.org.uk tools" |
| 13 | .SH NAME |
| 14 | udpkey \- send or receive a cryptographic key via a simple UDP protocol |
| 15 | .SH SYNOPSIS |
| 16 | .B udpkey |
| 17 | .RB [ \-k |
| 18 | .IR keyring ] |
| 19 | .RB [ \-r |
| 20 | .IR seed-file ] |
| 21 | .I fragment-tag |
| 22 | .I source-spec |
| 23 | \&... |
| 24 | .br |
| 25 | .B udpkey |
| 26 | .B \-l |
| 27 | .RB [ \-d ] |
| 28 | .RB [ \-k |
| 29 | .IR keyring ] |
| 30 | .RB [ \-r |
| 31 | .IR seed-file ] |
| 32 | .RI [ address \c |
| 33 | .BR : ] \c |
| 34 | .I port |
| 35 | .PP |
| 36 | .IR source-spec : |
| 37 | .br |
| 38 | |
| 39 | .IB address : port \c |
| 40 | .IB [ = \c |
| 41 | .IR tag ] \c |
| 42 | .IB [ # \c |
| 43 | .IR hash ] \c |
| 44 | .BR ; ... |
| 45 | .br |
| 46 | |
| 47 | .BI / filename |
| 48 | | |
| 49 | .BI ./ filename |
| 50 | .SH DESCRIPTION |
| 51 | The |
| 52 | .B udpkey |
| 53 | program can run in one of two modes: either it will request fragments of |
| 54 | a key from a number of sources (e.g., local files or remote servers), |
| 55 | assemble them together, and write the result to standard output; or it |
| 56 | will listen on a UDP port and transmit encrypted copies of key fragments |
| 57 | when requested. |
| 58 | .PP |
| 59 | The intended use of |
| 60 | .B udpkey |
| 61 | is for obtaining keys early in a system's boot process, so as to decrypt |
| 62 | the main disk volumes. See the discussion below regarding the security |
| 63 | properties of this approach. |
| 64 | .SS Options |
| 65 | The recognized command-line options are listed below. The synopsis |
| 66 | shows two distinct invocations for clarity: in fact, all options are |
| 67 | recognized all of the time, though options which are irrelevent in the |
| 68 | chosen mode are silently ignored. |
| 69 | .TP |
| 70 | .B \-h, \-\-help |
| 71 | Print a help message to standard output and exit successfully. |
| 72 | .TP |
| 73 | .B \-v, \-\-version |
| 74 | Print the program's version number to standard output and exit |
| 75 | successfully. |
| 76 | .TP |
| 77 | .B \-u, \-\-usage |
| 78 | Print a brief usage summary to standard output and exit successfully. |
| 79 | .TP |
| 80 | .B \-d, \-\-daemon |
| 81 | If the |
| 82 | .B \-l |
| 83 | option is also given, |
| 84 | .B udpkey |
| 85 | will detach from the terminal and run in the background after |
| 86 | initialization. Also, it will write messages using |
| 87 | .BR syslog (3) |
| 88 | (with facility |
| 89 | .BR daemon ) |
| 90 | rather than to standard error. |
| 91 | .TP |
| 92 | .BI "\-k, \-\-keyring=" keyring |
| 93 | Read keys from the |
| 94 | .I keyring |
| 95 | file, rather than the default, which is the file named |
| 96 | .B keyring |
| 97 | in the current working directory. |
| 98 | .TP |
| 99 | .B \-l, \-\-listen |
| 100 | Listen for incoming requests for key fragments and reply to them. The |
| 101 | default is to request key fragments. |
| 102 | .TP |
| 103 | .BI "\-r, \-\-random=" seed-file |
| 104 | Use (an initial portion of) the contents of |
| 105 | .I seed-file |
| 106 | to key the program's pseurorandom number generator. Since |
| 107 | .B udpkey |
| 108 | is intended to run early in a system's boot procedure, it's quite |
| 109 | unlikely that there's a great deal of high-quality entropy available. |
| 110 | It's therefore useful to generate a seed while the system is running, |
| 111 | and store it somewhere where it can be found during early boot. |
| 112 | .SS Client operation |
| 113 | For each |
| 114 | .I source-spec |
| 115 | on the command line of the form |
| 116 | .BI / filename |
| 117 | or |
| 118 | .BI ./ filename |
| 119 | the contents (or the inital 64KB of the contents, if the file is longer) |
| 120 | are read as a key fragment. |
| 121 | .PP |
| 122 | For each |
| 123 | .I source-spec |
| 124 | of the form |
| 125 | .IP |
| 126 | .IB address : port \c |
| 127 | .IB [ = \c |
| 128 | .IR tag ] \c |
| 129 | .IB [ # \c |
| 130 | .IR hash ] \c |
| 131 | .BR ; ... |
| 132 | .PP |
| 133 | a packet is sent to each listed |
| 134 | .I address |
| 135 | and |
| 136 | .I port |
| 137 | requesting the key fragment named by |
| 138 | .IR fragment-tag ; |
| 139 | responses are decrypted using the key |
| 140 | .I tag |
| 141 | (default |
| 142 | .BR udpkey-kem ). |
| 143 | If a valid response is received from any of the listed servers (matching |
| 144 | the given |
| 145 | .I hash |
| 146 | if specified) then the contents are used as the key fragment; if no |
| 147 | response is forthcoming from any of them then the requests are |
| 148 | retransmitted periodically. If no acceptable reponse is received after |
| 149 | a number of retransmissions, |
| 150 | .B udpkey |
| 151 | will give up. |
| 152 | .PP |
| 153 | If all of the fragments are successfully obtained then |
| 154 | .B udpkey |
| 155 | will check that they are the same length, XOR them together, and write |
| 156 | the result to its standard output; it finally exits with status 0. |
| 157 | .SS Server operaton |
| 158 | If the |
| 159 | .B \-l |
| 160 | option was given, |
| 161 | .B udpkey |
| 162 | runs in sever mode. It listens for incoming UDP packets addressed to |
| 163 | the given |
| 164 | .I port |
| 165 | (and, if specified, the given |
| 166 | .I address |
| 167 | \(en by default, any local address will do). If the |
| 168 | .B \-d |
| 169 | option was given, then |
| 170 | .B udpkey |
| 171 | will detach from its terminal (if any) and continue running in the |
| 172 | background. |
| 173 | .PP |
| 174 | A request packet contains a key tag identifying the wanted key |
| 175 | fragment. The key fragment is located. If the key data is not a plain |
| 176 | binary string, or the key has no |
| 177 | .B clients |
| 178 | attribute, then the request is rejected. Otherwise, the value of the |
| 179 | .B clients |
| 180 | attribute is expected to take the form |
| 181 | .IP |
| 182 | .IR address \c |
| 183 | .RB [ / \c |
| 184 | .IR prefix-len ] \c |
| 185 | .RB [ = \c |
| 186 | .IR tag ] \c |
| 187 | .BR ; ... |
| 188 | .PP |
| 189 | The clauses of the attribute value are interpreted from left to right, |
| 190 | as follows. If the most significant |
| 191 | .I prefix-len |
| 192 | bits (default 32 \(en i.e., all of them) of client's IP match the |
| 193 | corresponding bits of |
| 194 | .I address |
| 195 | then send the key fragment, encrypted using the key named |
| 196 | .I tag |
| 197 | (default |
| 198 | .BI client- addr \fR, |
| 199 | where |
| 200 | .I addr |
| 201 | is the client's IP address in dotted-quad form); no further clauses are |
| 202 | examined. If no clauses match then the request is refused and no reply |
| 203 | is sent. |
| 204 | .SS Key setup |
| 205 | The |
| 206 | .B udpkey |
| 207 | program uses the Catacomb keyring format to store its cryptographic |
| 208 | keys: see |
| 209 | .BR keyring (5) |
| 210 | for the technical details. Keys may be generated and managed using the |
| 211 | .BR key (1) |
| 212 | utility. |
| 213 | .PP |
| 214 | The security of |
| 215 | .BR udpkey 's |
| 216 | protocol (described below, for those who care about such things) is |
| 217 | based on the difficulty of \*(DH problems in cyclic groups. The client |
| 218 | needs to know the private key; the server need only know the public |
| 219 | part. Both ends must agree on the attributes associated with the key. |
| 220 | .PP |
| 221 | Two types of \*(DH groups are supported. The group type is determined |
| 222 | from the appropriate key's |
| 223 | .B group |
| 224 | attribute, if present. The possible values are as follows. |
| 225 | .TP |
| 226 | .B dh |
| 227 | Plain old \*(DH, in a Schnorr group \(en i.e., a prime-order subgroup of |
| 228 | the multiplicative group of a prime-order finite field. An appropriate |
| 229 | key may be generated using a command such as |
| 230 | .RS |
| 231 | .IP |
| 232 | .nf |
| 233 | .BI "key add \-t" tag " \-adh \-LS \-b3072 \-B256 udpkey-kem group=dh \fR..." |
| 234 | .fi |
| 235 | .RE |
| 236 | .TP |
| 237 | .B ec |
| 238 | A prime order subgroup of the group of projective points on an elliptic |
| 239 | curve. Catacomb's |
| 240 | .BR key (1) |
| 241 | program can't generate such groups, though it knows of a number of |
| 242 | suitable examples, or you can use your own curves. An appropriate key |
| 243 | can be generated using a command such as |
| 244 | .RS |
| 245 | .IP |
| 246 | .BI "key add \-t" tag " \-aec \-Cnist-p256 udpkey-kem group=ec \fR..." |
| 247 | .RE |
| 248 | .PP |
| 249 | Other attributes on the key determine the ancillary cryptographic |
| 250 | algorithms used in the protocol, as follows. |
| 251 | .TP |
| 252 | .B hash |
| 253 | The hash function used to derive symmetric keys from the shared secret |
| 254 | group element. The default is |
| 255 | .BR sha256 . |
| 256 | .TP |
| 257 | .B cipher |
| 258 | The symmetric encryption algorithm used to encrypt the key fragment. |
| 259 | The default is |
| 260 | .BR rijndael-counter . |
| 261 | .TP |
| 262 | .B mac |
| 263 | The message authentication code used to ensure the integrity of the |
| 264 | ciphertext, in the form |
| 265 | .IB name\fR[ / tagbits \fR]. |
| 266 | The defaults are to use HMAC with the chosen hash function, and truncate |
| 267 | the tag to half of its original length. |
| 268 | .PP |
| 269 | Key fragments must contain only plain binary data: you can generate one |
| 270 | using a command such as |
| 271 | .IP |
| 272 | .BI "key add \-t" tag " \-abinary \-b256 udpkey-frag clients=" client-spec " \fR..." |
| 273 | .PP |
| 274 | The |
| 275 | .B client |
| 276 | attribute is mandatory; its syntax and semantics are described above. |
| 277 | .SS Protocol description |
| 278 | Let $G$ be a cyclic group with prime order $q$; we consider this as a |
| 279 | one-dimensional vector space over the finite field ${roman GF}(q)$. Let |
| 280 | $P$ be any nonzero vector. |
| 281 | .PP |
| 282 | The client's private key is a scalar $x$; its public key is the |
| 283 | corresponding vector $X = x P$. When constructing a request, a client |
| 284 | selects a random scalar $u$; let $U = u P$ be the corresponding vector. |
| 285 | The request packet consists of the key tag of the wanted key fragment |
| 286 | followed by a representation of the vector $U$. |
| 287 | .PP |
| 288 | When constructing a response, a server selects random scalars $v$ and |
| 289 | $r$, and computes $V = v P$ and $R = r P$. It then determines $Y = v U$ |
| 290 | and $Z = r X$, and hashes $R$ and $Z$ to obtain keys for a symmetric |
| 291 | cipher and MAC. It encrypts the key fragment and authenticates the |
| 292 | resulting ciphertext. Finally, the response consists of the vectors $V$ |
| 293 | and $W = R - Y$, the MAC tag on the ciphertext, and the ciphertext |
| 294 | itself. |
| 295 | .PP |
| 296 | The client can determine $Y = u V$, $R = W + Y$, and compute $Z = x R$, |
| 297 | and thereby recover the cipher and MAC keys. |
| 298 | .SS Security discussion |
| 299 | We assume that the client can securely |
| 300 | .I erase |
| 301 | the key, and the ephemeral secret scalar $r$, from its memory once it |
| 302 | has finished using them. If we detect that the client has compromised |
| 303 | at some point when it does not know the key, we can instruct the servers |
| 304 | to withhold their fragments of the key. |
| 305 | .PP |
| 306 | The dance with $U$ and $V$ is a standard ephemeral \*(DH key exchange. |
| 307 | The other dance with $R$ and $X$, and the symmetric encryption, is |
| 308 | basically DLIES. The only trick is that $R$ is masked in the reply |
| 309 | using the ephemeral \*(DH key $Y$. (Subtracting rather than adding $Y$ |
| 310 | is more efficient. For the server, it makes no difference, since it can |
| 311 | compute $-Y = (-v) U$ and add; but for the client, subtraction might be |
| 312 | rather slower than addition.) |
| 313 | .PP |
| 314 | We have the following properties. |
| 315 | .hP \*o |
| 316 | Passively collecting requests and responses before compromising the |
| 317 | client does not assist an adversary in determining the value of a key |
| 318 | fragment, since the ephemeral scalars $u$ and $v$ are random and |
| 319 | independent. Assuming that Decisional \*(DH is hard in $G$, the |
| 320 | ephemeral secret $Y$ appears random to the adversary, so $W$ leaks |
| 321 | nothing about $R$. The symmetric keys are therefore independent of the |
| 322 | adversary's view. |
| 323 | .IP |
| 324 | We can do better. Suppose that an adversary can recover the symmetric |
| 325 | key given a request/reply pair. If we assume that the symmetric |
| 326 | encryption is good, then the adversary must have found the key by |
| 327 | hashing $R$ and $Z$. Therefore it can recover $Y = R - W$, which solves |
| 328 | an instance of the harder |
| 329 | .I Computational |
| 330 | (actually, Gap) \*(DH problem in $G$. |
| 331 | .IP |
| 332 | This analysis can be made rigorous and quantitative. |
| 333 | .hP \*o |
| 334 | Neither side attempts to authenticate the other explicitly. The server |
| 335 | implicitly authenticates the client by encrypting its key fragment using |
| 336 | the client's public key. (This encryption is standard DLIES, and |
| 337 | security again depends on the Gap \*(DH problem in $G$.) The client |
| 338 | doesn't attempt to authenticate the server at all, though it can check |
| 339 | that the response is correct by comparing its hash to a known copy; this |
| 340 | confirms that the received key fragment is correct, and the client has |
| 341 | no reason to care where a correct key fragment really came from. |
| 342 | .hP \*o |
| 343 | If multiple sources are used, and each knows a fragment chosen uniformly |
| 344 | at random,, then none of the individual sources has enough information |
| 345 | to construct the complete key. |
| 346 | .hP \*o |
| 347 | Storing a key fragment in a local file means that compromising servers |
| 348 | doesn't help an adversary obtain the key: the client |
| 349 | .I must |
| 350 | be compromised if the adversary is to succeed. |
| 351 | .hP \*o |
| 352 | If the client is compromised, and none of the sources has revoked the |
| 353 | client's access to its fragment, then the game is over and the adversary |
| 354 | wins. The client can obviously decrypt the fragments and assemble |
| 355 | them. If any source refuses to provide its fragment, the adversary |
| 356 | learns nothing about the reassembled key. |
| 357 | .hP \*o |
| 358 | In practice, high quality entropy is probably in short supply during |
| 359 | early boot. If an adversary can guess the ephemeral \*(DH scalar $u$ |
| 360 | having compromised the client, he can potentially decrypt a previously |
| 361 | captured response. Periodically rekeying the random number generator |
| 362 | \(en by rewriting the |
| 363 | .I seed-file |
| 364 | when high-quality entropy is available \(en serves to limit the exposure |
| 365 | to responses captured since the last rekeying. |
| 366 | .SH BUGS |
| 367 | For some mysterious reason, |
| 368 | .BR cryptsetup (8) |
| 369 | initially rejects a key from |
| 370 | .BR udpkey ; |
| 371 | but when the relevant |
| 372 | .B initramfs |
| 373 | script retries, everything works. I'm not sure what's going on here. |
| 374 | .SH SEE ALSO |
| 375 | .BR key (1), |
| 376 | .BR crypttab (5), |
| 377 | .BR keyring (5), |
| 378 | .BR cryptsetup (8), |
| 379 | .BR initramfs-tools (8). |
| 380 | .SH AUTHOR |
| 381 | Mark Wooding, <mdw@distorted.org.uk> |