Commit | Line | Data |
---|---|---|
247f344a MW |
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 | .BR "\-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 key while the system is running, and | |
111 | 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 maybe 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 the \*(DH in cyclic groups. The client need | |
218 | to know the private key; the server need only know the public part. | |
219 | 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 | a the multiplicative group of a prime-order finite field. An | |
229 | appropriate 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 man | |
243 | 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 / tagbits \fR. | |
266 | The default is 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 element of the group. | |
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 $U = u 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$. This analysis can be made | |
331 | rigorous and quantitative. | |
332 | .hP \*o | |
333 | Neither side attempts to authenticate the other explicitly. The server | |
334 | implicitly authenticates the client by encrypting its key fragment using | |
335 | the client's public key. (This encryption is standard DLIES, and | |
336 | security again depends on the Gap \*(DH problem in $G$.) The client | |
337 | doesn't attempt to authenticate the server at all, though it can check | |
338 | that the response is correct by comparing its hash to a known copy; this | |
339 | confirms that the received key fragment is correct, and the client has | |
340 | no reason to care where a correct key fragment really came from. | |
341 | .hP \*o | |
342 | If multiple sources are used, and each knows a fragment chosen uniformly | |
343 | at random,, then none of the individual sources has enough information | |
344 | to construct the complete key. | |
345 | .hP \*o | |
346 | Storing a key fragment in a local file means that compromising servers | |
347 | doesn't help an adversary obtain the key: the client | |
348 | .I must | |
349 | be compromised if the adversary is to succeed. | |
350 | .hP \*o | |
351 | If the client is compromised, and none of the sources has revoked the | |
352 | client's access to its fragment, then the game is over and the adversary | |
353 | wins. The client can obviously decrypt the fragments and assemble | |
354 | them. If any source refuses to provide its fragment, the adversary | |
355 | learns nothing about the reassembled key. | |
356 | .hP \*o | |
357 | In practice, high quality entropy is probably in short supply during | |
358 | early boot. If an adversary can guess the ephemeral \*(DH scalar $u$ | |
359 | having compromised the client, he can potentially decrypt a previously | |
360 | captured response. Periodically rekeying the random number generator | |
361 | \(en by rewriting the | |
362 | .I seed-file | |
363 | when high-quality entropy is available \(en serves to limit the exposure | |
364 | to responses captured since the last rekeying. | |
365 | .SH BUGS | |
366 | For some mysterious reason, | |
367 | .BR cryptsetup (8) | |
368 | initially rejects a key from | |
369 | .BR udpkey ; | |
370 | but when the relevant | |
371 | .B initramfs | |
372 | script retries, everything works. I'm not sure what's going on here. | |
373 | .SH SEE ALSO | |
374 | .BR key (1), | |
375 | .BR crypttab (5), | |
376 | .BR keyring (5), | |
377 | .BR cryptsetup (8), | |
378 | .BR initramfs-tools (8). | |
379 | .SH AUTHOR | |
380 | Mark Wooding, <mdw@distorted.org.uk> |