11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: kexecdhs.c,v 1.2 2010/09/22 05:01:29 djm Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2001 Markus Friedl. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2010 Damien Miller. All rights reserved. 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <signal.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "buffer.h" 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "key.h" 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "cipher.h" 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "kex.h" 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "packet.h" 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "dh.h" 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh2.h" 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef GSSAPI 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh-gss.h" 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "monitor_wrap.h" 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef OPENSSL_HAS_ECC 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <openssl/ecdh.h> 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkexecdh_server(Kex *kex) 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT *client_public; 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY *server_key; 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const EC_GROUP *group; 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BIGNUM *shared_secret; 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood Key *server_host_private, *server_host_public; 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *server_host_key_blob = NULL, *signature = NULL; 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *kbuf, *hash; 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int klen, slen, sbloblen, hashlen; 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int curve_nid; 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((curve_nid = kex_ecdh_name_to_nid(kex->name)) == -1) 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: unsupported ECDH curve \"%s\"", __func__, kex->name); 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((server_key = EC_KEY_new_by_curve_name(curve_nid)) == NULL) 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_new_by_curve_name failed", __func__); 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (EC_KEY_generate_key(server_key) != 1) 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_KEY_generate_key failed", __func__); 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood group = EC_KEY_get0_group(server_key); 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXECDH 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("server private key:\n", stderr); 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_dump_ec_key(server_key); 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->load_host_public_key == NULL || 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->load_host_private_key == NULL) 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Cannot load hostkey"); 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_public = kex->load_host_public_key(kex->hostkey_type); 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_public == NULL) 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Unsupported hostkey type %d", kex->hostkey_type); 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_private = kex->load_host_private_key(kex->hostkey_type); 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (server_host_private == NULL) 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("Missing private key for hostkey type %d", 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->hostkey_type); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("expecting SSH2_MSG_KEX_ECDH_INIT"); 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_read_expect(SSH2_MSG_KEX_ECDH_INIT); 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((client_public = EC_POINT_new(group)) == NULL) 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: EC_POINT_new failed", __func__); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_get_ecpoint(group, client_public); 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_check_eom(); 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (key_ec_validate_public(group, client_public) != 0) 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: invalid client public key", __func__); 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXECDH 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fputs("client public key:\n", stderr); 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_dump_ec_point(group, client_public); 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Calculate shared_secret */ 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood klen = (EC_GROUP_get_degree(group) + 7) / 8; 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kbuf = xmalloc(klen); 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ECDH_compute_key(kbuf, klen, client_public, 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_key, NULL) != (int)klen) 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: ECDH_compute_key failed", __func__); 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef DEBUG_KEXDH 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood dump_digest("shared secret", kbuf, klen); 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((shared_secret = BN_new()) == NULL) 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_new failed", __func__); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (BN_bin2bn(kbuf, klen, shared_secret) == NULL) 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: BN_bin2bn failed", __func__); 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memset(kbuf, 0, klen); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(kbuf); 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* calc H */ 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood key_to_blob(server_host_public, &server_host_key_blob, &sbloblen); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_ecdh_hash( 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->evp_md, 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood group, 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->client_version_string, 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->server_version_string, 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->peer), buffer_len(&kex->peer), 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buffer_ptr(&kex->my), buffer_len(&kex->my), 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood server_host_key_blob, sbloblen, 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood client_public, 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_get0_public_key(server_key), 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood shared_secret, 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood &hash, &hashlen 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ); 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_POINT_clear_free(client_public); 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* save session id := H */ 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (kex->session_id == NULL) { 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id_len = hashlen; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex->session_id = xmalloc(kex->session_id_len); 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(kex->session_id, hash, kex->session_id_len); 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* sign H */ 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (PRIVSEP(key_sign(server_host_private, &signature, &slen, 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hash, hashlen)) < 0) 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("kexdh_server: key_sign failed"); 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* destroy_sensitive_data(); */ 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* send server hostkey, ECDH pubkey 'Q_S' and signed H */ 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_start(SSH2_MSG_KEX_ECDH_REPLY); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(server_host_key_blob, sbloblen); 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_ecpoint(group, EC_KEY_get0_public_key(server_key)); 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_put_string(signature, slen); 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood packet_send(); 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(signature); 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(server_host_key_blob); 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* have keys, free server key */ 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood EC_KEY_free(server_key); 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_derive_keys(kex, hash, hashlen, shared_secret); 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood BN_clear_free(shared_secret); 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood kex_finish(kex); 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else /* OPENSSL_HAS_ECC */ 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodkexecdh_server(Kex *kex) 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("ECC support is not enabled"); 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif /* OPENSSL_HAS_ECC */ 174