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