View | Details | Raw Unified | Return to bug 1023 | Differences between
and this patch

Collapse All | Expand All

(-)kex.c (-17 / +29 lines)
Lines 44-49 RCSID("$OpenBSD: kex.c,v 1.63 2005/07/17 Link Here
44
44
45
#define KEX_COOKIE_LEN	16
45
#define KEX_COOKIE_LEN	16
46
46
47
extern const EVP_MD *evp_ssh_sha256(void);
48
47
/* prototype */
49
/* prototype */
48
static void kex_kexinit_finish(Kex *);
50
static void kex_kexinit_finish(Kex *);
49
static void kex_choose_conf(Kex *);
51
static void kex_choose_conf(Kex *);
Lines 287-304 choose_comp(Comp *comp, char *client, ch Link Here
287
static void
289
static void
288
choose_kex(Kex *k, char *client, char *server)
290
choose_kex(Kex *k, char *client, char *server)
289
{
291
{
292
	int mdsz;
293
290
	k->name = match_list(client, server, NULL);
294
	k->name = match_list(client, server, NULL);
291
	if (k->name == NULL)
295
	if (k->name == NULL)
292
		fatal("no kex alg");
296
		fatal("no kex alg");
293
	if (strcmp(k->name, KEX_DH1) == 0) {
297
	if (strcmp(k->name, KEX_DH1) == 0) {
294
		k->kex_type = KEX_DH_GRP1_SHA1;
298
		k->kex_type = KEX_DH_GRP1_SHA1;
299
		k->evp_md = EVP_sha1();
295
	} else if (strcmp(k->name, KEX_DH14) == 0) {
300
	} else if (strcmp(k->name, KEX_DH14) == 0) {
296
		k->kex_type = KEX_DH_GRP14_SHA1;
301
		k->kex_type = KEX_DH_GRP14_SHA1;
297
	} else if (strcmp(k->name, KEX_DHGEX) == 0) {
302
		k->evp_md = EVP_sha1();
303
	} else if (strcmp(k->name, KEX_DHGEX_SHA1) == 0) {
298
		k->kex_type = KEX_DH_GEX_SHA1;
304
		k->kex_type = KEX_DH_GEX_SHA1;
305
		k->evp_md = EVP_sha1();
306
	} else if (strcmp(k->name, KEX_DHGEX_SHA256) == 0) {
307
		k->kex_type = KEX_DH_GEX_SHA256;
308
		k->evp_md = evp_ssh_sha256();
299
	} else
309
	} else
300
		fatal("bad kex alg %s", k->name);
310
		fatal("bad kex alg %s", k->name);
311
312
	if ((mdsz = EVP_MD_size(k->evp_md)) <= 0)
313
		fatal("bad kex md size %d", mdsz);
314
	k->mdsz = mdsz;
301
}
315
}
316
302
static void
317
static void
303
choose_hostkeyalg(Kex *k, char *client, char *server)
318
choose_hostkeyalg(Kex *k, char *client, char *server)
304
{
319
{
Lines 402-429 kex_choose_conf(Kex *kex) Link Here
402
}
417
}
403
418
404
static u_char *
419
static u_char *
405
derive_key(Kex *kex, int id, u_int need, u_char *hash, BIGNUM *shared_secret)
420
derive_key(Kex *kex, int id, u_int need, u_char *hash, u_int hashlen,
421
    BIGNUM *shared_secret)
406
{
422
{
407
	Buffer b;
423
	Buffer b;
408
	const EVP_MD *evp_md = EVP_sha1();
409
	EVP_MD_CTX md;
424
	EVP_MD_CTX md;
410
	char c = id;
425
	char c = id;
411
	u_int have;
426
	u_int have;
412
	int mdsz = EVP_MD_size(evp_md);
427
	u_char *digest = xmalloc(roundup(need, kex->mdsz));
413
	u_char *digest;
414
415
	if (mdsz < 0)
416
		fatal("derive_key: mdsz < 0");
417
	digest = xmalloc(roundup(need, mdsz));
418
428
419
	buffer_init(&b);
429
	buffer_init(&b);
420
	buffer_put_bignum2(&b, shared_secret);
430
	buffer_put_bignum2(&b, shared_secret);
421
431
422
	/* K1 = HASH(K || H || "A" || session_id) */
432
	/* K1 = HASH(K || H || "A" || session_id) */
423
	EVP_DigestInit(&md, evp_md);
433
	EVP_DigestInit(&md, kex->evp_md);
424
	if (!(datafellows & SSH_BUG_DERIVEKEY))
434
	if (!(datafellows & SSH_BUG_DERIVEKEY))
425
		EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
435
		EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
426
	EVP_DigestUpdate(&md, hash, mdsz);
436
	EVP_DigestUpdate(&md, hash, hashlen);
427
	EVP_DigestUpdate(&md, &c, 1);
437
	EVP_DigestUpdate(&md, &c, 1);
428
	EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
438
	EVP_DigestUpdate(&md, kex->session_id, kex->session_id_len);
429
	EVP_DigestFinal(&md, digest, NULL);
439
	EVP_DigestFinal(&md, digest, NULL);
Lines 433-443 derive_key(Kex *kex, int id, u_int need, Link Here
433
	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
443
	 * Kn = HASH(K || H || K1 || K2 || ... || Kn-1)
434
	 * Key = K1 || K2 || ... || Kn
444
	 * Key = K1 || K2 || ... || Kn
435
	 */
445
	 */
436
	for (have = mdsz; need > have; have += mdsz) {
446
	for (have = kex->mdsz; need > have; have += kex->mdsz) {
437
		EVP_DigestInit(&md, evp_md);
447
		EVP_DigestInit(&md, kex->evp_md);
438
		if (!(datafellows & SSH_BUG_DERIVEKEY))
448
		if (!(datafellows & SSH_BUG_DERIVEKEY))
439
			EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
449
			EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
440
		EVP_DigestUpdate(&md, hash, mdsz);
450
		EVP_DigestUpdate(&md, hash, kex->mdsz);
441
		EVP_DigestUpdate(&md, digest, have);
451
		EVP_DigestUpdate(&md, digest, have);
442
		EVP_DigestFinal(&md, digest + have, NULL);
452
		EVP_DigestFinal(&md, digest + have, NULL);
443
	}
453
	}
Lines 453-465 Newkeys *current_keys[MODE_MAX]; Link Here
453
463
454
#define NKEYS	6
464
#define NKEYS	6
455
void
465
void
456
kex_derive_keys(Kex *kex, u_char *hash, BIGNUM *shared_secret)
466
kex_derive_keys(Kex *kex, u_char *hash, u_int hashlen, BIGNUM *shared_secret)
457
{
467
{
458
	u_char *keys[NKEYS];
468
	u_char *keys[NKEYS];
459
	u_int i, mode, ctos;
469
	u_int i, mode, ctos;
460
470
461
	for (i = 0; i < NKEYS; i++)
471
	for (i = 0; i < NKEYS; i++) {
462
		keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, shared_secret);
472
		keys[i] = derive_key(kex, 'A'+i, kex->we_need, hash, hashlen,
473
		    shared_secret);
474
	}
463
475
464
	debug2("kex_derive_keys");
476
	debug2("kex_derive_keys");
465
	for (mode = 0; mode < MODE_MAX; mode++) {
477
	for (mode = 0; mode < MODE_MAX; mode++) {
(-)kex.h (-9 / +14 lines)
Lines 31-39 Link Here
31
#include "cipher.h"
31
#include "cipher.h"
32
#include "key.h"
32
#include "key.h"
33
33
34
#define	KEX_DH1		"diffie-hellman-group1-sha1"
34
#define	KEX_DH1			"diffie-hellman-group1-sha1"
35
#define	KEX_DH14	"diffie-hellman-group14-sha1"
35
#define	KEX_DH14		"diffie-hellman-group14-sha1"
36
#define	KEX_DHGEX	"diffie-hellman-group-exchange-sha1"
36
#define	KEX_DHGEX_SHA1		"diffie-hellman-group-exchange-sha1"
37
#define	KEX_DHGEX_SHA256	"diffie-hellman-group-exchange-sha256"
37
38
38
enum kex_init_proposals {
39
enum kex_init_proposals {
39
	PROPOSAL_KEX_ALGS,
40
	PROPOSAL_KEX_ALGS,
Lines 59-64 enum kex_exchange { Link Here
59
	KEX_DH_GRP1_SHA1,
60
	KEX_DH_GRP1_SHA1,
60
	KEX_DH_GRP14_SHA1,
61
	KEX_DH_GRP14_SHA1,
61
	KEX_DH_GEX_SHA1,
62
	KEX_DH_GEX_SHA1,
63
	KEX_DH_GEX_SHA256,
62
	KEX_MAX
64
	KEX_MAX
63
};
65
};
64
66
Lines 110-115 struct Kex { Link Here
110
	Buffer	peer;
112
	Buffer	peer;
111
	int	done;
113
	int	done;
112
	int	flags;
114
	int	flags;
115
	u_int	mdsz;
116
	const EVP_MD *evp_md;
113
	char	*client_version_string;
117
	char	*client_version_string;
114
	char	*server_version_string;
118
	char	*server_version_string;
115
	int	(*verify_host_key)(Key *);
119
	int	(*verify_host_key)(Key *);
Lines 123-129 void kex_finish(Kex *); Link Here
123
127
124
void	 kex_send_kexinit(Kex *);
128
void	 kex_send_kexinit(Kex *);
125
void	 kex_input_kexinit(int, u_int32_t, void *);
129
void	 kex_input_kexinit(int, u_int32_t, void *);
126
void	 kex_derive_keys(Kex *, u_char *, BIGNUM *);
130
void	 kex_derive_keys(Kex *, u_char *, u_int, BIGNUM *);
127
131
128
Newkeys *kex_get_newkeys(int);
132
Newkeys *kex_get_newkeys(int);
129
133
Lines 132-143 void kexdh_server(Kex *); Link Here
132
void	 kexgex_client(Kex *);
136
void	 kexgex_client(Kex *);
133
void	 kexgex_server(Kex *);
137
void	 kexgex_server(Kex *);
134
138
135
u_char *
139
void
136
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
140
kex_dh_hash(char *, char *, char *, int, char *, int, u_char *, int,
137
    BIGNUM *, BIGNUM *, BIGNUM *);
141
    BIGNUM *, BIGNUM *, BIGNUM *, u_char **, u_int *);
138
u_char *
142
void
139
kexgex_hash(char *, char *, char *, int, char *, int, u_char *, int,
143
kexgex_hash(const EVP_MD *, char *, char *, char *, int, char *,
140
    int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *, BIGNUM *);
144
    int, u_char *, int, int, int, int, BIGNUM *, BIGNUM *, BIGNUM *, 
145
    BIGNUM *, BIGNUM *, u_char **, u_int *);
141
146
142
void
147
void
143
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
148
derive_ssh1_session_id(BIGNUM *, BIGNUM *, u_int8_t[8], u_int8_t[16]);
(-)kexdh.c (-3 / +5 lines)
Lines 32-38 RCSID("$OpenBSD: kexdh.c,v 1.19 2003/02/ Link Here
32
#include "ssh2.h"
32
#include "ssh2.h"
33
#include "kex.h"
33
#include "kex.h"
34
34
35
u_char *
35
void
36
kex_dh_hash(
36
kex_dh_hash(
37
    char *client_version_string,
37
    char *client_version_string,
38
    char *server_version_string,
38
    char *server_version_string,
Lines 41-47 kex_dh_hash( Link Here
41
    u_char *serverhostkeyblob, int sbloblen,
41
    u_char *serverhostkeyblob, int sbloblen,
42
    BIGNUM *client_dh_pub,
42
    BIGNUM *client_dh_pub,
43
    BIGNUM *server_dh_pub,
43
    BIGNUM *server_dh_pub,
44
    BIGNUM *shared_secret)
44
    BIGNUM *shared_secret,
45
    u_char **hash, u_int *hashlen)
45
{
46
{
46
	Buffer b;
47
	Buffer b;
47
	static u_char digest[EVP_MAX_MD_SIZE];
48
	static u_char digest[EVP_MAX_MD_SIZE];
Lines 77-81 kex_dh_hash( Link Here
77
#ifdef DEBUG_KEX
78
#ifdef DEBUG_KEX
78
	dump_digest("hash", digest, EVP_MD_size(evp_md));
79
	dump_digest("hash", digest, EVP_MD_size(evp_md));
79
#endif
80
#endif
80
	return digest;
81
	*hash = digest;
82
	*hashlen = EVP_MD_size(evp_md);
81
}
83
}
(-)kexdhc.c (-6 / +7 lines)
Lines 41-47 kexdh_client(Kex *kex) Link Here
41
	Key *server_host_key;
41
	Key *server_host_key;
42
	u_char *server_host_key_blob = NULL, *signature = NULL;
42
	u_char *server_host_key_blob = NULL, *signature = NULL;
43
	u_char *kbuf, *hash;
43
	u_char *kbuf, *hash;
44
	u_int klen, kout, slen, sbloblen;
44
	u_int klen, kout, slen, sbloblen, hashlen;
45
45
46
	/* generate and send 'e', client DH public key */
46
	/* generate and send 'e', client DH public key */
47
	switch (kex->kex_type) {
47
	switch (kex->kex_type) {
Lines 114-120 kexdh_client(Kex *kex) Link Here
114
	xfree(kbuf);
114
	xfree(kbuf);
115
115
116
	/* calc and verify H */
116
	/* calc and verify H */
117
	hash = kex_dh_hash(
117
	kex_dh_hash(
118
	    kex->client_version_string,
118
	    kex->client_version_string,
119
	    kex->server_version_string,
119
	    kex->server_version_string,
120
	    buffer_ptr(&kex->my), buffer_len(&kex->my),
120
	    buffer_ptr(&kex->my), buffer_len(&kex->my),
Lines 122-146 kexdh_client(Kex *kex) Link Here
122
	    server_host_key_blob, sbloblen,
122
	    server_host_key_blob, sbloblen,
123
	    dh->pub_key,
123
	    dh->pub_key,
124
	    dh_server_pub,
124
	    dh_server_pub,
125
	    shared_secret
125
	    shared_secret,
126
	    &hash, &hashlen
126
	);
127
	);
127
	xfree(server_host_key_blob);
128
	xfree(server_host_key_blob);
128
	BN_clear_free(dh_server_pub);
129
	BN_clear_free(dh_server_pub);
129
	DH_free(dh);
130
	DH_free(dh);
130
131
131
	if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
132
	if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
132
		fatal("key_verify failed for server_host_key");
133
		fatal("key_verify failed for server_host_key");
133
	key_free(server_host_key);
134
	key_free(server_host_key);
134
	xfree(signature);
135
	xfree(signature);
135
136
136
	/* save session id */
137
	/* save session id */
137
	if (kex->session_id == NULL) {
138
	if (kex->session_id == NULL) {
138
		kex->session_id_len = 20;
139
		kex->session_id_len = hashlen;
139
		kex->session_id = xmalloc(kex->session_id_len);
140
		kex->session_id = xmalloc(kex->session_id_len);
140
		memcpy(kex->session_id, hash, kex->session_id_len);
141
		memcpy(kex->session_id, hash, kex->session_id_len);
141
	}
142
	}
142
143
143
	kex_derive_keys(kex, hash, shared_secret);
144
	kex_derive_keys(kex, hash, hashlen, shared_secret);
144
	BN_clear_free(shared_secret);
145
	BN_clear_free(shared_secret);
145
	kex_finish(kex);
146
	kex_finish(kex);
146
}
147
}
(-)kexdhs.c (-8 / +7 lines)
Lines 41-47 kexdh_server(Kex *kex) Link Here
41
	DH *dh;
41
	DH *dh;
42
	Key *server_host_key;
42
	Key *server_host_key;
43
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
43
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
44
	u_int sbloblen, klen, kout;
44
	u_int sbloblen, klen, kout, hashlen;
45
	u_int slen;
45
	u_int slen;
46
46
47
	/* generate server DH public key */
47
	/* generate server DH public key */
Lines 103-109 kexdh_server(Kex *kex) Link Here
103
	key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
103
	key_to_blob(server_host_key, &server_host_key_blob, &sbloblen);
104
104
105
	/* calc H */
105
	/* calc H */
106
	hash = kex_dh_hash(
106
	kex_dh_hash(
107
	    kex->client_version_string,
107
	    kex->client_version_string,
108
	    kex->server_version_string,
108
	    kex->server_version_string,
109
	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
109
	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Lines 111-131 kexdh_server(Kex *kex) Link Here
111
	    server_host_key_blob, sbloblen,
111
	    server_host_key_blob, sbloblen,
112
	    dh_client_pub,
112
	    dh_client_pub,
113
	    dh->pub_key,
113
	    dh->pub_key,
114
	    shared_secret
114
	    shared_secret,
115
	    &hash, &hashlen
115
	);
116
	);
116
	BN_clear_free(dh_client_pub);
117
	BN_clear_free(dh_client_pub);
117
118
118
	/* save session id := H */
119
	/* save session id := H */
119
	/* XXX hashlen depends on KEX */
120
	if (kex->session_id == NULL) {
120
	if (kex->session_id == NULL) {
121
		kex->session_id_len = 20;
121
		kex->session_id_len = hashlen;
122
		kex->session_id = xmalloc(kex->session_id_len);
122
		kex->session_id = xmalloc(kex->session_id_len);
123
		memcpy(kex->session_id, hash, kex->session_id_len);
123
		memcpy(kex->session_id, hash, kex->session_id_len);
124
	}
124
	}
125
125
126
	/* sign H */
126
	/* sign H */
127
	/* XXX hashlen depends on KEX */
127
	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
128
	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
129
128
130
	/* destroy_sensitive_data(); */
129
	/* destroy_sensitive_data(); */
131
130
Lines 141-147 kexdh_server(Kex *kex) Link Here
141
	/* have keys, free DH */
140
	/* have keys, free DH */
142
	DH_free(dh);
141
	DH_free(dh);
143
142
144
	kex_derive_keys(kex, hash, shared_secret);
143
	kex_derive_keys(kex, hash, hashlen, shared_secret);
145
	BN_clear_free(shared_secret);
144
	BN_clear_free(shared_secret);
146
	kex_finish(kex);
145
	kex_finish(kex);
147
}
146
}
(-)kexgex.c (-9 / +14 lines)
Lines 26-40 Link Here
26
#include "includes.h"
26
#include "includes.h"
27
RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
27
RCSID("$OpenBSD: kexgex.c,v 1.23 2003/02/16 17:09:57 markus Exp $");
28
28
29
#include <openssl/evp.h>
29
#include <openssl/sha.h>
30
30
31
#include "buffer.h"
31
#include "buffer.h"
32
#include "bufaux.h"
32
#include "bufaux.h"
33
#include "kex.h"
33
#include "kex.h"
34
#include "ssh2.h"
34
#include "ssh2.h"
35
#include "log.h"
35
36
36
u_char *
37
extern const EVP_MD *evp_ssh_sha256(void);
38
39
void
37
kexgex_hash(
40
kexgex_hash(
41
    const EVP_MD *evp_md,
38
    char *client_version_string,
42
    char *client_version_string,
39
    char *server_version_string,
43
    char *server_version_string,
40
    char *ckexinit, int ckexinitlen,
44
    char *ckexinit, int ckexinitlen,
Lines 43-53 kexgex_hash( Link Here
43
    int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
47
    int min, int wantbits, int max, BIGNUM *prime, BIGNUM *gen,
44
    BIGNUM *client_dh_pub,
48
    BIGNUM *client_dh_pub,
45
    BIGNUM *server_dh_pub,
49
    BIGNUM *server_dh_pub,
46
    BIGNUM *shared_secret)
50
    BIGNUM *shared_secret,
51
    u_char **hash, u_int *hashlen)
47
{
52
{
48
	Buffer b;
53
	Buffer b;
49
	static u_char digest[EVP_MAX_MD_SIZE];
54
	static u_char digest[64];
50
	const EVP_MD *evp_md = EVP_sha1();
51
	EVP_MD_CTX md;
55
	EVP_MD_CTX md;
52
56
53
	buffer_init(&b);
57
	buffer_init(&b);
Lines 79-92 kexgex_hash( Link Here
79
#ifdef DEBUG_KEXDH
83
#ifdef DEBUG_KEXDH
80
	buffer_dump(&b);
84
	buffer_dump(&b);
81
#endif
85
#endif
86
82
	EVP_DigestInit(&md, evp_md);
87
	EVP_DigestInit(&md, evp_md);
83
	EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
88
	EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
84
	EVP_DigestFinal(&md, digest, NULL);
89
	EVP_DigestFinal(&md, digest, NULL);
85
90
	
86
	buffer_free(&b);
91
	buffer_free(&b);
87
92
	*hash = digest;
93
	*hashlen = EVP_MD_size(evp_md);
88
#ifdef DEBUG_KEXDH
94
#ifdef DEBUG_KEXDH
89
	dump_digest("hash", digest, EVP_MD_size(evp_md));
95
	dump_digest("hash", digest, *hashlen);
90
#endif
96
#endif
91
	return digest;
92
}
97
}
(-)kexgexc.c (-6 / +9 lines)
Lines 42-48 kexgex_client(Kex *kex) Link Here
42
	BIGNUM *p = NULL, *g = NULL;
42
	BIGNUM *p = NULL, *g = NULL;
43
	Key *server_host_key;
43
	Key *server_host_key;
44
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
44
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
45
	u_int klen, kout, slen, sbloblen;
45
	u_int klen, kout, slen, sbloblen, hashlen;
46
	int min, max, nbits;
46
	int min, max, nbits;
47
	DH *dh;
47
	DH *dh;
48
48
Lines 155-161 kexgex_client(Kex *kex) Link Here
155
		min = max = -1;
155
		min = max = -1;
156
156
157
	/* calc and verify H */
157
	/* calc and verify H */
158
	hash = kexgex_hash(
158
	kexgex_hash(
159
	    kex->evp_md,
159
	    kex->client_version_string,
160
	    kex->client_version_string,
160
	    kex->server_version_string,
161
	    kex->server_version_string,
161
	    buffer_ptr(&kex->my), buffer_len(&kex->my),
162
	    buffer_ptr(&kex->my), buffer_len(&kex->my),
Lines 165-189 kexgex_client(Kex *kex) Link Here
165
	    dh->p, dh->g,
166
	    dh->p, dh->g,
166
	    dh->pub_key,
167
	    dh->pub_key,
167
	    dh_server_pub,
168
	    dh_server_pub,
168
	    shared_secret
169
	    shared_secret,
170
	    &hash, &hashlen
169
	);
171
	);
172
170
	/* have keys, free DH */
173
	/* have keys, free DH */
171
	DH_free(dh);
174
	DH_free(dh);
172
	xfree(server_host_key_blob);
175
	xfree(server_host_key_blob);
173
	BN_clear_free(dh_server_pub);
176
	BN_clear_free(dh_server_pub);
174
177
175
	if (key_verify(server_host_key, signature, slen, hash, 20) != 1)
178
	if (key_verify(server_host_key, signature, slen, hash, hashlen) != 1)
176
		fatal("key_verify failed for server_host_key");
179
		fatal("key_verify failed for server_host_key");
177
	key_free(server_host_key);
180
	key_free(server_host_key);
178
	xfree(signature);
181
	xfree(signature);
179
182
180
	/* save session id */
183
	/* save session id */
181
	if (kex->session_id == NULL) {
184
	if (kex->session_id == NULL) {
182
		kex->session_id_len = 20;
185
		kex->session_id_len = hashlen;
183
		kex->session_id = xmalloc(kex->session_id_len);
186
		kex->session_id = xmalloc(kex->session_id_len);
184
		memcpy(kex->session_id, hash, kex->session_id_len);
187
		memcpy(kex->session_id, hash, kex->session_id_len);
185
	}
188
	}
186
	kex_derive_keys(kex, hash, shared_secret);
189
	kex_derive_keys(kex, hash, hashlen, shared_secret);
187
	BN_clear_free(shared_secret);
190
	BN_clear_free(shared_secret);
188
191
189
	kex_finish(kex);
192
	kex_finish(kex);
(-)kexgexs.c (-8 / +8 lines)
Lines 43-49 kexgex_server(Kex *kex) Link Here
43
	Key *server_host_key;
43
	Key *server_host_key;
44
	DH *dh;
44
	DH *dh;
45
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
45
	u_char *kbuf, *hash, *signature = NULL, *server_host_key_blob = NULL;
46
	u_int sbloblen, klen, kout, slen;
46
	u_int sbloblen, klen, kout, slen, hashlen;
47
	int min = -1, max = -1, nbits = -1, type;
47
	int min = -1, max = -1, nbits = -1, type;
48
48
49
	if (kex->load_host_key == NULL)
49
	if (kex->load_host_key == NULL)
Lines 138-144 kexgex_server(Kex *kex) Link Here
138
		min = max = -1;
138
		min = max = -1;
139
139
140
	/* calc H */			/* XXX depends on 'kex' */
140
	/* calc H */			/* XXX depends on 'kex' */
141
	hash = kexgex_hash(
141
	kexgex_hash(
142
	    kex->evp_md,
142
	    kex->client_version_string,
143
	    kex->client_version_string,
143
	    kex->server_version_string,
144
	    kex->server_version_string,
144
	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
145
	    buffer_ptr(&kex->peer), buffer_len(&kex->peer),
Lines 148-168 kexgex_server(Kex *kex) Link Here
148
	    dh->p, dh->g,
149
	    dh->p, dh->g,
149
	    dh_client_pub,
150
	    dh_client_pub,
150
	    dh->pub_key,
151
	    dh->pub_key,
151
	    shared_secret
152
	    shared_secret,
153
	    &hash, &hashlen
152
	);
154
	);
153
	BN_clear_free(dh_client_pub);
155
	BN_clear_free(dh_client_pub);
154
156
155
	/* save session id := H */
157
	/* save session id := H */
156
	/* XXX hashlen depends on KEX */
157
	if (kex->session_id == NULL) {
158
	if (kex->session_id == NULL) {
158
		kex->session_id_len = 20;
159
		kex->session_id_len = hashlen;
159
		kex->session_id = xmalloc(kex->session_id_len);
160
		kex->session_id = xmalloc(kex->session_id_len);
160
		memcpy(kex->session_id, hash, kex->session_id_len);
161
		memcpy(kex->session_id, hash, kex->session_id_len);
161
	}
162
	}
162
163
163
	/* sign H */
164
	/* sign H */
164
	/* XXX hashlen depends on KEX */
165
	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, hashlen));
165
	PRIVSEP(key_sign(server_host_key, &signature, &slen, hash, 20));
166
166
167
	/* destroy_sensitive_data(); */
167
	/* destroy_sensitive_data(); */
168
168
Lines 179-185 kexgex_server(Kex *kex) Link Here
179
	/* have keys, free DH */
179
	/* have keys, free DH */
180
	DH_free(dh);
180
	DH_free(dh);
181
181
182
	kex_derive_keys(kex, hash, shared_secret);
182
	kex_derive_keys(kex, hash, hashlen, shared_secret);
183
	BN_clear_free(shared_secret);
183
	BN_clear_free(shared_secret);
184
184
185
	kex_finish(kex);
185
	kex_finish(kex);
(-)md-sha256.c (+79 lines)
Added Link Here
1
/*
2
 * Copyright (c) 2005 Damien Miller.  All rights reserved.
3
 *
4
 * Redistribution and use in source and binary forms, with or without
5
 * modification, are permitted provided that the following conditions
6
 * are met:
7
 * 1. Redistributions of source code must retain the above copyright
8
 *    notice, this list of conditions and the following disclaimer.
9
 * 2. Redistributions in binary form must reproduce the above copyright
10
 *    notice, this list of conditions and the following disclaimer in the
11
 *    documentation and/or other materials provided with the distribution.
12
 *
13
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
14
 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
15
 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
16
 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
17
 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
18
 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
19
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
20
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
21
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
22
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
23
 */
24
25
/* EVP wrapper for SHA256 */
26
27
#include "includes.h"
28
RCSID("$OpenBSD$");
29
30
#include <openssl/evp.h>
31
#include <sha2.h>
32
33
const EVP_MD *evp_ssh_sha256(void);
34
35
static int
36
ssh_sha256_init(EVP_MD_CTX *ctxt)
37
{
38
	SHA256_Init(ctxt->md_data);
39
	return (1);
40
}
41
42
static int
43
ssh_sha256_update(EVP_MD_CTX *ctxt, const void *data, unsigned long len)
44
{
45
	SHA256_Update(ctxt->md_data, data, len);
46
	return (1);
47
}
48
49
static int
50
ssh_sha256_final(EVP_MD_CTX *ctxt, unsigned char *digest)
51
{
52
	SHA256_Final(digest, ctxt->md_data);
53
	return (1);
54
}
55
56
static int
57
ssh_sha256_cleanup(EVP_MD_CTX *ctxt)
58
{
59
	memset(ctxt->md_data, 0, sizeof(SHA256_CTX));
60
	return (1);
61
}
62
63
const EVP_MD *
64
evp_ssh_sha256(void)
65
{
66
	static EVP_MD ssh_sha256;
67
68
	memset(&ssh_sha256, 0, sizeof(ssh_sha256));
69
	ssh_sha256.type = NID_undef;
70
	ssh_sha256.md_size = SHA256_DIGEST_LENGTH;
71
	ssh_sha256.init = ssh_sha256_init;
72
	ssh_sha256.update = ssh_sha256_update;
73
	ssh_sha256.final = ssh_sha256_final;
74
	ssh_sha256.cleanup = ssh_sha256_cleanup;
75
	ssh_sha256.block_size = SHA256_BLOCK_LENGTH;
76
	ssh_sha256.ctx_size = sizeof(SHA256_CTX);
77
78
	return (&ssh_sha256);
79
}
(-)monitor.c (-1 / +6 lines)
Lines 473-479 mm_answer_sign(int sock, Buffer *m) Link Here
473
	keyid = buffer_get_int(m);
473
	keyid = buffer_get_int(m);
474
	p = buffer_get_string(m, &datlen);
474
	p = buffer_get_string(m, &datlen);
475
475
476
	if (datlen != 20)
476
	/*
477
	 * Supported KEX types will only return SHA1 (20 byte) or 
478
	 * SHA256 (32 byte) hashes
479
	 */
480
	if (datlen != 20 && datlen != 32)
477
		fatal("%s: data length incorrect: %u", __func__, datlen);
481
		fatal("%s: data length incorrect: %u", __func__, datlen);
478
482
479
	/* save session id, it will be passed on the first call */
483
	/* save session id, it will be passed on the first call */
Lines 1375-1380 mm_get_kex(Buffer *m) Link Here
1375
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1379
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1376
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1380
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1377
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1381
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1382
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1378
	kex->server = 1;
1383
	kex->server = 1;
1379
	kex->hostkey_type = buffer_get_int(m);
1384
	kex->hostkey_type = buffer_get_int(m);
1380
	kex->kex_type = buffer_get_int(m);
1385
	kex->kex_type = buffer_get_int(m);
(-)myproposal.h (-3 / +5 lines)
Lines 23-31 Link Here
23
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
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.
24
 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
25
 */
26
#define KEX_DEFAULT_KEX		"diffie-hellman-group-exchange-sha1," \
26
#define KEX_DEFAULT_KEX		\
27
	"diffie-hellman-group14-sha1," \
27
	"diffie-hellman-group-exchange-sha256," \
28
	"diffie-hellman-group1-sha1"
28
	"diffie-hellman-group-exchange-sha1," \
29
 	"diffie-hellman-group14-sha1," \
30
 	"diffie-hellman-group1-sha1"
29
#define	KEX_DEFAULT_PK_ALG	"ssh-rsa,ssh-dss"
31
#define	KEX_DEFAULT_PK_ALG	"ssh-rsa,ssh-dss"
30
#define	KEX_DEFAULT_ENCRYPT \
32
#define	KEX_DEFAULT_ENCRYPT \
31
	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
33
	"aes128-cbc,3des-cbc,blowfish-cbc,cast128-cbc," \
(-)ssh-keyscan.c (+1 lines)
Lines 341-346 keygrab_ssh2(con *c) Link Here
341
	c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
341
	c->c_kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
342
	c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
342
	c->c_kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
343
	c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
343
	c->c_kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
344
	c->c_kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
344
	c->c_kex->verify_host_key = hostjump;
345
	c->c_kex->verify_host_key = hostjump;
345
346
346
	if (!(j = setjmp(kexjmp))) {
347
	if (!(j = setjmp(kexjmp))) {
(-)sshconnect2.c (+1 lines)
Lines 120-125 ssh_kex2(char *host, struct sockaddr *ho Link Here
120
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
120
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_client;
121
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
121
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_client;
122
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
122
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
123
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
123
	kex->client_version_string=client_version_string;
124
	kex->client_version_string=client_version_string;
124
	kex->server_version_string=server_version_string;
125
	kex->server_version_string=server_version_string;
125
	kex->verify_host_key=&verify_host_key_callback;
126
	kex->verify_host_key=&verify_host_key_callback;
(-)sshd.c (+1 lines)
Lines 1910-1915 do_ssh2_kex(void) Link Here
1910
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1910
	kex->kex[KEX_DH_GRP1_SHA1] = kexdh_server;
1911
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1911
	kex->kex[KEX_DH_GRP14_SHA1] = kexdh_server;
1912
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1912
	kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
1913
	kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
1913
	kex->server = 1;
1914
	kex->server = 1;
1914
	kex->client_version_string=client_version_string;
1915
	kex->client_version_string=client_version_string;
1915
	kex->server_version_string=server_version_string;
1916
	kex->server_version_string=server_version_string;
(-)lib/Makefile (-1 / +1 lines)
Lines 11-17 SRCS= authfd.c authfile.c bufaux.c buffe Link Here
11
	key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \
11
	key.c dispatch.c kex.c mac.c uidswap.c uuencode.c misc.c \
12
	ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
12
	ssh-dss.c ssh-rsa.c dh.c kexdh.c kexgex.c \
13
	kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c \
13
	kexdhc.c kexgexc.c scard.c msg.c progressmeter.c dns.c \
14
	monitor_fdpass.c
14
	monitor_fdpass.c md-sha256.c
15
15
16
DEBUGLIBS= no
16
DEBUGLIBS= no
17
NOPROFILE= yes
17
NOPROFILE= yes

Return to bug 1023