1261287Sdes/* $OpenBSD: kexc25519c.c,v 1.4 2014/01/12 08:13:13 djm Exp $ */ 2261287Sdes/* 3261287Sdes * Copyright (c) 2001 Markus Friedl. All rights reserved. 4261287Sdes * Copyright (c) 2010 Damien Miller. All rights reserved. 5261287Sdes * Copyright (c) 2013 Aris Adamantiadis. All rights reserved. 6261287Sdes * 7261287Sdes * Redistribution and use in source and binary forms, with or without 8261287Sdes * modification, are permitted provided that the following conditions 9261287Sdes * are met: 10261287Sdes * 1. Redistributions of source code must retain the above copyright 11261287Sdes * notice, this list of conditions and the following disclaimer. 12261287Sdes * 2. Redistributions in binary form must reproduce the above copyright 13261287Sdes * notice, this list of conditions and the following disclaimer in the 14261287Sdes * documentation and/or other materials provided with the distribution. 15261287Sdes * 16261287Sdes * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17261287Sdes * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18261287Sdes * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19261287Sdes * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20261287Sdes * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21261287Sdes * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22261287Sdes * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23261287Sdes * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24261287Sdes * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25261287Sdes * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26261287Sdes */ 27261287Sdes 28261287Sdes#include "includes.h" 29261287Sdes 30261287Sdes#include <sys/types.h> 31261287Sdes 32261287Sdes#include <stdio.h> 33261287Sdes#include <string.h> 34261287Sdes#include <signal.h> 35261287Sdes 36261287Sdes#include "xmalloc.h" 37261287Sdes#include "buffer.h" 38261287Sdes#include "key.h" 39261287Sdes#include "cipher.h" 40261287Sdes#include "kex.h" 41261287Sdes#include "log.h" 42261287Sdes#include "packet.h" 43261287Sdes#include "ssh2.h" 44261287Sdes 45261287Sdesvoid 46261287Sdeskexc25519_client(Kex *kex) 47261287Sdes{ 48261287Sdes Key *server_host_key; 49261287Sdes u_char client_key[CURVE25519_SIZE]; 50261287Sdes u_char client_pubkey[CURVE25519_SIZE]; 51261287Sdes u_char *server_pubkey = NULL; 52261287Sdes u_char *server_host_key_blob = NULL, *signature = NULL; 53261287Sdes u_char *hash; 54261287Sdes u_int slen, sbloblen, hashlen; 55261287Sdes Buffer shared_secret; 56261287Sdes 57261287Sdes kexc25519_keygen(client_key, client_pubkey); 58261287Sdes 59261287Sdes packet_start(SSH2_MSG_KEX_ECDH_INIT); 60261287Sdes packet_put_string(client_pubkey, sizeof(client_pubkey)); 61261287Sdes packet_send(); 62261287Sdes debug("sending SSH2_MSG_KEX_ECDH_INIT"); 63261287Sdes 64261287Sdes#ifdef DEBUG_KEXECDH 65261287Sdes dump_digest("client private key:", client_key, sizeof(client_key)); 66261287Sdes#endif 67261287Sdes 68261287Sdes debug("expecting SSH2_MSG_KEX_ECDH_REPLY"); 69261287Sdes packet_read_expect(SSH2_MSG_KEX_ECDH_REPLY); 70261287Sdes 71261287Sdes /* hostkey */ 72261287Sdes server_host_key_blob = packet_get_string(&sbloblen); 73261287Sdes server_host_key = key_from_blob(server_host_key_blob, sbloblen); 74261287Sdes if (server_host_key == NULL) 75261287Sdes fatal("cannot decode server_host_key_blob"); 76261287Sdes if (server_host_key->type != kex->hostkey_type) 77261287Sdes fatal("type mismatch for decoded server_host_key_blob"); 78261287Sdes if (kex->verify_host_key == NULL) 79261287Sdes fatal("cannot verify server_host_key"); 80261287Sdes if (kex->verify_host_key(server_host_key) == -1) 81261287Sdes fatal("server_host_key verification failed"); 82261287Sdes 83261287Sdes /* Q_S, server public key */ 84261287Sdes server_pubkey = packet_get_string(&slen); 85261287Sdes if (slen != CURVE25519_SIZE) 86261287Sdes fatal("Incorrect size for server Curve25519 pubkey: %d", slen); 87261287Sdes 88261287Sdes#ifdef DEBUG_KEXECDH 89261287Sdes dump_digest("server public key:", server_pubkey, CURVE25519_SIZE); 90261287Sdes#endif 91261287Sdes 92261287Sdes /* signed H */ 93261287Sdes signature = packet_get_string(&slen); 94261287Sdes packet_check_eom(); 95261287Sdes 96261287Sdes buffer_init(&shared_secret); 97261287Sdes kexc25519_shared_key(client_key, server_pubkey, &shared_secret); 98261287Sdes 99261287Sdes /* calc and verify H */ 100261287Sdes kex_c25519_hash( 101261287Sdes kex->hash_alg, 102261287Sdes kex->client_version_string, 103261287Sdes kex->server_version_string, 104261287Sdes buffer_ptr(&kex->my), buffer_len(&kex->my), 105261287Sdes buffer_ptr(&kex->peer), buffer_len(&kex->peer), 106261287Sdes server_host_key_blob, sbloblen, 107261287Sdes client_pubkey, 108261287Sdes server_pubkey, 109261287Sdes buffer_ptr(&shared_secret), buffer_len(&shared_secret), 110261287Sdes &hash, &hashlen 111261287Sdes ); 112261287Sdes free(server_host_key_blob); 113261287Sdes free(server_pubkey); 114261287Sdes if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1) 115261287Sdes fatal("key_verify failed for server_host_key"); 116261287Sdes key_free(server_host_key); 117261287Sdes free(signature); 118261287Sdes 119261287Sdes /* save session id */ 120261287Sdes if (kex->session_id == NULL) { 121261287Sdes kex->session_id_len = hashlen; 122261287Sdes kex->session_id = xmalloc(kex->session_id_len); 123261287Sdes memcpy(kex->session_id, hash, kex->session_id_len); 124261287Sdes } 125261287Sdes kex_derive_keys(kex, hash, hashlen, 126261287Sdes buffer_ptr(&shared_secret), buffer_len(&shared_secret)); 127261287Sdes buffer_free(&shared_secret); 128261287Sdes kex_finish(kex); 129261287Sdes} 130