xref: /dragonfly/lib/libdmsg/crypto.c (revision 37de577a)
1 /*
2  * Copyright (c) 2011-2012 The DragonFly Project.  All rights reserved.
3  *
4  * This code is derived from software contributed to The DragonFly Project
5  * by Matthew Dillon <dillon@dragonflybsd.org>
6  * by Venkatesh Srinivas <vsrinivas@dragonflybsd.org>
7  * by Alex Hornung <alexh@dragonflybsd.org>
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  *
13  * 1. Redistributions of source code must retain the above copyright
14  *    notice, this list of conditions and the following disclaimer.
15  * 2. Redistributions in binary form must reproduce the above copyright
16  *    notice, this list of conditions and the following disclaimer in
17  *    the documentation and/or other materials provided with the
18  *    distribution.
19  * 3. Neither the name of The DragonFly Project nor the names of its
20  *    contributors may be used to endorse or promote products derived
21  *    from this software without specific, prior written permission.
22  *
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27  * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28  * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31  * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34  * SUCH DAMAGE.
35  */
36 
37 #include "dmsg_local.h"
38 
39 /*
40  * Setup crypto for pthreads
41  */
42 static pthread_mutex_t *crypto_locks;
43 int crypto_count;
44 
45 static int dmsg_crypto_gcm_init(dmsg_ioq_t *, char *, int, char *, int, int);
46 static int dmsg_crypto_gcm_encrypt_chunk(dmsg_ioq_t *, char *, char *, int, int *);
47 static int dmsg_crypto_gcm_decrypt_chunk(dmsg_ioq_t *, char *, char *, int, int *);
48 
49 /*
50  * NOTE: the order of this table needs to match the DMSG_CRYPTO_ALGO_*_IDX
51  *       defines in network.h.
52  */
53 static struct crypto_algo crypto_algos[] = {
54 	{
55 		.name      = "aes-256-gcm",
56 		.keylen    = DMSG_CRYPTO_GCM_KEY_SIZE,
57 		.taglen    = DMSG_CRYPTO_GCM_TAG_SIZE,
58 		.init      = dmsg_crypto_gcm_init,
59 		.enc_chunk = dmsg_crypto_gcm_encrypt_chunk,
60 		.dec_chunk = dmsg_crypto_gcm_decrypt_chunk
61 	},
62 	{ NULL, 0, 0, NULL, NULL, NULL }
63 };
64 
65 static
66 unsigned long
67 dmsg_crypto_id_callback(void)
68 {
69 	return ((unsigned long)(uintptr_t)pthread_self());
70 }
71 
72 static
73 void
74 dmsg_crypto_locking_callback(int mode, int type,
75 				const char *file __unused, int line __unused)
76 {
77 	assert(type >= 0 && type < crypto_count);
78 	if (mode & CRYPTO_LOCK) {
79 		pthread_mutex_lock(&crypto_locks[type]);
80 	} else {
81 		pthread_mutex_unlock(&crypto_locks[type]);
82 	}
83 }
84 
85 void
86 dmsg_crypto_setup(void)
87 {
88 	crypto_count = CRYPTO_num_locks();
89 	crypto_locks = calloc(crypto_count, sizeof(crypto_locks[0]));
90 	CRYPTO_set_id_callback(dmsg_crypto_id_callback);
91 	CRYPTO_set_locking_callback(dmsg_crypto_locking_callback);
92 }
93 
94 static
95 int
96 dmsg_crypto_gcm_init(dmsg_ioq_t *ioq, char *key, int klen,
97 			char *iv_fixed, int ivlen, int enc)
98 {
99 	int i, ok;
100 
101 	if (klen < DMSG_CRYPTO_GCM_KEY_SIZE ||
102 	    ivlen < DMSG_CRYPTO_GCM_IV_FIXED_SIZE) {
103 		dm_printf(1, "%s\n", "Not enough key or iv material");
104 		return -1;
105 	}
106 
107 	dm_printf(6, "%s key: ", enc ? "Encryption" : "Decryption");
108 	for (i = 0; i < DMSG_CRYPTO_GCM_KEY_SIZE; ++i)
109 		dmx_printf(6, "%02x", (unsigned char)key[i]);
110 	dmx_printf(6, "%s\n", "");
111 
112 	dm_printf(6, "%s iv:  ", enc ? "Encryption" : "Decryption");
113 	for (i = 0; i < DMSG_CRYPTO_GCM_IV_FIXED_SIZE; ++i)
114 		dmx_printf(6, "%02x", (unsigned char)iv_fixed[i]);
115 	dmx_printf(6, "%s\n", " (fixed part only)");
116 
117 	EVP_CIPHER_CTX_init(&ioq->ctx);
118 
119 	if (enc)
120 		ok = EVP_EncryptInit_ex(&ioq->ctx, EVP_aes_256_gcm(), NULL,
121 					(unsigned char*)key, NULL);
122 	else
123 		ok = EVP_DecryptInit_ex(&ioq->ctx, EVP_aes_256_gcm(), NULL,
124 					(unsigned char*)key, NULL);
125 	if (!ok)
126 		goto fail;
127 
128 	/*
129 	 * According to the original Galois/Counter Mode of Operation (GCM)
130 	 * proposal, only IVs that are exactly 96 bits get used without any
131 	 * further processing. Other IV sizes cause the GHASH() operation
132 	 * to be applied to the IV, which is more costly.
133 	 *
134 	 * The NIST SP 800-38D also recommends using a 96 bit IV for the same
135 	 * reasons. We actually follow the deterministic construction
136 	 * recommended in NIST SP 800-38D with a 64 bit invocation field as an
137 	 * integer counter and a random, session-specific fixed field.
138 	 *
139 	 * This means that we can essentially use the same session key and
140 	 * IV fixed field for up to 2^64 invocations of the authenticated
141 	 * encryption or decryption.
142 	 *
143 	 * With a chunk size of 64 bytes, this adds up to 1 zettabyte of
144 	 * traffic.
145 	 */
146 	ok = EVP_CIPHER_CTX_ctrl(&ioq->ctx, EVP_CTRL_GCM_SET_IVLEN,
147 				 DMSG_CRYPTO_GCM_IV_SIZE, NULL);
148 	if (!ok)
149 		goto fail;
150 
151 	memset(ioq->iv, 0, DMSG_CRYPTO_GCM_IV_SIZE);
152 	memcpy(ioq->iv, iv_fixed, DMSG_CRYPTO_GCM_IV_FIXED_SIZE);
153 
154 	/*
155 	 * Strictly speaking, padding is irrelevant with a counter mode
156 	 * encryption.
157 	 *
158 	 * However, setting padding to 0, even if using a counter mode such
159 	 * as GCM, will cause an error in _finish if the pt/ct size is not
160 	 * a multiple of the cipher block size.
161 	 */
162 	EVP_CIPHER_CTX_set_padding(&ioq->ctx, 0);
163 
164 	return 0;
165 
166 fail:
167 	dm_printf(1, "%s\n", "Error during _gcm_init");
168 	return -1;
169 }
170 
171 static
172 int
173 _gcm_iv_increment(char *iv)
174 {
175 	/*
176 	 * Deterministic construction according to NIST SP 800-38D, with
177 	 * 64 bit invocation field as integer counter.
178 	 *
179 	 * In other words, our 96 bit IV consists of a 32 bit fixed field
180 	 * unique to the session and a 64 bit integer counter.
181 	 */
182 
183 	uint64_t *c = (uint64_t *)(&iv[DMSG_CRYPTO_GCM_IV_FIXED_SIZE]);
184 
185 	/* Increment invocation field integer counter */
186 	*c = htobe64(be64toh(*c)+1);
187 
188 	/*
189 	 * Detect wrap-around, which means it is time to renegotiate
190 	 * the session to get a new key and/or fixed field.
191 	 */
192 	return (*c == 0) ? 0 : 1;
193 }
194 
195 static
196 int
197 dmsg_crypto_gcm_encrypt_chunk(dmsg_ioq_t *ioq, char *ct, char *pt,
198 				 int in_size, int *out_size)
199 {
200 	int ok;
201 	int u_len, f_len;
202 
203 	*out_size = 0;
204 
205 	/* Re-initialize with new IV (but without redoing the key schedule) */
206 	ok = EVP_EncryptInit_ex(&ioq->ctx, NULL, NULL, NULL,
207 		(unsigned char*)ioq->iv);
208 	if (!ok)
209 		goto fail;
210 
211 	u_len = 0;	/* safety */
212 	ok = EVP_EncryptUpdate(&ioq->ctx, (unsigned char*)ct, &u_len,
213 		(unsigned char*)pt, in_size);
214 	if (!ok)
215 		goto fail;
216 
217 	f_len = 0;	/* safety */
218 	ok = EVP_EncryptFinal_ex(&ioq->ctx, (unsigned char*)ct + u_len, &f_len);
219 	if (!ok)
220 		goto fail;
221 
222 	/* Retrieve auth tag */
223 	ok = EVP_CIPHER_CTX_ctrl(&ioq->ctx, EVP_CTRL_GCM_GET_TAG,
224 				 DMSG_CRYPTO_GCM_TAG_SIZE,
225 				 ct + u_len + f_len);
226 	if (!ok)
227 		goto fail;
228 
229 	ok = _gcm_iv_increment(ioq->iv);
230 	if (!ok) {
231 		ioq->error = DMSG_IOQ_ERROR_IVWRAP;
232 		goto fail_out;
233 	}
234 
235 	*out_size = u_len + f_len + DMSG_CRYPTO_GCM_TAG_SIZE;
236 	EVP_CIPHER_CTX_reset(&ioq->ctx);
237 
238 	return 0;
239 
240 fail:
241 	ioq->error = DMSG_IOQ_ERROR_ALGO;
242 fail_out:
243 	EVP_CIPHER_CTX_reset(&ioq->ctx);
244 	dm_printf(1, "%s\n", "error during encrypt_chunk");
245 	return -1;
246 }
247 
248 static
249 int
250 dmsg_crypto_gcm_decrypt_chunk(dmsg_ioq_t *ioq, char *ct, char *pt,
251 				 int out_size, int *consume_size)
252 {
253 	int ok;
254 	int u_len, f_len;
255 
256 	*consume_size = 0;
257 
258 	/* Re-initialize with new IV (but without redoing the key schedule) */
259 	ok = EVP_DecryptInit_ex(&ioq->ctx, NULL, NULL, NULL,
260 		(unsigned char*)ioq->iv);
261 	if (!ok) {
262 		ioq->error = DMSG_IOQ_ERROR_ALGO;
263 		goto fail_out;
264 	}
265 
266 	ok = EVP_CIPHER_CTX_ctrl(&ioq->ctx, EVP_CTRL_GCM_SET_TAG,
267 				 DMSG_CRYPTO_GCM_TAG_SIZE,
268 				 ct + out_size);
269 	if (!ok) {
270 		ioq->error = DMSG_IOQ_ERROR_ALGO;
271 		goto fail_out;
272 	}
273 
274 	ok = EVP_DecryptUpdate(&ioq->ctx, (unsigned char*)pt, &u_len,
275 		(unsigned char*)ct, out_size);
276 	if (!ok)
277 		goto fail;
278 
279 	ok = EVP_DecryptFinal_ex(&ioq->ctx, (unsigned char*)pt + u_len, &f_len);
280 	if (!ok)
281 		goto fail;
282 
283 	ok = _gcm_iv_increment(ioq->iv);
284 	if (!ok) {
285 		ioq->error = DMSG_IOQ_ERROR_IVWRAP;
286 		goto fail_out;
287 	}
288 
289 	*consume_size = u_len + f_len + DMSG_CRYPTO_GCM_TAG_SIZE;
290 	EVP_CIPHER_CTX_reset(&ioq->ctx);
291 
292 	return 0;
293 
294 fail:
295 	ioq->error = DMSG_IOQ_ERROR_MACFAIL;
296 fail_out:
297 	EVP_CIPHER_CTX_reset(&ioq->ctx);
298 	dm_printf(1, "%s\n",
299 		  "error during decrypt_chunk "
300 		  "(likely authentication error)");
301 	return -1;
302 }
303 
304 /*
305  * Synchronously negotiate crypto for a new session.  This must occur
306  * within 10 seconds or the connection is error'd out.
307  *
308  * We work off the IP address and/or reverse DNS.  The IP address is
309  * checked first, followed by the IP address at various levels of granularity,
310  * followed by the full domain name and domain names at various levels of
311  * granularity.
312  *
313  *	/etc/hammer2/remote/<name>.pub	- Contains a public key
314  *	/etc/hammer2/remote/<name>.none	- Indicates no encryption (empty file)
315  *					  (e.g. localhost.none).
316  *
317  * We first attempt to locate a public key file based on the peer address or
318  * peer FQDN.
319  *
320  *	<name>.none	- No further negotiation is needed.  We simply return.
321  *			  All communication proceeds without encryption.
322  *			  No public key handshake occurs in this situation.
323  *			  (both ends must match).
324  *
325  *	<name>.pub	- We have located the public key for the peer.  Both
326  *			  sides transmit a block encrypted with their private
327  *			  keys and the peer's public key.
328  *
329  *			  Both sides receive a block and decrypt it.
330  *
331  *			  Both sides formulate a reply using the decrypted
332  *			  block and transmit it.
333  *
334  *			  communication proceeds with the negotiated session
335  *			  key (typically AES-256-CBC).
336  *
337  * If we fail to locate the appropriate file and no floating.db exists the
338  * connection is terminated without further action.
339  *
340  * If floating.db exists the connection proceeds with a floating negotiation.
341  */
342 typedef union {
343 	struct sockaddr sa;
344 	struct sockaddr_in sa_in;
345 	struct sockaddr_in6 sa_in6;
346 } sockaddr_any_t;
347 
348 void
349 dmsg_crypto_negotiate(dmsg_iocom_t *iocom)
350 {
351 	sockaddr_any_t sa;
352 	socklen_t salen = sizeof(sa);
353 	char peername[128];
354 	char realname[128];
355 	dmsg_handshake_t handtx;
356 	dmsg_handshake_t handrx;
357 	char buf1[sizeof(handtx)];
358 	char buf2[sizeof(handtx)];
359 	char *ptr;
360 	char *path = NULL;
361 	struct stat st;
362 	FILE *fp;
363 	RSA *keys[3] = { NULL, NULL, NULL };
364 	size_t i;
365 	size_t blksize;
366 	size_t blkmask;
367 	ssize_t n;
368 	int fd;
369 	int error;
370 
371 	/*
372 	 * Get the peer IP address for the connection as a string.
373 	 */
374 	if (getpeername(iocom->sock_fd, &sa.sa, &salen) < 0) {
375 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_NOPEER;
376 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
377 		dm_printf(1, "%s\n", "accept: getpeername() failed");
378 		goto done;
379 	}
380 	if (getnameinfo(&sa.sa, salen, peername, sizeof(peername),
381 			NULL, 0, NI_NUMERICHOST) < 0) {
382 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_NOPEER;
383 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
384 		dm_printf(1, "%s\n", "accept: cannot decode sockaddr");
385 		goto done;
386 	}
387 	if (DMsgDebugOpt) {
388 		if (realhostname_sa(realname, sizeof(realname),
389 				    &sa.sa, salen) == HOSTNAME_FOUND) {
390 			dm_printf(1, "accept from %s (%s)\n",
391 				  peername, realname);
392 		} else {
393 			dm_printf(1, "accept from %s\n", peername);
394 		}
395 	}
396 
397 	/*
398 	 * Find the remote host's public key
399 	 *
400 	 * If the link is not to be encrypted (<ip>.none located) we shortcut
401 	 * the handshake entirely.  No buffers are exchanged.
402 	 */
403 	asprintf(&path, "%s/%s.pub", DMSG_PATH_REMOTE, peername);
404 	if ((fp = fopen(path, "r")) == NULL) {
405 		free(path);
406 		asprintf(&path, "%s/%s.none",
407 			 DMSG_PATH_REMOTE, peername);
408 		if (stat(path, &st) < 0) {
409 			iocom->ioq_rx.error = DMSG_IOQ_ERROR_NORKEY;
410 			atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
411 			dm_printf(1, "%s\n", "auth failure: unknown host");
412 			goto done;
413 		}
414 		dm_printf(1, "%s\n", "auth succeeded, unencrypted link");
415 		goto done;
416 	}
417 	if (fp) {
418 		keys[0] = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
419 		fclose(fp);
420 		if (keys[0] == NULL) {
421 			iocom->ioq_rx.error = DMSG_IOQ_ERROR_KEYFMT;
422 			atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
423 			dm_printf(1, "%s\n", "auth failure: bad key format");
424 			goto done;
425 		}
426 	}
427 
428 	/*
429 	 * Get our public and private keys
430 	 */
431 	free(path);
432 	asprintf(&path, DMSG_DEFAULT_DIR "/rsa.pub");
433 	if ((fp = fopen(path, "r")) == NULL) {
434 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_NOLKEY;
435 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
436 		goto done;
437 	}
438 	keys[1] = PEM_read_RSA_PUBKEY(fp, NULL, NULL, NULL);
439 	fclose(fp);
440 	if (keys[1] == NULL) {
441 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_KEYFMT;
442 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
443 		dm_printf(1, "%s\n", "auth failure: bad host key format");
444 		goto done;
445 	}
446 
447 	free(path);
448 	asprintf(&path, DMSG_DEFAULT_DIR "/rsa.prv");
449 	if ((fp = fopen(path, "r")) == NULL) {
450 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_NOLKEY;
451 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
452 		dm_printf(1, "%s\n", "auth failure: bad host key format");
453 		goto done;
454 	}
455 	keys[2] = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL);
456 	fclose(fp);
457 	if (keys[2] == NULL) {
458 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_KEYFMT;
459 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
460 		dm_printf(1, "%s\n", "auth failure: bad host key format");
461 		goto done;
462 	}
463 	free(path);
464 	path = NULL;
465 
466 	/*
467 	 * public key encrypt/decrypt block size.
468 	 */
469 	if (keys[0]) {
470 		blksize = (size_t)RSA_size(keys[0]);
471 		if (blksize != (size_t)RSA_size(keys[1]) ||
472 		    blksize != (size_t)RSA_size(keys[2]) ||
473 		    sizeof(handtx) % blksize != 0) {
474 			iocom->ioq_rx.error = DMSG_IOQ_ERROR_KEYFMT;
475 			atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
476 			dm_printf(1, "%s\n",
477 				  "auth failure: key size mismatch");
478 			goto done;
479 		}
480 	} else {
481 		blksize = sizeof(handtx);
482 	}
483 	blkmask = blksize - 1;
484 
485 	bzero(&handrx, sizeof(handrx));
486 	bzero(&handtx, sizeof(handtx));
487 
488 	/*
489 	 * Fill all unused fields (particular all junk fields) with random
490 	 * data, and also set the session key.
491 	 */
492 	fd = open("/dev/urandom", O_RDONLY);
493 	if (fd < 0 ||
494 	    fstat(fd, &st) < 0 ||	/* something wrong */
495 	    S_ISREG(st.st_mode) ||	/* supposed to be a RNG dev! */
496 	    read(fd, &handtx, sizeof(handtx)) != sizeof(handtx)) {
497 urandfail:
498 		if (fd >= 0)
499 			close(fd);
500 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_BADURANDOM;
501 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
502 		dm_printf(1, "%s\n", "auth failure: bad rng");
503 		goto done;
504 	}
505 	if (bcmp(&handrx, &handtx, sizeof(handtx)) == 0)
506 		goto urandfail;			/* read all zeros */
507 	close(fd);
508 	/* ERR_load_crypto_strings(); openssl debugging */
509 
510 	/*
511 	 * Handshake with the remote.
512 	 *
513 	 *	Encrypt with my private and remote's public
514 	 *	Decrypt with my private and remote's public
515 	 *
516 	 * When encrypting we have to make sure our buffer fits within the
517 	 * modulus, which typically requires bit 7 o the first byte to be
518 	 * zero.  To be safe make sure that bit 7 and bit 6 is zero.
519 	 */
520 	snprintf(handtx.quickmsg, sizeof(handtx.quickmsg), "Testing 1 2 3");
521 	handtx.magic = DMSG_HDR_MAGIC;
522 	handtx.version = 1;
523 	handtx.flags = 0;
524 	assert(sizeof(handtx.verf) * 4 == sizeof(handtx.sess));
525 	bzero(handtx.verf, sizeof(handtx.verf));
526 
527 	handtx.pad1[0] &= 0x3f;	/* message must fit within modulus */
528 	handtx.pad2[0] &= 0x3f;	/* message must fit within modulus */
529 
530 	for (i = 0; i < sizeof(handtx.sess); ++i)
531 		handtx.verf[i / 4] ^= handtx.sess[i];
532 
533 	/*
534 	 * Write handshake buffer to remote
535 	 */
536 	for (i = 0; i < sizeof(handtx); i += blksize) {
537 		ptr = (char *)&handtx + i;
538 		if (keys[0]) {
539 			/*
540 			 * Since we are double-encrypting we have to make
541 			 * sure that the result of the first stage does
542 			 * not blow out the modulus for the second stage.
543 			 *
544 			 * The pointer is pointing to the pad*[] area so
545 			 * we can mess with that until the first stage
546 			 * is legal.
547 			 */
548 			do {
549 				++*(int *)(ptr + 4);
550 				if (RSA_private_encrypt(blksize,
551 					    (unsigned char*)ptr,
552 					    (unsigned char*)buf1,
553 					    keys[2], RSA_NO_PADDING) < 0) {
554 					iocom->ioq_rx.error =
555 						DMSG_IOQ_ERROR_KEYXCHGFAIL;
556 				}
557 			} while (buf1[0] & 0xC0);
558 
559 			if (RSA_public_encrypt(blksize,
560 					    (unsigned char*)buf1,
561 					    (unsigned char*)buf2,
562 					    keys[0], RSA_NO_PADDING) < 0) {
563 				iocom->ioq_rx.error =
564 					DMSG_IOQ_ERROR_KEYXCHGFAIL;
565 			}
566 		}
567 		if (write(iocom->sock_fd, buf2, blksize) != (ssize_t)blksize) {
568 			dmio_printf(iocom, 1, "%s\n", "WRITE ERROR");
569 		}
570 	}
571 	if (iocom->ioq_rx.error) {
572 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
573 		dmio_printf(iocom, 1, "%s\n",
574 			    "auth failure: key exchange failure "
575 			    "during encryption");
576 		goto done;
577 	}
578 
579 	/*
580 	 * Read handshake buffer from remote
581 	 */
582 	i = 0;
583 	while (i < sizeof(handrx)) {
584 		ptr = (char *)&handrx + i;
585 		n = read(iocom->sock_fd, ptr, blksize - (i & blkmask));
586 		if (n <= 0)
587 			break;
588 		ptr -= (i & blkmask);
589 		i += n;
590 		if (keys[0] && (i & blkmask) == 0) {
591 			if (RSA_private_decrypt(blksize,
592 					   (unsigned char*)ptr,
593 					   (unsigned char*)buf1,
594 					   keys[2], RSA_NO_PADDING) < 0)
595 				iocom->ioq_rx.error =
596 						DMSG_IOQ_ERROR_KEYXCHGFAIL;
597 			if (RSA_public_decrypt(blksize,
598 					   (unsigned char*)buf1,
599 					   (unsigned char*)ptr,
600 					   keys[0], RSA_NO_PADDING) < 0)
601 				iocom->ioq_rx.error =
602 						DMSG_IOQ_ERROR_KEYXCHGFAIL;
603 		}
604 	}
605 	if (iocom->ioq_rx.error) {
606 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
607 		dmio_printf(iocom, 1, "%s\n",
608 			    "auth failure: key exchange failure "
609 			    "during decryption");
610 		goto done;
611 	}
612 
613 	/*
614 	 * Validate the received data.  Try to make this a constant-time
615 	 * algorithm.
616 	 */
617 	if (i != sizeof(handrx)) {
618 keyxchgfail:
619 		iocom->ioq_rx.error = DMSG_IOQ_ERROR_KEYXCHGFAIL;
620 		atomic_set_int(&iocom->flags, DMSG_IOCOMF_EOF);
621 		dmio_printf(iocom, 1, "%s\n",
622 			    "auth failure: key exchange failure");
623 		goto done;
624 	}
625 
626 	if (handrx.magic == DMSG_HDR_MAGIC_REV) {
627 		handrx.version = bswap16(handrx.version);
628 		handrx.flags = bswap32(handrx.flags);
629 	}
630 	for (i = 0; i < sizeof(handrx.sess); ++i)
631 		handrx.verf[i / 4] ^= handrx.sess[i];
632 	n = 0;
633 	for (i = 0; i < sizeof(handrx.verf); ++i)
634 		n += handrx.verf[i];
635 	if (handrx.version != 1)
636 		++n;
637 	if (n != 0)
638 		goto keyxchgfail;
639 
640 	/*
641 	 * Use separate session keys and session fixed IVs for receive and
642 	 * transmit.
643 	 */
644 	error = crypto_algos[DMSG_CRYPTO_ALGO].init(&iocom->ioq_rx,
645 	    (char*)handrx.sess,
646 	    crypto_algos[DMSG_CRYPTO_ALGO].keylen,
647 	    (char*)handrx.sess + crypto_algos[DMSG_CRYPTO_ALGO].keylen,
648 	    sizeof(handrx.sess) - crypto_algos[DMSG_CRYPTO_ALGO].keylen,
649 	    0 /* decryption */);
650 	if (error)
651 		goto keyxchgfail;
652 
653 	error = crypto_algos[DMSG_CRYPTO_ALGO].init(&iocom->ioq_tx,
654 	    (char*)handtx.sess,
655 	    crypto_algos[DMSG_CRYPTO_ALGO].keylen,
656 	    (char*)handtx.sess + crypto_algos[DMSG_CRYPTO_ALGO].keylen,
657 	    sizeof(handtx.sess) - crypto_algos[DMSG_CRYPTO_ALGO].keylen,
658 	    1 /* encryption */);
659 	if (error)
660 		goto keyxchgfail;
661 
662 	atomic_set_int(&iocom->flags, DMSG_IOCOMF_CRYPTED);
663 
664 	dmio_printf(iocom, 1, "auth success: %s\n", handrx.quickmsg);
665 done:
666 	if (path)
667 		free(path);
668 	if (keys[0])
669 		RSA_free(keys[0]);
670 	if (keys[1])
671 		RSA_free(keys[1]);
672 	if (keys[2])
673 		RSA_free(keys[2]);
674 }
675 
676 /*
677  * Decrypt pending data in the ioq's fifo.  The data is decrypted in-place.
678  */
679 void
680 dmsg_crypto_decrypt(dmsg_iocom_t *iocom __unused, dmsg_ioq_t *ioq)
681 {
682 	int p_len;
683 	int used;
684 	__unused int error;	/* XXX */
685 	char buf[512];
686 
687 	/*
688 	 * fifo_beg to fifo_cdx is data already decrypted.
689 	 * fifo_cdn to fifo_end is data not yet decrypted.
690 	 */
691 	p_len = ioq->fifo_end - ioq->fifo_cdn; /* data not yet decrypted */
692 
693 	if (p_len == 0)
694 		return;
695 
696 	while (p_len >= crypto_algos[DMSG_CRYPTO_ALGO].taglen +
697 	    DMSG_CRYPTO_CHUNK_SIZE) {
698 		bcopy(ioq->buf + ioq->fifo_cdn, buf,
699 		      crypto_algos[DMSG_CRYPTO_ALGO].taglen +
700 		      DMSG_CRYPTO_CHUNK_SIZE);
701 		error = crypto_algos[DMSG_CRYPTO_ALGO].dec_chunk(
702 		    ioq, buf,
703 		    ioq->buf + ioq->fifo_cdx,
704 		    DMSG_CRYPTO_CHUNK_SIZE,
705 		    &used);
706 #ifdef CRYPTO_DEBUG
707 		dmio_printf(iocom, 5,
708 			    "dec: p_len: %d, used: %d, "
709 			    "fifo_cdn: %ju, fifo_cdx: %ju\n",
710 			     p_len, used,
711 			     ioq->fifo_cdn, ioq->fifo_cdx);
712 #endif
713 		p_len -= used;
714 		ioq->fifo_cdn += used;
715 		ioq->fifo_cdx += DMSG_CRYPTO_CHUNK_SIZE;
716 #ifdef CRYPTO_DEBUG
717 		dmio_printf(iocom, 5,
718 			    "dec: p_len: %d, used: %d, "
719 			    "fifo_cdn: %ju, fifo_cdx: %ju\n",
720 			    p_len, used, ioq->fifo_cdn, ioq->fifo_cdx);
721 #endif
722 	}
723 }
724 
725 /*
726  * *nactp is set to the number of ORIGINAL bytes consumed by the encrypter.
727  * The FIFO may contain more data.
728  */
729 int
730 dmsg_crypto_encrypt(dmsg_iocom_t *iocom __unused, dmsg_ioq_t *ioq,
731 		    struct iovec *iov, int n, size_t *nactp)
732 {
733 	int p_len, used, ct_used;
734 	int i;
735 	__unused int error;	/* XXX */
736 	size_t nmax;
737 
738 	nmax = sizeof(ioq->buf) - ioq->fifo_end;	/* max new bytes */
739 
740 	*nactp = 0;
741 	for (i = 0; i < n && nmax; ++i) {
742 		used = 0;
743 		p_len = iov[i].iov_len;
744 		assert((p_len & DMSG_ALIGNMASK) == 0);
745 
746 		while (p_len >= DMSG_CRYPTO_CHUNK_SIZE &&
747 		    nmax >= DMSG_CRYPTO_CHUNK_SIZE +
748 		    (size_t)crypto_algos[DMSG_CRYPTO_ALGO].taglen) {
749 			error = crypto_algos[DMSG_CRYPTO_ALGO].enc_chunk(
750 			    ioq,
751 			    ioq->buf + ioq->fifo_cdx,
752 			    (char *)iov[i].iov_base + used,
753 			    DMSG_CRYPTO_CHUNK_SIZE, &ct_used);
754 #ifdef CRYPTO_DEBUG
755 			dmio_printf(iocom, 5,
756 				    "nactp: %ju, p_len: %d, "
757 				    "ct_used: %d, used: %d, nmax: %ju\n",
758 				    *nactp, p_len, ct_used, used, nmax);
759 #endif
760 
761 			*nactp += (size_t)DMSG_CRYPTO_CHUNK_SIZE;	/* plaintext count */
762 			used += DMSG_CRYPTO_CHUNK_SIZE;
763 			p_len -= DMSG_CRYPTO_CHUNK_SIZE;
764 
765 			/*
766 			 * NOTE: crypted count will eventually differ from
767 			 *	 nmax, but for now we have not yet introduced
768 			 *	 random armor.
769 			 */
770 			ioq->fifo_cdx += (size_t)ct_used;
771 			ioq->fifo_cdn += (size_t)ct_used;
772 			ioq->fifo_end += (size_t)ct_used;
773 			nmax -= (size_t)ct_used;
774 #ifdef CRYPTO_DEBUG
775 			dmio_printf(iocom, 5,
776 				    "nactp: %ju, p_len: %d, "
777 				    "ct_used: %d, used: %d, nmax: %ju\n",
778 				    *nactp, p_len, ct_used, used, nmax);
779 #endif
780 		}
781 	}
782 	iov[0].iov_base = ioq->buf + ioq->fifo_beg;
783 	iov[0].iov_len = ioq->fifo_cdx - ioq->fifo_beg;
784 
785 	return (1);
786 }
787