1*ba1276acSMatthew Dillon /* $OpenBSD: kex.h,v 1.123 2024/05/17 00:30:23 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 330cbfa66cSDaniel Fojt # include <openssl/bn.h> 340cbfa66cSDaniel Fojt # include <openssl/dh.h> 350cbfa66cSDaniel 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" 6550a69bb5SSascha Wildner #define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com" 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 { 95*ba1276acSMatthew Dillon KEX_DH_GRP1_SHA1 = 1, 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, 10450a69bb5SSascha Wildner KEX_KEM_SNTRUP761X25519_SHA512, 10518de8d7fSPeter Avalos KEX_MAX 10618de8d7fSPeter Avalos }; 10718de8d7fSPeter Avalos 108ee116499SAntonio Huete Jimenez /* kex->flags */ 10918de8d7fSPeter Avalos #define KEX_INIT_SENT 0x0001 110664f4763Szrj #define KEX_INITIAL 0x0002 111ee116499SAntonio Huete Jimenez #define KEX_HAS_PUBKEY_HOSTBOUND 0x0004 112ee116499SAntonio Huete Jimenez #define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ 113ee116499SAntonio Huete Jimenez #define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ 114*ba1276acSMatthew Dillon #define KEX_HAS_PING 0x0020 115*ba1276acSMatthew Dillon #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 11618de8d7fSPeter Avalos 117e9778795SPeter Avalos struct sshenc { 11818de8d7fSPeter Avalos char *name; 119e9778795SPeter Avalos const struct sshcipher *cipher; 12018de8d7fSPeter Avalos int enabled; 12118de8d7fSPeter Avalos u_int key_len; 12236e94dc5SPeter Avalos u_int iv_len; 12318de8d7fSPeter Avalos u_int block_size; 12418de8d7fSPeter Avalos u_char *key; 12518de8d7fSPeter Avalos u_char *iv; 12618de8d7fSPeter Avalos }; 127e9778795SPeter Avalos struct sshcomp { 128e9778795SPeter Avalos u_int type; 12918de8d7fSPeter Avalos int enabled; 13018de8d7fSPeter Avalos char *name; 13118de8d7fSPeter Avalos }; 132e9778795SPeter Avalos struct newkeys { 133e9778795SPeter Avalos struct sshenc enc; 134e9778795SPeter Avalos struct sshmac mac; 135e9778795SPeter Avalos struct sshcomp comp; 13618de8d7fSPeter Avalos }; 137e9778795SPeter Avalos 138e9778795SPeter Avalos struct ssh; 139ee116499SAntonio Huete Jimenez struct sshbuf; 140e9778795SPeter Avalos 141e9778795SPeter Avalos struct kex { 142e9778795SPeter Avalos struct newkeys *newkeys[MODE_MAX]; 14318de8d7fSPeter Avalos u_int we_need; 14436e94dc5SPeter Avalos u_int dh_need; 14518de8d7fSPeter Avalos int server; 14618de8d7fSPeter Avalos char *name; 147e9778795SPeter Avalos char *hostkey_alg; 14818de8d7fSPeter Avalos int hostkey_type; 149e9778795SPeter Avalos int hostkey_nid; 150e9778795SPeter Avalos u_int kex_type; 151664f4763Szrj char *server_sig_algs; 152e9778795SPeter Avalos int ext_info_c; 153*ba1276acSMatthew Dillon int ext_info_s; 154*ba1276acSMatthew Dillon int kex_strict; 155*ba1276acSMatthew Dillon int ext_info_received; 156e9778795SPeter Avalos struct sshbuf *my; 157e9778795SPeter Avalos struct sshbuf *peer; 158664f4763Szrj struct sshbuf *client_version; 159664f4763Szrj struct sshbuf *server_version; 16050a69bb5SSascha Wildner struct sshbuf *session_id; 161ee116499SAntonio Huete Jimenez struct sshbuf *initial_sig; 162ee116499SAntonio Huete Jimenez struct sshkey *initial_hostkey; 16318de8d7fSPeter Avalos sig_atomic_t done; 164e9778795SPeter Avalos u_int flags; 16536e94dc5SPeter Avalos int hash_alg; 16636e94dc5SPeter Avalos int ec_nid; 167e9778795SPeter Avalos char *failed_choice; 168e9778795SPeter Avalos int (*verify_host_key)(struct sshkey *, struct ssh *); 169e9778795SPeter Avalos struct sshkey *(*load_host_public_key)(int, int, struct ssh *); 170e9778795SPeter Avalos struct sshkey *(*load_host_private_key)(int, int, struct ssh *); 171e9778795SPeter Avalos int (*host_key_index)(struct sshkey *, int, struct ssh *); 172664f4763Szrj int (*sign)(struct ssh *, struct sshkey *, struct sshkey *, 173664f4763Szrj u_char **, size_t *, const u_char *, size_t, const char *); 174e9778795SPeter Avalos int (*kex[KEX_MAX])(struct ssh *); 175e9778795SPeter Avalos /* kex specific state */ 176e9778795SPeter Avalos DH *dh; /* DH */ 177e9778795SPeter Avalos u_int min, max, nbits; /* GEX */ 178e9778795SPeter Avalos EC_KEY *ec_client_key; /* ECDH */ 179e9778795SPeter Avalos const EC_GROUP *ec_group; /* ECDH */ 180664f4763Szrj u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ 181e9778795SPeter Avalos u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ 18250a69bb5SSascha Wildner u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ 183664f4763Szrj struct sshbuf *client_pub; 18418de8d7fSPeter Avalos }; 18518de8d7fSPeter Avalos 186*ba1276acSMatthew Dillon int kex_name_valid(const char *); 187*ba1276acSMatthew Dillon u_int kex_type_from_name(const char *); 188*ba1276acSMatthew Dillon int kex_hash_from_name(const char *); 189*ba1276acSMatthew Dillon int kex_nid_from_name(const char *); 1909f304aafSPeter Avalos int kex_names_valid(const char *); 19136e94dc5SPeter Avalos char *kex_alg_list(char); 192e9778795SPeter Avalos char *kex_names_cat(const char *, const char *); 193*ba1276acSMatthew Dillon int kex_has_any_alg(const char *, const char *); 194664f4763Szrj int kex_assemble_names(char **, const char *, const char *); 195*ba1276acSMatthew Dillon void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], 196*ba1276acSMatthew Dillon const char *, const char *, const char *, const char *, const char *); 197*ba1276acSMatthew Dillon void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); 1989f304aafSPeter Avalos 199664f4763Szrj int kex_exchange_identification(struct ssh *, int, const char *); 200664f4763Szrj 201664f4763Szrj struct kex *kex_new(void); 202664f4763Szrj int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); 203e9778795SPeter Avalos int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); 204e9778795SPeter Avalos void kex_free_newkeys(struct newkeys *); 205e9778795SPeter Avalos void kex_free(struct kex *); 20618de8d7fSPeter Avalos 207e9778795SPeter Avalos int kex_buf2prop(struct sshbuf *, int *, char ***); 208e9778795SPeter Avalos int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); 209e9778795SPeter Avalos void kex_prop_free(char **); 210664f4763Szrj int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); 211664f4763Szrj int kex_verify_host_key(struct ssh *, struct sshkey *); 21218de8d7fSPeter Avalos 213e9778795SPeter Avalos int kex_send_kexinit(struct ssh *); 214ce74bacaSMatthew Dillon int kex_input_kexinit(int, u_int32_t, struct ssh *); 215ce74bacaSMatthew Dillon int kex_input_ext_info(int, u_int32_t, struct ssh *); 21650a69bb5SSascha Wildner int kex_protocol_error(int, u_int32_t, struct ssh *); 217e9778795SPeter Avalos int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); 218e9778795SPeter Avalos int kex_send_newkeys(struct ssh *); 219e9778795SPeter Avalos int kex_start_rekex(struct ssh *); 220*ba1276acSMatthew Dillon int kex_server_update_ext_info(struct ssh *); 221*ba1276acSMatthew Dillon void kex_set_server_sig_algs(struct ssh *, const char *); 22218de8d7fSPeter Avalos 223e9778795SPeter Avalos int kexgex_client(struct ssh *); 224e9778795SPeter Avalos int kexgex_server(struct ssh *); 225664f4763Szrj int kex_gen_client(struct ssh *); 226664f4763Szrj int kex_gen_server(struct ssh *); 22718de8d7fSPeter Avalos 228664f4763Szrj int kex_dh_keypair(struct kex *); 229664f4763Szrj int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 230664f4763Szrj struct sshbuf **); 231664f4763Szrj int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 23236e94dc5SPeter Avalos 233664f4763Szrj int kex_ecdh_keypair(struct kex *); 234664f4763Szrj int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 235664f4763Szrj struct sshbuf **); 236664f4763Szrj int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 237664f4763Szrj 238664f4763Szrj int kex_c25519_keypair(struct kex *); 239664f4763Szrj int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 240664f4763Szrj struct sshbuf **); 241664f4763Szrj int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 242664f4763Szrj 24350a69bb5SSascha Wildner int kex_kem_sntrup761x25519_keypair(struct kex *); 24450a69bb5SSascha Wildner int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *, 245664f4763Szrj struct sshbuf **, struct sshbuf **); 24650a69bb5SSascha Wildner int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *, 247664f4763Szrj struct sshbuf **); 248664f4763Szrj 249664f4763Szrj int kex_dh_keygen(struct kex *); 250664f4763Szrj int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); 251664f4763Szrj 252664f4763Szrj int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, 253664f4763Szrj const struct sshbuf *, const struct sshbuf *, const struct sshbuf *, 254e9778795SPeter Avalos int, int, int, 255e9778795SPeter Avalos const BIGNUM *, const BIGNUM *, const BIGNUM *, 256664f4763Szrj const BIGNUM *, const u_char *, size_t, 257e9778795SPeter Avalos u_char *, size_t *); 258e9778795SPeter Avalos 259e9778795SPeter Avalos void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) 26036e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 26136e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 262e9778795SPeter Avalos int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], 263e9778795SPeter Avalos const u_char pub[CURVE25519_SIZE], struct sshbuf *out) 26436e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 26536e94dc5SPeter Avalos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 266664f4763Szrj int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], 267664f4763Szrj const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) 268664f4763Szrj __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 269664f4763Szrj __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 27018de8d7fSPeter Avalos 2719f304aafSPeter Avalos #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 272664f4763Szrj void dump_digest(const char *, const u_char *, int); 27318de8d7fSPeter Avalos #endif 27418de8d7fSPeter Avalos 275e9778795SPeter Avalos #if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) 276e9778795SPeter Avalos # undef EC_KEY 277e9778795SPeter Avalos # undef EC_GROUP 278e9778795SPeter Avalos # undef EC_POINT 279e9778795SPeter Avalos #endif 280e9778795SPeter Avalos 28118de8d7fSPeter Avalos #endif 282