kexgen.c 9.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348
  1. /* $OpenBSD: kexgen.c,v 1.4 2019/11/25 00:51:37 djm Exp $ */
  2. /*
  3. * Copyright (c) 2019 Markus Friedl. All rights reserved.
  4. *
  5. * Redistribution and use in source and binary forms, with or without
  6. * modification, are permitted provided that the following conditions
  7. * are met:
  8. * 1. Redistributions of source code must retain the above copyright
  9. * notice, this list of conditions and the following disclaimer.
  10. * 2. Redistributions in binary form must reproduce the above copyright
  11. * notice, this list of conditions and the following disclaimer in the
  12. * documentation and/or other materials provided with the distribution.
  13. *
  14. * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  15. * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  16. * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  17. * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  18. * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  19. * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  20. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  21. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  23. * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "includes.h"
  26. #include <sys/types.h>
  27. #include <stdarg.h>
  28. #include <stdio.h>
  29. #include <string.h>
  30. #include <signal.h>
  31. #include "sshkey.h"
  32. #include "kex.h"
  33. #include "log.h"
  34. #include "packet.h"
  35. #include "ssh2.h"
  36. #include "sshbuf.h"
  37. #include "digest.h"
  38. #include "ssherr.h"
  39. static int input_kex_gen_init(int, u_int32_t, struct ssh *);
  40. static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh);
  41. static int
  42. kex_gen_hash(
  43. int hash_alg,
  44. const struct sshbuf *client_version,
  45. const struct sshbuf *server_version,
  46. const struct sshbuf *client_kexinit,
  47. const struct sshbuf *server_kexinit,
  48. const struct sshbuf *server_host_key_blob,
  49. const struct sshbuf *client_pub,
  50. const struct sshbuf *server_pub,
  51. const struct sshbuf *shared_secret,
  52. u_char *hash, size_t *hashlen)
  53. {
  54. struct sshbuf *b;
  55. int r;
  56. if (*hashlen < ssh_digest_bytes(hash_alg))
  57. return SSH_ERR_INVALID_ARGUMENT;
  58. if ((b = sshbuf_new()) == NULL)
  59. return SSH_ERR_ALLOC_FAIL;
  60. if ((r = sshbuf_put_stringb(b, client_version)) != 0 ||
  61. (r = sshbuf_put_stringb(b, server_version)) != 0 ||
  62. /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
  63. (r = sshbuf_put_u32(b, sshbuf_len(client_kexinit) + 1)) != 0 ||
  64. (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
  65. (r = sshbuf_putb(b, client_kexinit)) != 0 ||
  66. (r = sshbuf_put_u32(b, sshbuf_len(server_kexinit) + 1)) != 0 ||
  67. (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) != 0 ||
  68. (r = sshbuf_putb(b, server_kexinit)) != 0 ||
  69. (r = sshbuf_put_stringb(b, server_host_key_blob)) != 0 ||
  70. (r = sshbuf_put_stringb(b, client_pub)) != 0 ||
  71. (r = sshbuf_put_stringb(b, server_pub)) != 0 ||
  72. (r = sshbuf_putb(b, shared_secret)) != 0) {
  73. sshbuf_free(b);
  74. return r;
  75. }
  76. #ifdef DEBUG_KEX
  77. sshbuf_dump(b, stderr);
  78. #endif
  79. if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
  80. sshbuf_free(b);
  81. debug("(ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0)");
  82. return SSH_ERR_LIBCRYPTO_ERROR;
  83. }
  84. sshbuf_free(b);
  85. *hashlen = ssh_digest_bytes(hash_alg);
  86. #ifdef DEBUG_KEX
  87. dump_digest("hash", hash, *hashlen);
  88. #endif
  89. return 0;
  90. }
  91. int
  92. kex_gen_client(struct ssh *ssh)
  93. {
  94. struct kex *kex = ssh->kex;
  95. int r;
  96. switch (kex->kex_type) {
  97. #ifdef WITH_OPENSSL
  98. case KEX_DH_GRP1_SHA1:
  99. case KEX_DH_GRP14_SHA1:
  100. case KEX_DH_GRP14_SHA256:
  101. case KEX_DH_GRP16_SHA512:
  102. case KEX_DH_GRP18_SHA512:
  103. r = kex_dh_keypair(kex);
  104. break;
  105. case KEX_ECDH_SHA2:
  106. r = kex_ecdh_keypair(kex);
  107. break;
  108. #endif
  109. case KEX_C25519_SHA256:
  110. r = kex_c25519_keypair(kex);
  111. break;
  112. case KEX_KEM_SNTRUP761X25519_SHA512:
  113. r = kex_kem_sntrup761x25519_keypair(kex);
  114. break;
  115. default:
  116. r = SSH_ERR_INVALID_ARGUMENT;
  117. break;
  118. }
  119. if (r != 0)
  120. return r;
  121. if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_INIT)) != 0 ||
  122. (r = sshpkt_put_stringb(ssh, kex->client_pub)) != 0 ||
  123. (r = sshpkt_send(ssh)) != 0)
  124. return r;
  125. debug("expecting SSH2_MSG_KEX_ECDH_REPLY");
  126. ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &input_kex_gen_reply);
  127. return 0;
  128. }
  129. static int
  130. input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
  131. {
  132. struct kex *kex = ssh->kex;
  133. struct sshkey *server_host_key = NULL;
  134. struct sshbuf *shared_secret = NULL;
  135. struct sshbuf *server_blob = NULL;
  136. struct sshbuf *tmp = NULL, *server_host_key_blob = NULL;
  137. u_char *signature = NULL;
  138. u_char hash[SSH_DIGEST_MAX_LENGTH];
  139. size_t slen, hashlen;
  140. int r;
  141. debug("SSH2_MSG_KEX_ECDH_REPLY received");
  142. ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_REPLY, &kex_protocol_error);
  143. /* hostkey */
  144. if ((r = sshpkt_getb_froms(ssh, &server_host_key_blob)) != 0)
  145. goto out;
  146. /* sshkey_fromb() consumes its buffer, so make a copy */
  147. if ((tmp = sshbuf_fromb(server_host_key_blob)) == NULL) {
  148. r = SSH_ERR_ALLOC_FAIL;
  149. goto out;
  150. }
  151. if ((r = sshkey_fromb(tmp, &server_host_key)) != 0)
  152. goto out;
  153. if ((r = kex_verify_host_key(ssh, server_host_key)) != 0)
  154. goto out;
  155. /* Q_S, server public key */
  156. /* signed H */
  157. if ((r = sshpkt_getb_froms(ssh, &server_blob)) != 0 ||
  158. (r = sshpkt_get_string(ssh, &signature, &slen)) != 0 ||
  159. (r = sshpkt_get_end(ssh)) != 0)
  160. goto out;
  161. /* compute shared secret */
  162. switch (kex->kex_type) {
  163. #ifdef WITH_OPENSSL
  164. case KEX_DH_GRP1_SHA1:
  165. case KEX_DH_GRP14_SHA1:
  166. case KEX_DH_GRP14_SHA256:
  167. case KEX_DH_GRP16_SHA512:
  168. case KEX_DH_GRP18_SHA512:
  169. r = kex_dh_dec(kex, server_blob, &shared_secret);
  170. break;
  171. case KEX_ECDH_SHA2:
  172. r = kex_ecdh_dec(kex, server_blob, &shared_secret);
  173. break;
  174. #endif
  175. case KEX_C25519_SHA256:
  176. r = kex_c25519_dec(kex, server_blob, &shared_secret);
  177. break;
  178. case KEX_KEM_SNTRUP761X25519_SHA512:
  179. r = kex_kem_sntrup761x25519_dec(kex, server_blob,
  180. &shared_secret);
  181. break;
  182. default:
  183. r = SSH_ERR_INVALID_ARGUMENT;
  184. break;
  185. }
  186. if (r !=0 )
  187. goto out;
  188. /* calc and verify H */
  189. hashlen = sizeof(hash);
  190. if ((r = kex_gen_hash(
  191. kex->hash_alg,
  192. kex->client_version,
  193. kex->server_version,
  194. kex->my,
  195. kex->peer,
  196. server_host_key_blob,
  197. kex->client_pub,
  198. server_blob,
  199. shared_secret,
  200. hash, &hashlen)) != 0)
  201. goto out;
  202. if ((r = sshkey_verify(server_host_key, signature, slen, hash, hashlen,
  203. kex->hostkey_alg, ssh->compat, NULL)) != 0)
  204. goto out;
  205. if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
  206. r = kex_send_newkeys(ssh);
  207. out:
  208. explicit_bzero(hash, sizeof(hash));
  209. explicit_bzero(kex->c25519_client_key, sizeof(kex->c25519_client_key));
  210. explicit_bzero(kex->sntrup761_client_key,
  211. sizeof(kex->sntrup761_client_key));
  212. sshbuf_free(server_host_key_blob);
  213. free(signature);
  214. sshbuf_free(tmp);
  215. sshkey_free(server_host_key);
  216. sshbuf_free(server_blob);
  217. sshbuf_free(shared_secret);
  218. sshbuf_free(kex->client_pub);
  219. kex->client_pub = NULL;
  220. return r;
  221. }
  222. int
  223. kex_gen_server(struct ssh *ssh)
  224. {
  225. debug("expecting SSH2_MSG_KEX_ECDH_INIT");
  226. ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &input_kex_gen_init);
  227. return 0;
  228. }
  229. static int
  230. input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
  231. {
  232. struct kex *kex = ssh->kex;
  233. struct sshkey *server_host_private, *server_host_public;
  234. struct sshbuf *shared_secret = NULL;
  235. struct sshbuf *server_pubkey = NULL;
  236. struct sshbuf *client_pubkey = NULL;
  237. struct sshbuf *server_host_key_blob = NULL;
  238. u_char *signature = NULL, hash[SSH_DIGEST_MAX_LENGTH];
  239. size_t slen, hashlen;
  240. int r;
  241. debug("SSH2_MSG_KEX_ECDH_INIT received");
  242. ssh_dispatch_set(ssh, SSH2_MSG_KEX_ECDH_INIT, &kex_protocol_error);
  243. if ((r = kex_load_hostkey(ssh, &server_host_private,
  244. &server_host_public)) != 0)
  245. goto out;
  246. if ((r = sshpkt_getb_froms(ssh, &client_pubkey)) != 0 ||
  247. (r = sshpkt_get_end(ssh)) != 0)
  248. goto out;
  249. /* compute shared secret */
  250. switch (kex->kex_type) {
  251. #ifdef WITH_OPENSSL
  252. case KEX_DH_GRP1_SHA1:
  253. case KEX_DH_GRP14_SHA1:
  254. case KEX_DH_GRP14_SHA256:
  255. case KEX_DH_GRP16_SHA512:
  256. case KEX_DH_GRP18_SHA512:
  257. r = kex_dh_enc(kex, client_pubkey, &server_pubkey,
  258. &shared_secret);
  259. break;
  260. case KEX_ECDH_SHA2:
  261. r = kex_ecdh_enc(kex, client_pubkey, &server_pubkey,
  262. &shared_secret);
  263. break;
  264. #endif
  265. case KEX_C25519_SHA256:
  266. r = kex_c25519_enc(kex, client_pubkey, &server_pubkey,
  267. &shared_secret);
  268. break;
  269. case KEX_KEM_SNTRUP761X25519_SHA512:
  270. r = kex_kem_sntrup761x25519_enc(kex, client_pubkey,
  271. &server_pubkey, &shared_secret);
  272. break;
  273. default:
  274. r = SSH_ERR_INVALID_ARGUMENT;
  275. break;
  276. }
  277. if (r !=0 )
  278. goto out;
  279. /* calc H */
  280. if ((server_host_key_blob = sshbuf_new()) == NULL) {
  281. r = SSH_ERR_ALLOC_FAIL;
  282. goto out;
  283. }
  284. if ((r = sshkey_putb(server_host_public, server_host_key_blob)) != 0)
  285. goto out;
  286. hashlen = sizeof(hash);
  287. if ((r = kex_gen_hash(
  288. kex->hash_alg,
  289. kex->client_version,
  290. kex->server_version,
  291. kex->peer,
  292. kex->my,
  293. server_host_key_blob,
  294. client_pubkey,
  295. server_pubkey,
  296. shared_secret,
  297. hash, &hashlen)) != 0)
  298. goto out;
  299. /* sign H */
  300. if ((r = kex->sign(ssh, server_host_private, server_host_public,
  301. &signature, &slen, hash, hashlen, kex->hostkey_alg)) != 0)
  302. goto out;
  303. /* send server hostkey, ECDH pubkey 'Q_S' and signed H */
  304. if ((r = sshpkt_start(ssh, SSH2_MSG_KEX_ECDH_REPLY)) != 0 ||
  305. (r = sshpkt_put_stringb(ssh, server_host_key_blob)) != 0 ||
  306. (r = sshpkt_put_stringb(ssh, server_pubkey)) != 0 ||
  307. (r = sshpkt_put_string(ssh, signature, slen)) != 0 ||
  308. (r = sshpkt_send(ssh)) != 0)
  309. goto out;
  310. if ((r = kex_derive_keys(ssh, hash, hashlen, shared_secret)) == 0)
  311. r = kex_send_newkeys(ssh);
  312. out:
  313. explicit_bzero(hash, sizeof(hash));
  314. sshbuf_free(server_host_key_blob);
  315. free(signature);
  316. sshbuf_free(shared_secret);
  317. sshbuf_free(client_pubkey);
  318. sshbuf_free(server_pubkey);
  319. return r;
  320. }