1*0cbfa66cSDaniel Fojt /* $OpenBSD: kex.h,v 1.109 2019/09/06 05:23:55 djm Exp $ */ 218de8d7fSPeter Avalos 318de8d7fSPeter Avalos /* 418de8d7fSPeter Avalos * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 518de8d7fSPeter Avalos * 618de8d7fSPeter Avalos * Redistribution and use in source and binary forms, with or without 718de8d7fSPeter Avalos * modification, are permitted provided that the following conditions 818de8d7fSPeter Avalos * are met: 918de8d7fSPeter Avalos * 1. Redistributions of source code must retain the above copyright 1018de8d7fSPeter Avalos * notice, this list of conditions and the following disclaimer. 1118de8d7fSPeter Avalos * 2. Redistributions in binary form must reproduce the above copyright 1218de8d7fSPeter Avalos * notice, this list of conditions and the following disclaimer in the 1318de8d7fSPeter Avalos * documentation and/or other materials provided with the distribution. 1418de8d7fSPeter Avalos * 1518de8d7fSPeter Avalos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 1618de8d7fSPeter Avalos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 1718de8d7fSPeter Avalos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 1818de8d7fSPeter Avalos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 1918de8d7fSPeter Avalos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2018de8d7fSPeter Avalos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2118de8d7fSPeter Avalos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2218de8d7fSPeter Avalos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2318de8d7fSPeter Avalos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2418de8d7fSPeter Avalos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2518de8d7fSPeter Avalos */ 2618de8d7fSPeter Avalos #ifndef KEX_H 2718de8d7fSPeter Avalos #define KEX_H 2818de8d7fSPeter Avalos 29e9778795SPeter Avalos #include "mac.h" 30664f4763Szrj #include "crypto_api.h" 31e9778795SPeter Avalos 32e9778795SPeter Avalos #ifdef WITH_OPENSSL 33*0cbfa66cSDaniel Fojt # include <openssl/bn.h> 34*0cbfa66cSDaniel Fojt # include <openssl/dh.h> 35*0cbfa66cSDaniel Fojt # include <openssl/ecdsa.h> 369f304aafSPeter Avalos # ifdef OPENSSL_HAS_ECC 379f304aafSPeter Avalos # include <openssl/ec.h> 38e9778795SPeter Avalos # else /* OPENSSL_HAS_ECC */ 39e9778795SPeter Avalos # define EC_KEY void 40e9778795SPeter Avalos # define EC_GROUP void 41e9778795SPeter Avalos # define EC_POINT void 42e9778795SPeter Avalos # endif /* OPENSSL_HAS_ECC */ 43e9778795SPeter Avalos #else /* WITH_OPENSSL */ 44664f4763Szrj # define DH void 45664f4763Szrj # define BIGNUM void 46e9778795SPeter Avalos # define EC_KEY void 47e9778795SPeter Avalos # define EC_GROUP void 48e9778795SPeter Avalos # define EC_POINT void 49e9778795SPeter Avalos #endif /* WITH_OPENSSL */ 5018de8d7fSPeter Avalos 5140c002afSPeter Avalos #define KEX_COOKIE_LEN 16 5240c002afSPeter Avalos 5318de8d7fSPeter Avalos #define KEX_DH1 "diffie-hellman-group1-sha1" 54e9778795SPeter Avalos #define KEX_DH14_SHA1 "diffie-hellman-group14-sha1" 55e9778795SPeter Avalos #define KEX_DH14_SHA256 "diffie-hellman-group14-sha256" 56e9778795SPeter Avalos #define KEX_DH16_SHA512 "diffie-hellman-group16-sha512" 57e9778795SPeter Avalos #define KEX_DH18_SHA512 "diffie-hellman-group18-sha512" 5818de8d7fSPeter Avalos #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" 5918de8d7fSPeter Avalos #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" 6036e94dc5SPeter Avalos #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" 6136e94dc5SPeter Avalos #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" 6236e94dc5SPeter Avalos #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" 63ce74bacaSMatthew Dillon #define KEX_CURVE25519_SHA256 "curve25519-sha256" 64ce74bacaSMatthew Dillon #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" 65664f4763Szrj #define KEX_SNTRUP4591761X25519_SHA512 "sntrup4591761x25519-sha512@tinyssh.org" 6618de8d7fSPeter Avalos 6718de8d7fSPeter Avalos #define COMP_NONE 0 68664f4763Szrj /* pre-auth compression (COMP_ZLIB) is only supported in the client */ 6918de8d7fSPeter Avalos #define COMP_ZLIB 1 7018de8d7fSPeter Avalos #define COMP_DELAYED 2 7118de8d7fSPeter Avalos 72e9778795SPeter Avalos #define CURVE25519_SIZE 32 73e9778795SPeter Avalos 7418de8d7fSPeter Avalos enum kex_init_proposals { 7518de8d7fSPeter Avalos PROPOSAL_KEX_ALGS, 7618de8d7fSPeter Avalos PROPOSAL_SERVER_HOST_KEY_ALGS, 7718de8d7fSPeter Avalos PROPOSAL_ENC_ALGS_CTOS, 7818de8d7fSPeter Avalos PROPOSAL_ENC_ALGS_STOC, 7918de8d7fSPeter Avalos PROPOSAL_MAC_ALGS_CTOS, 8018de8d7fSPeter Avalos PROPOSAL_MAC_ALGS_STOC, 8118de8d7fSPeter Avalos PROPOSAL_COMP_ALGS_CTOS, 8218de8d7fSPeter Avalos PROPOSAL_COMP_ALGS_STOC, 8318de8d7fSPeter Avalos PROPOSAL_LANG_CTOS, 8418de8d7fSPeter Avalos PROPOSAL_LANG_STOC, 8518de8d7fSPeter Avalos PROPOSAL_MAX 8618de8d7fSPeter Avalos }; 8718de8d7fSPeter Avalos 8818de8d7fSPeter Avalos enum kex_modes { 8918de8d7fSPeter Avalos MODE_IN, 9018de8d7fSPeter Avalos MODE_OUT, 9118de8d7fSPeter Avalos MODE_MAX 9218de8d7fSPeter Avalos }; 9318de8d7fSPeter Avalos 9418de8d7fSPeter Avalos enum kex_exchange { 9518de8d7fSPeter Avalos KEX_DH_GRP1_SHA1, 9618de8d7fSPeter Avalos KEX_DH_GRP14_SHA1, 97e9778795SPeter Avalos KEX_DH_GRP14_SHA256, 98e9778795SPeter Avalos KEX_DH_GRP16_SHA512, 99e9778795SPeter Avalos KEX_DH_GRP18_SHA512, 10018de8d7fSPeter Avalos KEX_DH_GEX_SHA1, 10118de8d7fSPeter Avalos KEX_DH_GEX_SHA256, 1029f304aafSPeter Avalos KEX_ECDH_SHA2, 10336e94dc5SPeter Avalos KEX_C25519_SHA256, 104664f4763Szrj KEX_KEM_SNTRUP4591761X25519_SHA512, 10518de8d7fSPeter Avalos KEX_MAX 10618de8d7fSPeter Avalos }; 10718de8d7fSPeter Avalos 10818de8d7fSPeter Avalos #define KEX_INIT_SENT 0x0001 109664f4763Szrj #define KEX_INITIAL 0x0002 11018de8d7fSPeter Avalos 111e9778795SPeter Avalos struct sshenc { 11218de8d7fSPeter Avalos char *name; 113e9778795SPeter Avalos const struct sshcipher *cipher; 11418de8d7fSPeter Avalos int enabled; 11518de8d7fSPeter Avalos u_int key_len; 11636e94dc5SPeter Avalos u_int iv_len; 11718de8d7fSPeter Avalos u_int block_size; 11818de8d7fSPeter Avalos u_char *key; 11918de8d7fSPeter Avalos u_char *iv; 12018de8d7fSPeter Avalos }; 121e9778795SPeter Avalos struct sshcomp { 122e9778795SPeter Avalos u_int type; 12318de8d7fSPeter Avalos int enabled; 12418de8d7fSPeter Avalos char *name; 12518de8d7fSPeter Avalos }; 126e9778795SPeter Avalos struct newkeys { 127e9778795SPeter Avalos struct sshenc enc; 128e9778795SPeter Avalos struct sshmac mac; 129e9778795SPeter Avalos struct sshcomp comp; 13018de8d7fSPeter Avalos }; 131e9778795SPeter Avalos 132e9778795SPeter Avalos struct ssh; 133e9778795SPeter Avalos 134e9778795SPeter Avalos struct kex { 13518de8d7fSPeter Avalos u_char *session_id; 136e9778795SPeter Avalos size_t session_id_len; 137e9778795SPeter Avalos struct newkeys *newkeys[MODE_MAX]; 13818de8d7fSPeter Avalos u_int we_need; 13936e94dc5SPeter Avalos u_int dh_need; 14018de8d7fSPeter Avalos int server; 14118de8d7fSPeter Avalos char *name; 142e9778795SPeter Avalos char *hostkey_alg; 14318de8d7fSPeter Avalos int hostkey_type; 144e9778795SPeter Avalos int hostkey_nid; 145e9778795SPeter Avalos u_int kex_type; 146664f4763Szrj char *server_sig_algs; 147e9778795SPeter Avalos int ext_info_c; 148e9778795SPeter Avalos struct sshbuf *my; 149e9778795SPeter Avalos struct sshbuf *peer; 150664f4763Szrj struct sshbuf *client_version; 151664f4763Szrj struct sshbuf *server_version; 15218de8d7fSPeter Avalos sig_atomic_t done; 153e9778795SPeter Avalos u_int flags; 15436e94dc5SPeter Avalos int hash_alg; 15536e94dc5SPeter Avalos int ec_nid; 156e9778795SPeter Avalos char *failed_choice; 157e9778795SPeter Avalos int (*verify_host_key)(struct sshkey *, struct ssh *); 158e9778795SPeter Avalos struct sshkey *(*load_host_public_key)(int, int, struct ssh *); 159e9778795SPeter Avalos struct sshkey *(*load_host_private_key)(int, int, struct ssh *); 160e9778795SPeter Avalos int (*host_key_index)(struct sshkey *, int, struct ssh *); 161664f4763Szrj int (*sign)(struct ssh *, struct sshkey *, struct sshkey *, 162664f4763Szrj u_char **, size_t *, const u_char *, size_t, const char *); 163e9778795SPeter Avalos int (*kex[KEX_MAX])(struct ssh *); 164e9778795SPeter Avalos /* kex specific state */ 165e9778795SPeter Avalos DH *dh; /* DH */ 166e9778795SPeter Avalos u_int min, max, nbits; /* GEX */ 167e9778795SPeter Avalos EC_KEY *ec_client_key; /* ECDH */ 168e9778795SPeter Avalos const EC_GROUP *ec_group; /* ECDH */ 169664f4763Szrj u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ 170e9778795SPeter Avalos u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ 171664f4763Szrj u_char sntrup4591761_client_key[crypto_kem_sntrup4591761_SECRETKEYBYTES]; /* KEM */ 172664f4763Szrj struct sshbuf *client_pub; 17318de8d7fSPeter Avalos }; 17418de8d7fSPeter Avalos 1759f304aafSPeter Avalos int kex_names_valid(const char *); 17636e94dc5SPeter Avalos char *kex_alg_list(char); 177e9778795SPeter Avalos char *kex_names_cat(const char *, const char *); 178664f4763Szrj int kex_assemble_names(char **, const char *, const char *); 1799f304aafSPeter Avalos 180664f4763Szrj int kex_exchange_identification(struct ssh *, int, const char *); 181664f4763Szrj 182664f4763Szrj struct kex *kex_new(void); 183664f4763Szrj int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); 184e9778795SPeter Avalos int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); 185e9778795SPeter Avalos void kex_free_newkeys(struct newkeys *); 186e9778795SPeter Avalos void kex_free(struct kex *); 18718de8d7fSPeter Avalos 188e9778795SPeter Avalos int kex_buf2prop(struct sshbuf *, int *, char ***); 189e9778795SPeter Avalos int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); 190e9778795SPeter Avalos void kex_prop_free(char **); 191664f4763Szrj int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); 192664f4763Szrj int kex_verify_host_key(struct ssh *, struct sshkey *); 19318de8d7fSPeter Avalos 194e9778795SPeter Avalos int kex_send_kexinit(struct ssh *); 195ce74bacaSMatthew Dillon int kex_input_kexinit(int, u_int32_t, struct ssh *); 196ce74bacaSMatthew Dillon int kex_input_ext_info(int, u_int32_t, struct ssh *); 197e9778795SPeter Avalos int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); 198e9778795SPeter Avalos int kex_send_newkeys(struct ssh *); 199e9778795SPeter Avalos int kex_start_rekex(struct ssh *); 20018de8d7fSPeter Avalos 201e9778795SPeter Avalos int kexgex_client(struct ssh *); 202e9778795SPeter Avalos int kexgex_server(struct ssh *); 203664f4763Szrj int kex_gen_client(struct ssh *); 204664f4763Szrj int kex_gen_server(struct ssh *); 20518de8d7fSPeter Avalos 206664f4763Szrj int kex_dh_keypair(struct kex *); 207664f4763Szrj int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 208664f4763Szrj struct sshbuf **); 209664f4763Szrj int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 21036e94dc5SPeter Avalos 211664f4763Szrj int kex_ecdh_keypair(struct kex *); 212664f4763Szrj int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 213664f4763Szrj struct sshbuf **); 214664f4763Szrj int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 215664f4763Szrj 216664f4763Szrj int kex_c25519_keypair(struct kex *); 217664f4763Szrj int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 218664f4763Szrj struct sshbuf **); 219664f4763Szrj int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 220664f4763Szrj 221664f4763Szrj int kex_kem_sntrup4591761x25519_keypair(struct kex *); 222664f4763Szrj int kex_kem_sntrup4591761x25519_enc(struct kex *, const struct sshbuf *, 223664f4763Szrj struct sshbuf **, struct sshbuf **); 224664f4763Szrj int kex_kem_sntrup4591761x25519_dec(struct kex *, const struct sshbuf *, 225664f4763Szrj struct sshbuf **); 226664f4763Szrj 227664f4763Szrj int kex_dh_keygen(struct kex *); 228664f4763Szrj int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); 229664f4763Szrj 230664f4763Szrj int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, 231664f4763Szrj const struct sshbuf *, const struct sshbuf *, const struct sshbuf *, 232e9778795SPeter Avalos int, int, int, 233e9778795SPeter Avalos const BIGNUM *, const BIGNUM *, const BIGNUM *, 234664f4763Szrj const BIGNUM *, const u_char *, size_t, 235e9778795SPeter Avalos u_char *, size_t *); 236e9778795SPeter Avalos 237e9778795SPeter Avalos void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) 23836e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 23936e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 240e9778795SPeter Avalos int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], 241e9778795SPeter Avalos const u_char pub[CURVE25519_SIZE], struct sshbuf *out) 24236e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 24336e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 244664f4763Szrj int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], 245664f4763Szrj const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) 246664f4763Szrj __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 247664f4763Szrj __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 24818de8d7fSPeter Avalos 2499f304aafSPeter Avalos #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 250664f4763Szrj void dump_digest(const char *, const u_char *, int); 25118de8d7fSPeter Avalos #endif 25218de8d7fSPeter Avalos 253e9778795SPeter Avalos #if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) 254e9778795SPeter Avalos # undef EC_KEY 255e9778795SPeter Avalos # undef EC_GROUP 256e9778795SPeter Avalos # undef EC_POINT 257e9778795SPeter Avalos #endif 258e9778795SPeter Avalos 25918de8d7fSPeter Avalos #endif 260