summaryrefslogtreecommitdiff
path: root/kexc25519.c
diff options
context:
space:
mode:
authorColin Watson <cjwatson@debian.org>2015-08-19 14:23:51 +0100
committerColin Watson <cjwatson@debian.org>2015-08-19 16:48:11 +0100
commit0f0841b2d28b7463267d4d91577e72e3340a1d3a (patch)
treeba55fcd2b6e2cc22b30f5afb561dbb3da4c8b6c7 /kexc25519.c
parentf2a5f5dae656759efb0b76c3d94890b65c197a02 (diff)
parent8698446b972003b63dfe5dcbdb86acfe986afb85 (diff)
New upstream release (6.8p1).
Diffstat (limited to 'kexc25519.c')
-rw-r--r--kexc25519.c94
1 files changed, 50 insertions, 44 deletions
diff --git a/kexc25519.c b/kexc25519.c
index e3afa0055..b6e6c4010 100644
--- a/kexc25519.c
+++ b/kexc25519.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: kexc25519.c,v 1.7 2014/05/02 03:27:54 djm Exp $ */ 1/* $OpenBSD: kexc25519.c,v 1.8 2015/01/19 20:16:15 markus Exp $ */
2/* 2/*
3 * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. 3 * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
4 * Copyright (c) 2010 Damien Miller. All rights reserved. 4 * Copyright (c) 2010 Damien Miller. All rights reserved.
@@ -35,13 +35,14 @@
35#include <openssl/bn.h> 35#include <openssl/bn.h>
36#include <openssl/evp.h> 36#include <openssl/evp.h>
37 37
38#include "buffer.h" 38#include "sshbuf.h"
39#include "ssh2.h" 39#include "ssh2.h"
40#include "key.h" 40#include "sshkey.h"
41#include "cipher.h" 41#include "cipher.h"
42#include "kex.h" 42#include "kex.h"
43#include "log.h" 43#include "log.h"
44#include "digest.h" 44#include "digest.h"
45#include "ssherr.h"
45 46
46extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], 47extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
47 const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) 48 const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])
@@ -58,65 +59,70 @@ kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])
58 crypto_scalarmult_curve25519(pub, key, basepoint); 59 crypto_scalarmult_curve25519(pub, key, basepoint);
59} 60}
60 61
61void 62int
62kexc25519_shared_key(const u_char key[CURVE25519_SIZE], 63kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
63 const u_char pub[CURVE25519_SIZE], Buffer *out) 64 const u_char pub[CURVE25519_SIZE], struct sshbuf *out)
64{ 65{
65 u_char shared_key[CURVE25519_SIZE]; 66 u_char shared_key[CURVE25519_SIZE];
67 int r;
66 68
67 crypto_scalarmult_curve25519(shared_key, key, pub); 69 crypto_scalarmult_curve25519(shared_key, key, pub);
68#ifdef DEBUG_KEXECDH 70#ifdef DEBUG_KEXECDH
69 dump_digest("shared secret", shared_key, CURVE25519_SIZE); 71 dump_digest("shared secret", shared_key, CURVE25519_SIZE);
70#endif 72#endif
71 buffer_clear(out); 73 sshbuf_reset(out);
72 buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); 74 r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE);
73 explicit_bzero(shared_key, CURVE25519_SIZE); 75 explicit_bzero(shared_key, CURVE25519_SIZE);
76 return r;
74} 77}
75 78
76void 79int
77kex_c25519_hash( 80kex_c25519_hash(
78 int hash_alg, 81 int hash_alg,
79 char *client_version_string, 82 const char *client_version_string,
80 char *server_version_string, 83 const char *server_version_string,
81 char *ckexinit, int ckexinitlen, 84 const char *ckexinit, size_t ckexinitlen,
82 char *skexinit, int skexinitlen, 85 const char *skexinit, size_t skexinitlen,
83 u_char *serverhostkeyblob, int sbloblen, 86 const u_char *serverhostkeyblob, size_t sbloblen,
84 const u_char client_dh_pub[CURVE25519_SIZE], 87 const u_char client_dh_pub[CURVE25519_SIZE],
85 const u_char server_dh_pub[CURVE25519_SIZE], 88 const u_char server_dh_pub[CURVE25519_SIZE],
86 const u_char *shared_secret, u_int secretlen, 89 const u_char *shared_secret, size_t secretlen,
87 u_char **hash, u_int *hashlen) 90 u_char *hash, size_t *hashlen)
88{ 91{
89 Buffer b; 92 struct sshbuf *b;
90 static u_char digest[SSH_DIGEST_MAX_LENGTH]; 93 int r;
91 94
92 buffer_init(&b); 95 if (*hashlen < ssh_digest_bytes(hash_alg))
93 buffer_put_cstring(&b, client_version_string); 96 return SSH_ERR_INVALID_ARGUMENT;
94 buffer_put_cstring(&b, server_version_string); 97 if ((b = sshbuf_new()) == NULL)
95 98 return SSH_ERR_ALLOC_FAIL;
96 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ 99 if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 ||
97 buffer_put_int(&b, ckexinitlen+1); 100 (r = sshbuf_put_cstring(b, server_version_string)) < 0 ||
98 buffer_put_char(&b, SSH2_MSG_KEXINIT); 101 /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
99 buffer_append(&b, ckexinit, ckexinitlen); 102 (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 ||
100 buffer_put_int(&b, skexinitlen+1); 103 (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
101 buffer_put_char(&b, SSH2_MSG_KEXINIT); 104 (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 ||
102 buffer_append(&b, skexinit, skexinitlen); 105 (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 ||
103 106 (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 ||
104 buffer_put_string(&b, serverhostkeyblob, sbloblen); 107 (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 ||
105 buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE); 108 (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 ||
106 buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE); 109 (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 ||
107 buffer_append(&b, shared_secret, secretlen); 110 (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 ||
108 111 (r = sshbuf_put(b, shared_secret, secretlen)) < 0) {
112 sshbuf_free(b);
113 return r;
114 }
109#ifdef DEBUG_KEX 115#ifdef DEBUG_KEX
110 buffer_dump(&b); 116 sshbuf_dump(b, stderr);
111#endif 117#endif
112 if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) 118 if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) {
113 fatal("%s: digest_buffer failed", __func__); 119 sshbuf_free(b);
114 120 return SSH_ERR_LIBCRYPTO_ERROR;
115 buffer_free(&b); 121 }
116 122 sshbuf_free(b);
123 *hashlen = ssh_digest_bytes(hash_alg);
117#ifdef DEBUG_KEX 124#ifdef DEBUG_KEX
118 dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); 125 dump_digest("hash", hash, *hashlen);
119#endif 126#endif
120 *hash = digest; 127 return 0;
121 *hashlen = ssh_digest_bytes(hash_alg);
122} 128}