diff options
Diffstat (limited to 'kexdh.c')
-rw-r--r-- | kexdh.c | 49 |
1 files changed, 46 insertions, 3 deletions
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: kexdh.c,v 1.28 2019/01/21 10:00:23 djm Exp $ */ | 1 | /* $OpenBSD: kexdh.c,v 1.29 2019/01/21 10:03:37 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2001 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -43,6 +43,7 @@ | |||
43 | #include "ssherr.h" | 43 | #include "ssherr.h" |
44 | #include "sshbuf.h" | 44 | #include "sshbuf.h" |
45 | #include "digest.h" | 45 | #include "digest.h" |
46 | #include "dh.h" | ||
46 | 47 | ||
47 | int | 48 | int |
48 | kex_dh_keygen(struct kex *kex) | 49 | kex_dh_keygen(struct kex *kex) |
@@ -70,6 +71,48 @@ kex_dh_keygen(struct kex *kex) | |||
70 | } | 71 | } |
71 | 72 | ||
72 | int | 73 | int |
74 | kex_dh_compute_key(struct kex *kex, BIGNUM *dh_pub, struct sshbuf *out) | ||
75 | { | ||
76 | BIGNUM *shared_secret = NULL; | ||
77 | u_char *kbuf = NULL; | ||
78 | size_t klen = 0; | ||
79 | int kout, r; | ||
80 | |||
81 | #ifdef DEBUG_KEXDH | ||
82 | fprintf(stderr, "dh_pub= "); | ||
83 | BN_print_fp(stderr, dh_pub); | ||
84 | fprintf(stderr, "\n"); | ||
85 | debug("bits %d", BN_num_bits(dh_pub)); | ||
86 | DHparams_print_fp(stderr, kex->dh); | ||
87 | fprintf(stderr, "\n"); | ||
88 | #endif | ||
89 | |||
90 | if (!dh_pub_is_valid(kex->dh, dh_pub)) { | ||
91 | r = SSH_ERR_MESSAGE_INCOMPLETE; | ||
92 | goto out; | ||
93 | } | ||
94 | klen = DH_size(kex->dh); | ||
95 | if ((kbuf = malloc(klen)) == NULL || | ||
96 | (shared_secret = BN_new()) == NULL) { | ||
97 | r = SSH_ERR_ALLOC_FAIL; | ||
98 | goto out; | ||
99 | } | ||
100 | if ((kout = DH_compute_key(kbuf, dh_pub, kex->dh)) < 0 || | ||
101 | BN_bin2bn(kbuf, kout, shared_secret) == NULL) { | ||
102 | r = SSH_ERR_LIBCRYPTO_ERROR; | ||
103 | goto out; | ||
104 | } | ||
105 | #ifdef DEBUG_KEXDH | ||
106 | dump_digest("shared secret", kbuf, kout); | ||
107 | #endif | ||
108 | r = sshbuf_put_bignum2(out, shared_secret); | ||
109 | out: | ||
110 | freezero(kbuf, klen); | ||
111 | BN_clear_free(shared_secret); | ||
112 | return r; | ||
113 | } | ||
114 | |||
115 | int | ||
73 | kex_dh_hash( | 116 | kex_dh_hash( |
74 | int hash_alg, | 117 | int hash_alg, |
75 | const struct sshbuf *client_version, | 118 | const struct sshbuf *client_version, |
@@ -79,7 +122,7 @@ kex_dh_hash( | |||
79 | const u_char *serverhostkeyblob, size_t sbloblen, | 122 | const u_char *serverhostkeyblob, size_t sbloblen, |
80 | const BIGNUM *client_dh_pub, | 123 | const BIGNUM *client_dh_pub, |
81 | const BIGNUM *server_dh_pub, | 124 | const BIGNUM *server_dh_pub, |
82 | const BIGNUM *shared_secret, | 125 | const u_char *shared_secret, size_t secretlen, |
83 | u_char *hash, size_t *hashlen) | 126 | u_char *hash, size_t *hashlen) |
84 | { | 127 | { |
85 | struct sshbuf *b; | 128 | struct sshbuf *b; |
@@ -101,7 +144,7 @@ kex_dh_hash( | |||
101 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || | 144 | (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) != 0 || |
102 | (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || | 145 | (r = sshbuf_put_bignum2(b, client_dh_pub)) != 0 || |
103 | (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || | 146 | (r = sshbuf_put_bignum2(b, server_dh_pub)) != 0 || |
104 | (r = sshbuf_put_bignum2(b, shared_secret)) != 0) { | 147 | (r = sshbuf_put(b, shared_secret, secretlen)) != 0) { |
105 | sshbuf_free(b); | 148 | sshbuf_free(b); |
106 | return r; | 149 | return r; |
107 | } | 150 | } |