1*3d9fd9fcSEd Maste /* $OpenBSD: kex.h,v 1.126 2024/09/02 12:13:56 djm Exp $ */ 21e8db6e2SBrian Feldman 3a04a10f8SKris Kennaway /* 4ae1f160dSDag-Erling Smørgrav * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. 5a04a10f8SKris Kennaway * 6a04a10f8SKris Kennaway * Redistribution and use in source and binary forms, with or without 7a04a10f8SKris Kennaway * modification, are permitted provided that the following conditions 8a04a10f8SKris Kennaway * are met: 9a04a10f8SKris Kennaway * 1. Redistributions of source code must retain the above copyright 10a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer. 11a04a10f8SKris Kennaway * 2. Redistributions in binary form must reproduce the above copyright 12a04a10f8SKris Kennaway * notice, this list of conditions and the following disclaimer in the 13a04a10f8SKris Kennaway * documentation and/or other materials provided with the distribution. 14a04a10f8SKris Kennaway * 15a04a10f8SKris Kennaway * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16a04a10f8SKris Kennaway * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17a04a10f8SKris Kennaway * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18a04a10f8SKris Kennaway * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19a04a10f8SKris Kennaway * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20a04a10f8SKris Kennaway * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21a04a10f8SKris Kennaway * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22a04a10f8SKris Kennaway * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23a04a10f8SKris Kennaway * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24a04a10f8SKris Kennaway * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25a04a10f8SKris Kennaway */ 26a04a10f8SKris Kennaway #ifndef KEX_H 27a04a10f8SKris Kennaway #define KEX_H 28a04a10f8SKris Kennaway 29bc5531deSDag-Erling Smørgrav #include "mac.h" 3019261079SEd Maste #include "crypto_api.h" 31bc5531deSDag-Erling Smørgrav 32bc5531deSDag-Erling Smørgrav #ifdef WITH_OPENSSL 3319261079SEd Maste # include <openssl/bn.h> 3419261079SEd Maste # include <openssl/dh.h> 3519261079SEd Maste # include <openssl/ecdsa.h> 364a421b63SDag-Erling Smørgrav # ifdef OPENSSL_HAS_ECC 374a421b63SDag-Erling Smørgrav # include <openssl/ec.h> 38bc5531deSDag-Erling Smørgrav # else /* OPENSSL_HAS_ECC */ 39bc5531deSDag-Erling Smørgrav # define EC_KEY void 40bc5531deSDag-Erling Smørgrav # define EC_GROUP void 41bc5531deSDag-Erling Smørgrav # define EC_POINT void 42bc5531deSDag-Erling Smørgrav # endif /* OPENSSL_HAS_ECC */ 43bc5531deSDag-Erling Smørgrav #else /* WITH_OPENSSL */ 44190cef3dSDag-Erling Smørgrav # define DH void 45190cef3dSDag-Erling Smørgrav # define BIGNUM void 46bc5531deSDag-Erling Smørgrav # define EC_KEY void 47bc5531deSDag-Erling Smørgrav # define EC_GROUP void 48bc5531deSDag-Erling Smørgrav # define EC_POINT void 49bc5531deSDag-Erling Smørgrav #endif /* WITH_OPENSSL */ 501e8db6e2SBrian Feldman 517aee6ffeSDag-Erling Smørgrav #define KEX_COOKIE_LEN 16 527aee6ffeSDag-Erling Smørgrav 53a04a10f8SKris Kennaway #define KEX_DH1 "diffie-hellman-group1-sha1" 54076ad2f8SDag-Erling Smørgrav #define KEX_DH14_SHA1 "diffie-hellman-group14-sha1" 55076ad2f8SDag-Erling Smørgrav #define KEX_DH14_SHA256 "diffie-hellman-group14-sha256" 56076ad2f8SDag-Erling Smørgrav #define KEX_DH16_SHA512 "diffie-hellman-group16-sha512" 57076ad2f8SDag-Erling Smørgrav #define KEX_DH18_SHA512 "diffie-hellman-group18-sha512" 58021d409fSDag-Erling Smørgrav #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" 59761efaa7SDag-Erling Smørgrav #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" 60e4a9863fSDag-Erling Smørgrav #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" 61e4a9863fSDag-Erling Smørgrav #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" 62e4a9863fSDag-Erling Smørgrav #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" 63ca86bcf2SDag-Erling Smørgrav #define KEX_CURVE25519_SHA256 "curve25519-sha256" 64ca86bcf2SDag-Erling Smørgrav #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" 65*3d9fd9fcSEd Maste #define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512" 66*3d9fd9fcSEd Maste #define KEX_SNTRUP761X25519_SHA512_OLD "sntrup761x25519-sha512@openssh.com" 67*3d9fd9fcSEd Maste #define KEX_MLKEM768X25519_SHA256 "mlkem768x25519-sha256" 68a04a10f8SKris Kennaway 69043840dfSDag-Erling Smørgrav #define COMP_NONE 0 70043840dfSDag-Erling Smørgrav #define COMP_DELAYED 2 71043840dfSDag-Erling Smørgrav 72bc5531deSDag-Erling Smørgrav #define CURVE25519_SIZE 32 73bc5531deSDag-Erling Smørgrav 74a04a10f8SKris Kennaway enum kex_init_proposals { 75a04a10f8SKris Kennaway PROPOSAL_KEX_ALGS, 76a04a10f8SKris Kennaway PROPOSAL_SERVER_HOST_KEY_ALGS, 77a04a10f8SKris Kennaway PROPOSAL_ENC_ALGS_CTOS, 78a04a10f8SKris Kennaway PROPOSAL_ENC_ALGS_STOC, 79a04a10f8SKris Kennaway PROPOSAL_MAC_ALGS_CTOS, 80a04a10f8SKris Kennaway PROPOSAL_MAC_ALGS_STOC, 81a04a10f8SKris Kennaway PROPOSAL_COMP_ALGS_CTOS, 82a04a10f8SKris Kennaway PROPOSAL_COMP_ALGS_STOC, 83a04a10f8SKris Kennaway PROPOSAL_LANG_CTOS, 84a04a10f8SKris Kennaway PROPOSAL_LANG_STOC, 85a04a10f8SKris Kennaway PROPOSAL_MAX 86a04a10f8SKris Kennaway }; 87a04a10f8SKris Kennaway 88a04a10f8SKris Kennaway enum kex_modes { 89a04a10f8SKris Kennaway MODE_IN, 90a04a10f8SKris Kennaway MODE_OUT, 91a04a10f8SKris Kennaway MODE_MAX 92a04a10f8SKris Kennaway }; 93a04a10f8SKris Kennaway 945b9b2fafSBrian Feldman enum kex_exchange { 950fdf8faeSEd Maste KEX_DH_GRP1_SHA1 = 1, 96d74d50a8SDag-Erling Smørgrav KEX_DH_GRP14_SHA1, 97076ad2f8SDag-Erling Smørgrav KEX_DH_GRP14_SHA256, 98076ad2f8SDag-Erling Smørgrav KEX_DH_GRP16_SHA512, 99076ad2f8SDag-Erling Smørgrav KEX_DH_GRP18_SHA512, 100d0c8c0bcSDag-Erling Smørgrav KEX_DH_GEX_SHA1, 101761efaa7SDag-Erling Smørgrav KEX_DH_GEX_SHA256, 1024a421b63SDag-Erling Smørgrav KEX_ECDH_SHA2, 103f7167e0eSDag-Erling Smørgrav KEX_C25519_SHA256, 10419261079SEd Maste KEX_KEM_SNTRUP761X25519_SHA512, 105*3d9fd9fcSEd Maste KEX_KEM_MLKEM768X25519_SHA256, 106d0c8c0bcSDag-Erling Smørgrav KEX_MAX 1075b9b2fafSBrian Feldman }; 1085b9b2fafSBrian Feldman 1091323ec57SEd Maste /* kex->flags */ 1101e8db6e2SBrian Feldman #define KEX_INIT_SENT 0x0001 11119261079SEd Maste #define KEX_INITIAL 0x0002 1121323ec57SEd Maste #define KEX_HAS_PUBKEY_HOSTBOUND 0x0004 1131323ec57SEd Maste #define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ 1141323ec57SEd Maste #define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ 115edf85781SEd Maste #define KEX_HAS_PING 0x0020 116069ac184SEd Maste #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 1171e8db6e2SBrian Feldman 118bc5531deSDag-Erling Smørgrav struct sshenc { 1195b9b2fafSBrian Feldman char *name; 120bc5531deSDag-Erling Smørgrav const struct sshcipher *cipher; 121a04a10f8SKris Kennaway int enabled; 122ae1f160dSDag-Erling Smørgrav u_int key_len; 1236888a9beSDag-Erling Smørgrav u_int iv_len; 124ae1f160dSDag-Erling Smørgrav u_int block_size; 1251e8db6e2SBrian Feldman u_char *key; 1261e8db6e2SBrian Feldman u_char *iv; 127a04a10f8SKris Kennaway }; 128bc5531deSDag-Erling Smørgrav struct sshcomp { 129bc5531deSDag-Erling Smørgrav u_int type; 130a04a10f8SKris Kennaway int enabled; 131a04a10f8SKris Kennaway char *name; 132a04a10f8SKris Kennaway }; 133bc5531deSDag-Erling Smørgrav struct newkeys { 134bc5531deSDag-Erling Smørgrav struct sshenc enc; 135bc5531deSDag-Erling Smørgrav struct sshmac mac; 136bc5531deSDag-Erling Smørgrav struct sshcomp comp; 1371e8db6e2SBrian Feldman }; 138bc5531deSDag-Erling Smørgrav 139bc5531deSDag-Erling Smørgrav struct ssh; 1401323ec57SEd Maste struct sshbuf; 141bc5531deSDag-Erling Smørgrav 142bc5531deSDag-Erling Smørgrav struct kex { 143bc5531deSDag-Erling Smørgrav struct newkeys *newkeys[MODE_MAX]; 144043840dfSDag-Erling Smørgrav u_int we_need; 145f7167e0eSDag-Erling Smørgrav u_int dh_need; 146a04a10f8SKris Kennaway int server; 147a04a10f8SKris Kennaway char *name; 148acc1a9efSDag-Erling Smørgrav char *hostkey_alg; 1491e8db6e2SBrian Feldman int hostkey_type; 150bc5531deSDag-Erling Smørgrav int hostkey_nid; 151bc5531deSDag-Erling Smørgrav u_int kex_type; 152190cef3dSDag-Erling Smørgrav char *server_sig_algs; 153acc1a9efSDag-Erling Smørgrav int ext_info_c; 154069ac184SEd Maste int ext_info_s; 15592f58c69SGordon Tetlow int kex_strict; 156069ac184SEd Maste int ext_info_received; 157bc5531deSDag-Erling Smørgrav struct sshbuf *my; 158bc5531deSDag-Erling Smørgrav struct sshbuf *peer; 15919261079SEd Maste struct sshbuf *client_version; 16019261079SEd Maste struct sshbuf *server_version; 16119261079SEd Maste struct sshbuf *session_id; 1621323ec57SEd Maste struct sshbuf *initial_sig; 1631323ec57SEd Maste struct sshkey *initial_hostkey; 164761efaa7SDag-Erling Smørgrav sig_atomic_t done; 165bc5531deSDag-Erling Smørgrav u_int flags; 166f7167e0eSDag-Erling Smørgrav int hash_alg; 167e4a9863fSDag-Erling Smørgrav int ec_nid; 168eccfee6eSDag-Erling Smørgrav char *failed_choice; 169bc5531deSDag-Erling Smørgrav int (*verify_host_key)(struct sshkey *, struct ssh *); 170bc5531deSDag-Erling Smørgrav struct sshkey *(*load_host_public_key)(int, int, struct ssh *); 171bc5531deSDag-Erling Smørgrav struct sshkey *(*load_host_private_key)(int, int, struct ssh *); 172bc5531deSDag-Erling Smørgrav int (*host_key_index)(struct sshkey *, int, struct ssh *); 17319261079SEd Maste int (*sign)(struct ssh *, struct sshkey *, struct sshkey *, 17419261079SEd Maste u_char **, size_t *, const u_char *, size_t, const char *); 175bc5531deSDag-Erling Smørgrav int (*kex[KEX_MAX])(struct ssh *); 176bc5531deSDag-Erling Smørgrav /* kex specific state */ 177bc5531deSDag-Erling Smørgrav DH *dh; /* DH */ 178bc5531deSDag-Erling Smørgrav u_int min, max, nbits; /* GEX */ 179bc5531deSDag-Erling Smørgrav EC_KEY *ec_client_key; /* ECDH */ 180bc5531deSDag-Erling Smørgrav const EC_GROUP *ec_group; /* ECDH */ 18119261079SEd Maste u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ 182bc5531deSDag-Erling Smørgrav u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ 18319261079SEd Maste u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ 184*3d9fd9fcSEd Maste u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */ 18519261079SEd Maste struct sshbuf *client_pub; 186a04a10f8SKris Kennaway }; 187a04a10f8SKris Kennaway 1880fdf8faeSEd Maste int kex_name_valid(const char *); 1890fdf8faeSEd Maste u_int kex_type_from_name(const char *); 1900fdf8faeSEd Maste int kex_hash_from_name(const char *); 1910fdf8faeSEd Maste int kex_nid_from_name(const char *); 1924a421b63SDag-Erling Smørgrav int kex_names_valid(const char *); 193f7167e0eSDag-Erling Smørgrav char *kex_alg_list(char); 194eccfee6eSDag-Erling Smørgrav char *kex_names_cat(const char *, const char *); 1950fdf8faeSEd Maste int kex_has_any_alg(const char *, const char *); 196190cef3dSDag-Erling Smørgrav int kex_assemble_names(char **, const char *, const char *); 1974d3fc8b0SEd Maste void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], 1984d3fc8b0SEd Maste const char *, const char *, const char *, const char *, const char *); 1994d3fc8b0SEd Maste void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); 2004a421b63SDag-Erling Smørgrav 20119261079SEd Maste int kex_exchange_identification(struct ssh *, int, const char *); 20219261079SEd Maste 20319261079SEd Maste struct kex *kex_new(void); 20419261079SEd Maste int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); 205bc5531deSDag-Erling Smørgrav int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); 206bc5531deSDag-Erling Smørgrav void kex_free_newkeys(struct newkeys *); 207bc5531deSDag-Erling Smørgrav void kex_free(struct kex *); 208a04a10f8SKris Kennaway 209bc5531deSDag-Erling Smørgrav int kex_buf2prop(struct sshbuf *, int *, char ***); 210bc5531deSDag-Erling Smørgrav int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); 211bc5531deSDag-Erling Smørgrav void kex_prop_free(char **); 21219261079SEd Maste int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); 21319261079SEd Maste int kex_verify_host_key(struct ssh *, struct sshkey *); 214a04a10f8SKris Kennaway 215bc5531deSDag-Erling Smørgrav int kex_send_kexinit(struct ssh *); 2164f52dfbbSDag-Erling Smørgrav int kex_input_kexinit(int, u_int32_t, struct ssh *); 2174f52dfbbSDag-Erling Smørgrav int kex_input_ext_info(int, u_int32_t, struct ssh *); 21819261079SEd Maste int kex_protocol_error(int, u_int32_t, struct ssh *); 219bc5531deSDag-Erling Smørgrav int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); 220bc5531deSDag-Erling Smørgrav int kex_send_newkeys(struct ssh *); 221acc1a9efSDag-Erling Smørgrav int kex_start_rekex(struct ssh *); 222069ac184SEd Maste int kex_server_update_ext_info(struct ssh *); 223069ac184SEd Maste void kex_set_server_sig_algs(struct ssh *, const char *); 2241e8db6e2SBrian Feldman 225bc5531deSDag-Erling Smørgrav int kexgex_client(struct ssh *); 226bc5531deSDag-Erling Smørgrav int kexgex_server(struct ssh *); 22719261079SEd Maste int kex_gen_client(struct ssh *); 22819261079SEd Maste int kex_gen_server(struct ssh *); 229d0c8c0bcSDag-Erling Smørgrav 23019261079SEd Maste int kex_dh_keypair(struct kex *); 23119261079SEd Maste int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 23219261079SEd Maste struct sshbuf **); 23319261079SEd Maste int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 234f7167e0eSDag-Erling Smørgrav 23519261079SEd Maste int kex_ecdh_keypair(struct kex *); 23619261079SEd Maste int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 23719261079SEd Maste struct sshbuf **); 23819261079SEd Maste int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 23919261079SEd Maste 24019261079SEd Maste int kex_c25519_keypair(struct kex *); 24119261079SEd Maste int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, 24219261079SEd Maste struct sshbuf **); 24319261079SEd Maste int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); 24419261079SEd Maste 24519261079SEd Maste int kex_kem_sntrup761x25519_keypair(struct kex *); 24619261079SEd Maste int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *, 24719261079SEd Maste struct sshbuf **, struct sshbuf **); 24819261079SEd Maste int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *, 24919261079SEd Maste struct sshbuf **); 25019261079SEd Maste 251*3d9fd9fcSEd Maste int kex_kem_mlkem768x25519_keypair(struct kex *); 252*3d9fd9fcSEd Maste int kex_kem_mlkem768x25519_enc(struct kex *, const struct sshbuf *, 253*3d9fd9fcSEd Maste struct sshbuf **, struct sshbuf **); 254*3d9fd9fcSEd Maste int kex_kem_mlkem768x25519_dec(struct kex *, const struct sshbuf *, 255*3d9fd9fcSEd Maste struct sshbuf **); 256*3d9fd9fcSEd Maste 25719261079SEd Maste int kex_dh_keygen(struct kex *); 25819261079SEd Maste int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); 25919261079SEd Maste 26019261079SEd Maste int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, 26119261079SEd Maste const struct sshbuf *, const struct sshbuf *, const struct sshbuf *, 262bc5531deSDag-Erling Smørgrav int, int, int, 263bc5531deSDag-Erling Smørgrav const BIGNUM *, const BIGNUM *, const BIGNUM *, 26419261079SEd Maste const BIGNUM *, const u_char *, size_t, 265bc5531deSDag-Erling Smørgrav u_char *, size_t *); 266bc5531deSDag-Erling Smørgrav 267bc5531deSDag-Erling Smørgrav void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) 268f7167e0eSDag-Erling Smørgrav __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 269f7167e0eSDag-Erling Smørgrav __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 270bc5531deSDag-Erling Smørgrav int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], 271bc5531deSDag-Erling Smørgrav const u_char pub[CURVE25519_SIZE], struct sshbuf *out) 272f7167e0eSDag-Erling Smørgrav __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 273f7167e0eSDag-Erling Smørgrav __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 27419261079SEd Maste int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], 27519261079SEd Maste const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) 27619261079SEd Maste __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) 27719261079SEd Maste __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); 278d0c8c0bcSDag-Erling Smørgrav 2794a421b63SDag-Erling Smørgrav #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) 28019261079SEd Maste void dump_digest(const char *, const u_char *, int); 2811e8db6e2SBrian Feldman #endif 2821e8db6e2SBrian Feldman 283bc5531deSDag-Erling Smørgrav #if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) 284bc5531deSDag-Erling Smørgrav # undef EC_KEY 285bc5531deSDag-Erling Smørgrav # undef EC_GROUP 286bc5531deSDag-Erling Smørgrav # undef EC_POINT 287bc5531deSDag-Erling Smørgrav #endif 288bc5531deSDag-Erling Smørgrav 289a04a10f8SKris Kennaway #endif 290