1*9469f4f1Schristos /* $NetBSD: kex.h,v 1.27 2024/09/24 21:32:18 christos Exp $ */ 2*9469f4f1Schristos /* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */ 3ca32bd8dSchristos 4ca32bd8dSchristos /* 5ca32bd8dSchristos * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 6ca32bd8dSchristos * 7ca32bd8dSchristos * Redistribution and use in source and binary forms, with or without 8ca32bd8dSchristos * modification, are permitted provided that the following conditions 9ca32bd8dSchristos * are met: 10ca32bd8dSchristos * 1. Redistributions of source code must retain the above copyright 11ca32bd8dSchristos * notice, this list of conditions and the following disclaimer. 12ca32bd8dSchristos * 2. Redistributions in binary form must reproduce the above copyright 13ca32bd8dSchristos * notice, this list of conditions and the following disclaimer in the 14ca32bd8dSchristos * documentation and/or other materials provided with the distribution. 15ca32bd8dSchristos * 16ca32bd8dSchristos * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17ca32bd8dSchristos * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18ca32bd8dSchristos * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19ca32bd8dSchristos * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20ca32bd8dSchristos * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21ca32bd8dSchristos * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22ca32bd8dSchristos * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23ca32bd8dSchristos * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24ca32bd8dSchristos * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25ca32bd8dSchristos * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26ca32bd8dSchristos */ 27ca32bd8dSchristos #ifndef KEX_H 28ca32bd8dSchristos #define KEX_H 29ca32bd8dSchristos 30e4d43b82Schristos #include "mac.h" 31aa36fcacSchristos #include "crypto_api.h" 32e4d43b82Schristos 33cd4ada6aSchristos #ifdef WITH_OPENSSL 34cd4ada6aSchristos #include <openssl/bn.h> 35cd4ada6aSchristos #include <openssl/dh.h> 36cd4ada6aSchristos #include <openssl/ec.h> 37cd4ada6aSchristos #include <openssl/ecdsa.h> 38cd4ada6aSchristos #else /* OPENSSL */ 39cd4ada6aSchristos #define BIGNUM void 40cd4ada6aSchristos #define DH void 41cd4ada6aSchristos #define EC_KEY void 42cd4ada6aSchristos #define EC_GROUP void 43cd4ada6aSchristos #endif /* WITH_OPENSSL */ 44ca32bd8dSchristos 4547dc7704Schristos #define KEX_COOKIE_LEN 16 4647dc7704Schristos 47ca32bd8dSchristos #define KEX_DH1 "diffie-hellman-group1-sha1" 485101d403Schristos #define KEX_DH14_SHA1 "diffie-hellman-group14-sha1" 495101d403Schristos #define KEX_DH14_SHA256 "diffie-hellman-group14-sha256" 505101d403Schristos #define KEX_DH16_SHA512 "diffie-hellman-group16-sha512" 515101d403Schristos #define KEX_DH18_SHA512 "diffie-hellman-group18-sha512" 52ca32bd8dSchristos #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" 53ca32bd8dSchristos #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" 5400a838c4Schristos #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" 5500a838c4Schristos #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" 5600a838c4Schristos #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" 57ee85abc4Schristos #define KEX_CURVE25519_SHA256 "curve25519-sha256" 58ee85abc4Schristos #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" 59*9469f4f1Schristos #define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512" 60*9469f4f1Schristos #define KEX_SNTRUP761X25519_SHA512_OLD "sntrup761x25519-sha512@openssh.com" 61*9469f4f1Schristos #define KEX_MLKEM768X25519_SHA256 "mlkem768x25519-sha256" 62ca32bd8dSchristos 63ca32bd8dSchristos #define COMP_NONE 0 64ca32bd8dSchristos #define COMP_DELAYED 2 65ca32bd8dSchristos 66e4d43b82Schristos #define CURVE25519_SIZE 32 67e4d43b82Schristos 68ca32bd8dSchristos enum kex_init_proposals { 69ca32bd8dSchristos PROPOSAL_KEX_ALGS, 70ca32bd8dSchristos PROPOSAL_SERVER_HOST_KEY_ALGS, 71ca32bd8dSchristos PROPOSAL_ENC_ALGS_CTOS, 72ca32bd8dSchristos PROPOSAL_ENC_ALGS_STOC, 73ca32bd8dSchristos PROPOSAL_MAC_ALGS_CTOS, 74ca32bd8dSchristos PROPOSAL_MAC_ALGS_STOC, 75ca32bd8dSchristos PROPOSAL_COMP_ALGS_CTOS, 76ca32bd8dSchristos PROPOSAL_COMP_ALGS_STOC, 77ca32bd8dSchristos PROPOSAL_LANG_CTOS, 78ca32bd8dSchristos PROPOSAL_LANG_STOC, 79ca32bd8dSchristos PROPOSAL_MAX 80ca32bd8dSchristos }; 81ca32bd8dSchristos 82ca32bd8dSchristos enum kex_modes { 83ca32bd8dSchristos MODE_IN, 84ca32bd8dSchristos MODE_OUT, 85ca32bd8dSchristos MODE_MAX 86ca32bd8dSchristos }; 87ca32bd8dSchristos 88ca32bd8dSchristos enum kex_exchange { 891c7715ddSchristos KEX_DH_GRP1_SHA1 = 1, 90ca32bd8dSchristos KEX_DH_GRP14_SHA1, 915101d403Schristos KEX_DH_GRP14_SHA256, 925101d403Schristos KEX_DH_GRP16_SHA512, 935101d403Schristos KEX_DH_GRP18_SHA512, 94ca32bd8dSchristos KEX_DH_GEX_SHA1, 95ca32bd8dSchristos KEX_DH_GEX_SHA256, 96185c8f97Schristos KEX_ECDH_SHA2, 978a4530f9Schristos KEX_C25519_SHA256, 9817418e98Schristos KEX_KEM_SNTRUP761X25519_SHA512, 99*9469f4f1Schristos KEX_KEM_MLKEM768X25519_SHA256, 100ca32bd8dSchristos KEX_MAX 101ca32bd8dSchristos }; 102ca32bd8dSchristos 103a03ec00cSchristos /* kex->flags */ 104ca32bd8dSchristos #define KEX_INIT_SENT 0x0001 105aa36fcacSchristos #define KEX_INITIAL 0x0002 106a03ec00cSchristos #define KEX_HAS_PUBKEY_HOSTBOUND 0x0004 107a03ec00cSchristos #define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ 108a03ec00cSchristos #define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ 109a629fefcSchristos #define KEX_HAS_PING 0x0020 110514b5d45Schristos #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 111ca32bd8dSchristos 112e4d43b82Schristos struct sshenc { 113ca32bd8dSchristos char *name; 114e4d43b82Schristos const struct sshcipher *cipher; 115ca32bd8dSchristos int enabled; 116ca32bd8dSchristos u_int key_len; 117ce11a51fSchristos u_int iv_len; 118ca32bd8dSchristos u_int block_size; 119ca32bd8dSchristos u_char *key; 120ca32bd8dSchristos u_char *iv; 121ca32bd8dSchristos }; 122e4d43b82Schristos struct sshcomp { 123e4d43b82Schristos u_int type; 124ca32bd8dSchristos int enabled; 125ca32bd8dSchristos char *name; 126ca32bd8dSchristos }; 127e4d43b82Schristos struct newkeys { 128e4d43b82Schristos struct sshenc enc; 129e4d43b82Schristos struct sshmac mac; 130e4d43b82Schristos struct sshcomp comp; 131ca32bd8dSchristos }; 132e4d43b82Schristos 133e4d43b82Schristos struct ssh; 134a03ec00cSchristos struct sshbuf; 135e4d43b82Schristos 136e4d43b82Schristos struct kex { 137e4d43b82Schristos struct newkeys *newkeys[MODE_MAX]; 138ca32bd8dSchristos u_int we_need; 1398a4530f9Schristos u_int dh_need; 140ca32bd8dSchristos int server; 141ca32bd8dSchristos char *name; 14279976551Schristos char *hostkey_alg; 143ca32bd8dSchristos int hostkey_type; 144e4d43b82Schristos int hostkey_nid; 145e4d43b82Schristos u_int kex_type; 14655a4608bSchristos char *server_sig_algs; 14779976551Schristos int ext_info_c; 148514b5d45Schristos int ext_info_s; 149514b5d45Schristos int kex_strict; 150514b5d45Schristos int ext_info_received; 151e4d43b82Schristos struct sshbuf *my; 152e4d43b82Schristos struct sshbuf *peer; 153aa36fcacSchristos struct sshbuf *client_version; 154aa36fcacSchristos struct sshbuf *server_version; 15517418e98Schristos struct sshbuf *session_id; 156a03ec00cSchristos struct sshbuf *initial_sig; 157a03ec00cSchristos struct sshkey *initial_hostkey; 158ca32bd8dSchristos sig_atomic_t done; 159e4d43b82Schristos u_int flags; 1608a4530f9Schristos int hash_alg; 16100a838c4Schristos int ec_nid; 1628395c133Schristos char *failed_choice; 163e4d43b82Schristos int (*verify_host_key)(struct sshkey *, struct ssh *); 164e4d43b82Schristos struct sshkey *(*load_host_public_key)(int, int, struct ssh *); 165e4d43b82Schristos struct sshkey *(*load_host_private_key)(int, int, struct ssh *); 166e4d43b82Schristos int (*host_key_index)(struct sshkey *, int, struct ssh *); 167aa36fcacSchristos int (*sign)(struct ssh *, struct sshkey *, struct sshkey *, 168aa36fcacSchristos u_char **, size_t *, const u_char *, size_t, const char *); 169e4d43b82Schristos int (*kex[KEX_MAX])(struct ssh *); 170e4d43b82Schristos /* kex specific state */ 171e4d43b82Schristos DH *dh; /* DH */ 172e4d43b82Schristos u_int min, max, nbits; /* GEX */ 173e4d43b82Schristos EC_KEY *ec_client_key; /* ECDH */ 174e4d43b82Schristos const EC_GROUP *ec_group; /* ECDH */ 175aa36fcacSchristos u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ 176e4d43b82Schristos u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ 17717418e98Schristos u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ 178*9469f4f1Schristos u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */ 179aa36fcacSchristos struct sshbuf *client_pub; 180ca32bd8dSchristos }; 181ca32bd8dSchristos 1821c7715ddSchristos int kex_name_valid(const char *); 1831c7715ddSchristos u_int kex_type_from_name(const char *); 1841c7715ddSchristos int kex_hash_from_name(const char *); 1851c7715ddSchristos int kex_nid_from_name(const char *); 186185c8f97Schristos int kex_names_valid(const char *); 1878a4530f9Schristos char *kex_alg_list(char); 1888395c133Schristos char *kex_names_cat(const char *, const char *); 1891c7715ddSchristos int kex_has_any_alg(const char *, const char *); 19055a4608bSchristos int kex_assemble_names(char **, const char *, const char *); 191b1066cf3Schristos void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], 192b1066cf3Schristos const char *, const char *, const char *, const char *, const char *); 193b1066cf3Schristos void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); 194185c8f97Schristos 195aa36fcacSchristos int kex_exchange_identification(struct ssh *, int, const char *); 196aa36fcacSchristos 197aa36fcacSchristos struct kex *kex_new(void); 198b1066cf3Schristos int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); 199b1066cf3Schristos int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); 200e4d43b82Schristos void kex_free_newkeys(struct newkeys *); 201e4d43b82Schristos void kex_free(struct kex *); 202ca32bd8dSchristos 203e4d43b82Schristos int kex_buf2prop(struct sshbuf *, int *, char ***); 204b1066cf3Schristos int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); 205e4d43b82Schristos void kex_prop_free(char **); 206aa36fcacSchristos int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); 207aa36fcacSchristos int kex_verify_host_key(struct ssh *, struct sshkey *); 208ca32bd8dSchristos 209e4d43b82Schristos int kex_send_kexinit(struct ssh *); 2107a183406Schristos int kex_input_kexinit(int, u_int32_t, struct ssh *); 2117a183406Schristos int kex_input_ext_info(int, u_int32_t, struct ssh *); 21217418e98Schristos int kex_protocol_error(int, u_int32_t, struct ssh *); 213e4d43b82Schristos int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); 214e4d43b82Schristos int kex_send_newkeys(struct ssh *); 21579976551Schristos int kex_start_rekex(struct ssh *); 216514b5d45Schristos int kex_server_update_ext_info(struct ssh *); 217514b5d45Schristos void kex_set_server_sig_algs(struct ssh *, const char *); 218ca32bd8dSchristos 219e4d43b82Schristos int kexgex_client(struct ssh *); 220e4d43b82Schristos int kexgex_server(struct ssh *); 221aa36fcacSchristos int kex_gen_client(struct ssh *); 222aa36fcacSchristos int kex_gen_server(struct ssh *); 223ca32bd8dSchristos 224aa36fcacSchristos int kex_dh_keypair(struct kex *); 225aa36fcacSchristos int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 226aa36fcacSchristos struct sshbuf **); 227aa36fcacSchristos int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 2288a4530f9Schristos 229aa36fcacSchristos int kex_ecdh_keypair(struct kex *); 230aa36fcacSchristos int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 231aa36fcacSchristos struct sshbuf **); 232aa36fcacSchristos int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 233aa36fcacSchristos 234aa36fcacSchristos int kex_c25519_keypair(struct kex *); 235aa36fcacSchristos int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 236aa36fcacSchristos struct sshbuf **); 237aa36fcacSchristos int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 238aa36fcacSchristos 23917418e98Schristos int kex_kem_sntrup761x25519_keypair(struct kex *); 24017418e98Schristos int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *, 241aa36fcacSchristos struct sshbuf **, struct sshbuf **); 24217418e98Schristos int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *, 243aa36fcacSchristos struct sshbuf **); 244aa36fcacSchristos 245*9469f4f1Schristos int kex_kem_mlkem768x25519_keypair(struct kex *); 246*9469f4f1Schristos int kex_kem_mlkem768x25519_enc(struct kex *, const struct sshbuf *, 247*9469f4f1Schristos struct sshbuf **, struct sshbuf **); 248*9469f4f1Schristos int kex_kem_mlkem768x25519_dec(struct kex *, const struct sshbuf *, 249*9469f4f1Schristos struct sshbuf **); 250*9469f4f1Schristos 251aa36fcacSchristos int kex_dh_keygen(struct kex *); 252aa36fcacSchristos int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); 253aa36fcacSchristos 254aa36fcacSchristos int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, 255aa36fcacSchristos const struct sshbuf *, const struct sshbuf *, const struct sshbuf *, 256e4d43b82Schristos int, int, int, 257e4d43b82Schristos const BIGNUM *, const BIGNUM *, const BIGNUM *, 258aa36fcacSchristos const BIGNUM *, const u_char *, size_t, 259e4d43b82Schristos u_char *, size_t *); 260e4d43b82Schristos 261e4d43b82Schristos void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) 2628a4530f9Schristos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 2638a4530f9Schristos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 264e4d43b82Schristos int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], 265e4d43b82Schristos const u_char pub[CURVE25519_SIZE], struct sshbuf *out) 2668a4530f9Schristos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 2678a4530f9Schristos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 268aa36fcacSchristos int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], 269aa36fcacSchristos const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) 270aa36fcacSchristos __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 271aa36fcacSchristos __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 272185c8f97Schristos 273185c8f97Schristos #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 274aa36fcacSchristos void dump_digest(const char *, const u_char *, int); 275ca32bd8dSchristos #endif 276ca32bd8dSchristos 277ca32bd8dSchristos #endif 278