Annotation of src/usr.bin/ssh/kexc25519.c, Revision 1.2
1.2 ! markus 1: /* $OpenBSD: myproposal.h,v 1.33 2013/11/02 21:59:15 markus Exp $ */
1.1 markus 2: /*
3: * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved.
4: * Copyright (c) 2010 Damien Miller. All rights reserved.
5: * Copyright (c) 2013 Aris Adamantiadis. All rights reserved.
6: *
7: * Redistribution and use in source and binary forms, with or without
8: * modification, are permitted provided that the following conditions
9: * are met:
10: * 1. Redistributions of source code must retain the above copyright
11: * notice, this list of conditions and the following disclaimer.
12: * 2. Redistributions in binary form must reproduce the above copyright
13: * notice, this list of conditions and the following disclaimer in the
14: * documentation and/or other materials provided with the distribution.
15: *
16: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17: * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21: * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22: * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23: * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24: * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25: * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26: */
27:
28: #include <sys/types.h>
29:
30: #include <signal.h>
31: #include <string.h>
32:
33: #include <openssl/bn.h>
34: #include <openssl/evp.h>
35:
36: #include "buffer.h"
37: #include "ssh2.h"
38: #include "key.h"
39: #include "cipher.h"
40: #include "kex.h"
41: #include "log.h"
42:
43: extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE],
44: const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE])
45: __attribute__((__bounded__(__minbytes__, 1, CURVE25519_SIZE)))
46: __attribute__((__bounded__(__minbytes__, 2, CURVE25519_SIZE)))
47: __attribute__((__bounded__(__minbytes__, 3, CURVE25519_SIZE)));
48:
49: void
50: kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE])
51: {
52: static const u_char basepoint[CURVE25519_SIZE] = {9};
53:
54: arc4random_buf(key, CURVE25519_SIZE);
55: crypto_scalarmult_curve25519(pub, key, basepoint);
56: }
57:
58: BIGNUM *
59: kexc25519_shared_key(const u_char key[CURVE25519_SIZE],
60: const u_char pub[CURVE25519_SIZE])
61: {
62: u_char shared_key[CURVE25519_SIZE];
63: BIGNUM *shared_secret;
64:
65: crypto_scalarmult_curve25519(shared_key, key, pub);
66: #ifdef DEBUG_KEXECDH
67: dump_digest("shared secret", shared_key, CURVE25519_SIZE);
68: #endif
69: if ((shared_secret = BN_new()) == NULL)
70: fatal("%s: BN_new failed", __func__);
71: if (BN_bin2bn(shared_key, sizeof(shared_key), shared_secret) == NULL)
72: fatal("%s: BN_bin2bn failed", __func__);
73: memset(shared_key, 0, CURVE25519_SIZE); /* XXX explicit_bzero() */
74: return (shared_secret);
75: }
76:
77: void
78: kex_c25519_hash(
79: const EVP_MD *evp_md,
80: char *client_version_string,
81: char *server_version_string,
82: char *ckexinit, int ckexinitlen,
83: char *skexinit, int skexinitlen,
84: u_char *serverhostkeyblob, int sbloblen,
85: const u_char client_dh_pub[CURVE25519_SIZE],
86: const u_char server_dh_pub[CURVE25519_SIZE],
87: const BIGNUM *shared_secret,
88: u_char **hash, u_int *hashlen)
89: {
90: Buffer b;
91: EVP_MD_CTX md;
92: static u_char digest[EVP_MAX_MD_SIZE];
93:
94: buffer_init(&b);
95: buffer_put_cstring(&b, client_version_string);
96: buffer_put_cstring(&b, server_version_string);
97:
98: /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */
99: buffer_put_int(&b, ckexinitlen+1);
100: buffer_put_char(&b, SSH2_MSG_KEXINIT);
101: buffer_append(&b, ckexinit, ckexinitlen);
102: buffer_put_int(&b, skexinitlen+1);
103: buffer_put_char(&b, SSH2_MSG_KEXINIT);
104: buffer_append(&b, skexinit, skexinitlen);
105:
106: buffer_put_string(&b, serverhostkeyblob, sbloblen);
107: buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE);
108: buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE);
109: buffer_put_bignum2(&b, shared_secret);
110:
111: #ifdef DEBUG_KEX
112: buffer_dump(&b);
113: #endif
114: EVP_DigestInit(&md, evp_md);
115: EVP_DigestUpdate(&md, buffer_ptr(&b), buffer_len(&b));
116: EVP_DigestFinal(&md, digest, NULL);
117:
118: buffer_free(&b);
119:
120: #ifdef DEBUG_KEX
121: dump_digest("hash", digest, EVP_MD_size(evp_md));
122: #endif
123: *hash = digest;
124: *hashlen = EVP_MD_size(evp_md);
125: }