]>
Commit | Line | Data |
---|---|---|
4dbc5a36 | 1 | /* $OpenBSD: kex.h,v 1.122 2024/02/02 00:13:34 djm Exp $ */ |
36579d3d | 2 | |
33b13568 | 3 | /* |
44697233 | 4 | * Copyright (c) 2000, 2001 Markus Friedl. All rights reserved. |
33b13568 DM |
5 | * |
6 | * Redistribution and use in source and binary forms, with or without | |
7 | * modification, are permitted provided that the following conditions | |
8 | * are met: | |
9 | * 1. Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * 2. Redistributions in binary form must reproduce the above copyright | |
12 | * notice, this list of conditions and the following disclaimer in the | |
13 | * documentation and/or other materials provided with the distribution. | |
33b13568 DM |
14 | * |
15 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
16 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
17 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
18 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
19 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
20 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
21 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
22 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
23 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
24 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
25 | */ | |
26 | #ifndef KEX_H | |
27 | #define KEX_H | |
28 | ||
128343bc | 29 | #include "mac.h" |
dfd59161 | 30 | #include "crypto_api.h" |
128343bc | 31 | |
773dda25 | 32 | #ifdef WITH_OPENSSL |
edd1d3a6 DM |
33 | # include <openssl/bn.h> |
34 | # include <openssl/dh.h> | |
35 | # include <openssl/ecdsa.h> | |
773dda25 DM |
36 | # ifdef OPENSSL_HAS_ECC |
37 | # include <openssl/ec.h> | |
38 | # else /* OPENSSL_HAS_ECC */ | |
39 | # define EC_KEY void | |
40 | # define EC_GROUP void | |
41 | # define EC_POINT void | |
42 | # endif /* OPENSSL_HAS_ECC */ | |
43 | #else /* WITH_OPENSSL */ | |
eef1447d DM |
44 | # define DH void |
45 | # define BIGNUM void | |
773dda25 DM |
46 | # define EC_KEY void |
47 | # define EC_GROUP void | |
48 | # define EC_POINT void | |
49 | #endif /* WITH_OPENSSL */ | |
50 | ||
5b48cdd8 DT |
51 | #define KEX_COOKIE_LEN 16 |
52 | ||
b97739dc | 53 | #define KEX_DH1 "diffie-hellman-group1-sha1" |
54 | #define KEX_DH14_SHA1 "diffie-hellman-group14-sha1" | |
55 | #define KEX_DH14_SHA256 "diffie-hellman-group14-sha256" | |
56 | #define KEX_DH16_SHA512 "diffie-hellman-group16-sha512" | |
57 | #define KEX_DH18_SHA512 "diffie-hellman-group18-sha512" | |
58 | #define KEX_DHGEX_SHA1 "diffie-hellman-group-exchange-sha1" | |
59 | #define KEX_DHGEX_SHA256 "diffie-hellman-group-exchange-sha256" | |
60 | #define KEX_ECDH_SHA2_NISTP256 "ecdh-sha2-nistp256" | |
61 | #define KEX_ECDH_SHA2_NISTP384 "ecdh-sha2-nistp384" | |
62 | #define KEX_ECDH_SHA2_NISTP521 "ecdh-sha2-nistp521" | |
63 | #define KEX_CURVE25519_SHA256 "curve25519-sha256" | |
64 | #define KEX_CURVE25519_SHA256_OLD "curve25519-sha256@libssh.org" | |
2c71cec0 | 65 | #define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512@openssh.com" |
33b13568 | 66 | |
9786e6e2 | 67 | #define COMP_NONE 0 |
984bacfa | 68 | /* pre-auth compression (COMP_ZLIB) is only supported in the client */ |
ab39267f | 69 | #define COMP_ZLIB 1 |
168b46f4 | 70 | #define COMP_DELAYED 2 |
9786e6e2 | 71 | |
57d10cbe | 72 | #define CURVE25519_SIZE 32 |
73 | ||
33b13568 DM |
74 | enum kex_init_proposals { |
75 | PROPOSAL_KEX_ALGS, | |
76 | PROPOSAL_SERVER_HOST_KEY_ALGS, | |
77 | PROPOSAL_ENC_ALGS_CTOS, | |
78 | PROPOSAL_ENC_ALGS_STOC, | |
79 | PROPOSAL_MAC_ALGS_CTOS, | |
80 | PROPOSAL_MAC_ALGS_STOC, | |
81 | PROPOSAL_COMP_ALGS_CTOS, | |
82 | PROPOSAL_COMP_ALGS_STOC, | |
83 | PROPOSAL_LANG_CTOS, | |
84 | PROPOSAL_LANG_STOC, | |
85 | PROPOSAL_MAX | |
86 | }; | |
87 | ||
88 | enum kex_modes { | |
89 | MODE_IN, | |
90 | MODE_OUT, | |
91 | MODE_MAX | |
92 | }; | |
93 | ||
874d77bb | 94 | enum kex_exchange { |
8e7fb335 | 95 | KEX_DH_GRP1_SHA1, |
f675fc49 | 96 | KEX_DH_GRP14_SHA1, |
0e8eeec8 | 97 | KEX_DH_GRP14_SHA256, |
98 | KEX_DH_GRP16_SHA512, | |
99 | KEX_DH_GRP18_SHA512, | |
8e7fb335 | 100 | KEX_DH_GEX_SHA1, |
a63128d1 | 101 | KEX_DH_GEX_SHA256, |
eb8b60e3 | 102 | KEX_ECDH_SHA2, |
1e124260 | 103 | KEX_C25519_SHA256, |
2c71cec0 | 104 | KEX_KEM_SNTRUP761X25519_SHA512, |
8e7fb335 | 105 | KEX_MAX |
874d77bb | 106 | }; |
ef4eea9b | 107 | |
94ae0c6f | 108 | /* kex->flags */ |
109 | #define KEX_INIT_SENT 0x0001 | |
110 | #define KEX_INITIAL 0x0002 | |
111 | #define KEX_HAS_PUBKEY_HOSTBOUND 0x0004 | |
4dbc5a36 | 112 | #define KEX_RSA_SHA2_256_SUPPORTED 0x0008 /* only set in server for now */ |
113 | #define KEX_RSA_SHA2_512_SUPPORTED 0x0010 /* only set in server for now */ | |
114 | #define KEX_HAS_PING 0x0020 | |
115 | #define KEX_HAS_EXT_INFO_IN_AUTH 0x0040 | |
2d90e003 | 116 | |
091c3028 | 117 | struct sshenc { |
2d90e003 | 118 | char *name; |
091c3028 | 119 | const struct sshcipher *cipher; |
2d90e003 | 120 | int enabled; |
963f6b25 | 121 | u_int key_len; |
1d75abfe | 122 | u_int iv_len; |
963f6b25 | 123 | u_int block_size; |
46c16220 BL |
124 | u_char *key; |
125 | u_char *iv; | |
33b13568 | 126 | }; |
091c3028 | 127 | struct sshcomp { |
128 | u_int type; | |
2d90e003 BL |
129 | int enabled; |
130 | char *name; | |
131 | }; | |
091c3028 | 132 | struct newkeys { |
133 | struct sshenc enc; | |
134 | struct sshmac mac; | |
57d10cbe | 135 | struct sshcomp comp; |
33b13568 | 136 | }; |
57d10cbe | 137 | |
138 | struct ssh; | |
b42c61d6 | 139 | struct sshbuf; |
57d10cbe | 140 | |
091c3028 | 141 | struct kex { |
091c3028 | 142 | struct newkeys *newkeys[MODE_MAX]; |
eccb9de7 | 143 | u_int we_need; |
76eea4ab | 144 | u_int dh_need; |
2d90e003 BL |
145 | int server; |
146 | char *name; | |
76c9fbbe | 147 | char *hostkey_alg; |
2d90e003 | 148 | int hostkey_type; |
5104db7c | 149 | int hostkey_nid; |
57d10cbe | 150 | u_int kex_type; |
4ba0d547 | 151 | char *server_sig_algs; |
76c9fbbe | 152 | int ext_info_c; |
a7ed931c | 153 | int ext_info_s; |
1edb00c5 | 154 | int kex_strict; |
a7ed931c | 155 | int ext_info_received; |
091c3028 | 156 | struct sshbuf *my; |
157 | struct sshbuf *peer; | |
0a843d9a | 158 | struct sshbuf *client_version; |
159 | struct sshbuf *server_version; | |
39be3dc2 | 160 | struct sshbuf *session_id; |
b42c61d6 | 161 | struct sshbuf *initial_sig; |
162 | struct sshkey *initial_hostkey; | |
97c91f68 | 163 | sig_atomic_t done; |
57d10cbe | 164 | u_int flags; |
b3051d01 | 165 | int hash_alg; |
ea11119e | 166 | int ec_nid; |
f319912b | 167 | char *failed_choice; |
57d10cbe | 168 | int (*verify_host_key)(struct sshkey *, struct ssh *); |
5104db7c | 169 | struct sshkey *(*load_host_public_key)(int, int, struct ssh *); |
170 | struct sshkey *(*load_host_private_key)(int, int, struct ssh *); | |
523463a3 | 171 | int (*host_key_index)(struct sshkey *, int, struct ssh *); |
04c091fc | 172 | int (*sign)(struct ssh *, struct sshkey *, struct sshkey *, |
173 | u_char **, size_t *, const u_char *, size_t, const char *); | |
57d10cbe | 174 | int (*kex[KEX_MAX])(struct ssh *); |
175 | /* kex specific state */ | |
176 | DH *dh; /* DH */ | |
177 | u_int min, max, nbits; /* GEX */ | |
178 | EC_KEY *ec_client_key; /* ECDH */ | |
179 | const EC_GROUP *ec_group; /* ECDH */ | |
dfd59161 | 180 | u_char c25519_client_key[CURVE25519_SIZE]; /* 25519 + KEM */ |
57d10cbe | 181 | u_char c25519_client_pubkey[CURVE25519_SIZE]; /* 25519 */ |
2c71cec0 | 182 | u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */ |
aaca72d6 | 183 | struct sshbuf *client_pub; |
33b13568 DM |
184 | }; |
185 | ||
d5f62bf2 | 186 | int kex_names_valid(const char *); |
690d9890 | 187 | char *kex_alg_list(char); |
f9eca249 | 188 | char *kex_names_cat(const char *, const char *); |
312d2f28 | 189 | int kex_assemble_names(char **, const char *, const char *); |
9641753e | 190 | void kex_proposal_populate_entries(struct ssh *, char *prop[PROPOSAL_MAX], |
191 | const char *, const char *, const char *, const char *, const char *); | |
192 | void kex_proposal_free_entries(char *prop[PROPOSAL_MAX]); | |
d5f62bf2 | 193 | |
0a843d9a | 194 | int kex_exchange_identification(struct ssh *, int, const char *); |
195 | ||
196 | struct kex *kex_new(void); | |
197 | int kex_ready(struct ssh *, char *[PROPOSAL_MAX]); | |
57d10cbe | 198 | int kex_setup(struct ssh *, char *[PROPOSAL_MAX]); |
199 | void kex_free_newkeys(struct newkeys *); | |
200 | void kex_free(struct kex *); | |
238abf6a | 201 | |
57d10cbe | 202 | int kex_buf2prop(struct sshbuf *, int *, char ***); |
203 | int kex_prop2buf(struct sshbuf *, char *proposal[PROPOSAL_MAX]); | |
204 | void kex_prop_free(char **); | |
bb39bafb | 205 | int kex_load_hostkey(struct ssh *, struct sshkey **, struct sshkey **); |
b1b2ff4e | 206 | int kex_verify_host_key(struct ssh *, struct sshkey *); |
1e124260 | 207 | |
57d10cbe | 208 | int kex_send_kexinit(struct ssh *); |
2ae666a8 | 209 | int kex_input_kexinit(int, u_int32_t, struct ssh *); |
210 | int kex_input_ext_info(int, u_int32_t, struct ssh *); | |
3dd0c64e | 211 | int kex_protocol_error(int, u_int32_t, struct ssh *); |
57d10cbe | 212 | int kex_derive_keys(struct ssh *, u_char *, u_int, const struct sshbuf *); |
57d10cbe | 213 | int kex_send_newkeys(struct ssh *); |
19bcf2ea | 214 | int kex_start_rekex(struct ssh *); |
a7ed931c | 215 | int kex_server_update_ext_info(struct ssh *); |
216 | void kex_set_server_sig_algs(struct ssh *, const char *); | |
57d10cbe | 217 | |
57d10cbe | 218 | int kexgex_client(struct ssh *); |
219 | int kexgex_server(struct ssh *); | |
aaca72d6 | 220 | int kex_gen_client(struct ssh *); |
221 | int kex_gen_server(struct ssh *); | |
dfd59161 | 222 | |
9c9c97e1 | 223 | int kex_dh_keypair(struct kex *); |
71e67fff | 224 | int kex_dh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
9c9c97e1 | 225 | struct sshbuf **); |
71e67fff | 226 | int kex_dh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
9c9c97e1 | 227 | |
92dda34e | 228 | int kex_ecdh_keypair(struct kex *); |
71e67fff | 229 | int kex_ecdh_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
92dda34e | 230 | struct sshbuf **); |
71e67fff | 231 | int kex_ecdh_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
92dda34e | 232 | |
2f6a9ddb | 233 | int kex_c25519_keypair(struct kex *); |
71e67fff | 234 | int kex_c25519_enc(struct kex *, const struct sshbuf *, struct sshbuf **, |
2f6a9ddb | 235 | struct sshbuf **); |
71e67fff | 236 | int kex_c25519_dec(struct kex *, const struct sshbuf *, struct sshbuf **); |
2f6a9ddb | 237 | |
2c71cec0 | 238 | int kex_kem_sntrup761x25519_keypair(struct kex *); |
239 | int kex_kem_sntrup761x25519_enc(struct kex *, const struct sshbuf *, | |
dfd59161 | 240 | struct sshbuf **, struct sshbuf **); |
2c71cec0 | 241 | int kex_kem_sntrup761x25519_dec(struct kex *, const struct sshbuf *, |
dfd59161 | 242 | struct sshbuf **); |
57d10cbe | 243 | |
e93bd98e | 244 | int kex_dh_keygen(struct kex *); |
dec5e9d3 | 245 | int kex_dh_compute_key(struct kex *, BIGNUM *, struct sshbuf *); |
57d10cbe | 246 | |
0a843d9a | 247 | int kexgex_hash(int, const struct sshbuf *, const struct sshbuf *, |
bb956eaa | 248 | const struct sshbuf *, const struct sshbuf *, const struct sshbuf *, |
57d10cbe | 249 | int, int, int, |
250 | const BIGNUM *, const BIGNUM *, const BIGNUM *, | |
dec5e9d3 | 251 | const BIGNUM *, const u_char *, size_t, |
57d10cbe | 252 | u_char *, size_t *); |
253 | ||
57d10cbe | 254 | void kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) |
686c7d9e DM |
255 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) |
256 | __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); | |
57d10cbe | 257 | int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], |
258 | const u_char pub[CURVE25519_SIZE], struct sshbuf *out) | |
686c7d9e DM |
259 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) |
260 | __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); | |
dfd59161 | 261 | int kexc25519_shared_key_ext(const u_char key[CURVE25519_SIZE], |
262 | const u_char pub[CURVE25519_SIZE], struct sshbuf *out, int) | |
263 | __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE))) | |
264 | __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE))); | |
8e7fb335 | 265 | |
eb8b60e3 | 266 | #if defined(DEBUG_KEX) || defined(DEBUG_KEXDH) || defined(DEBUG_KEXECDH) |
dfd59161 | 267 | void dump_digest(const char *, const u_char *, int); |
20d7c7b0 | 268 | #endif |
33b13568 | 269 | |
773dda25 DM |
270 | #if !defined(WITH_OPENSSL) || !defined(OPENSSL_HAS_ECC) |
271 | # undef EC_KEY | |
272 | # undef EC_GROUP | |
273 | # undef EC_POINT | |
274 | #endif | |
275 | ||
33b13568 | 276 | #endif |