diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2016-01-22 20:41:56 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2016-01-22 20:41:56 +0000 |
commit | d9b9dae1a954c5a277eada994d268f88eb5f3f20 (patch) | |
tree | 10bd7a9c1abe1f278df85958745a2a09074c1dda /crypto/openssh/kexc25519.c | |
parent | 5e23bfeb2dc28a70a77ea119c74c4a69ad030237 (diff) | |
parent | fa28b6e7dab231f5c6ae7c3b6a3ef4a38785eefe (diff) | |
download | src-test2-d9b9dae1a954c5a277eada994d268f88eb5f3f20.tar.gz src-test2-d9b9dae1a954c5a277eada994d268f88eb5f3f20.zip |
Notes
Diffstat (limited to 'crypto/openssh/kexc25519.c')
-rw-r--r-- | crypto/openssh/kexc25519.c | 99 |
1 files changed, 55 insertions, 44 deletions
diff --git a/crypto/openssh/kexc25519.c b/crypto/openssh/kexc25519.c index ee79b4327ee1..8d8cd4a2bae9 100644 --- a/crypto/openssh/kexc25519.c +++ b/crypto/openssh/kexc25519.c @@ -1,4 +1,4 @@ -/* $OpenBSD: kexc25519.c,v 1.5 2014/01/31 16:39:19 tedu Exp $ */ +/* $OpenBSD: kexc25519.c,v 1.9 2015/03/26 07:00:04 djm Exp $ */ /* * Copyright (c) 2001, 2013 Markus Friedl. All rights reserved. * Copyright (c) 2010 Damien Miller. All rights reserved. @@ -35,13 +35,14 @@ #include <openssl/bn.h> #include <openssl/evp.h> -#include "buffer.h" +#include "sshbuf.h" #include "ssh2.h" -#include "key.h" +#include "sshkey.h" #include "cipher.h" #include "kex.h" #include "log.h" #include "digest.h" +#include "ssherr.h" extern int crypto_scalarmult_curve25519(u_char a[CURVE25519_SIZE], const u_char b[CURVE25519_SIZE], const u_char c[CURVE25519_SIZE]) @@ -58,65 +59,75 @@ kexc25519_keygen(u_char key[CURVE25519_SIZE], u_char pub[CURVE25519_SIZE]) crypto_scalarmult_curve25519(pub, key, basepoint); } -void +int kexc25519_shared_key(const u_char key[CURVE25519_SIZE], - const u_char pub[CURVE25519_SIZE], Buffer *out) + const u_char pub[CURVE25519_SIZE], struct sshbuf *out) { u_char shared_key[CURVE25519_SIZE]; + int r; + + /* Check for all-zero public key */ + explicit_bzero(shared_key, CURVE25519_SIZE); + if (timingsafe_bcmp(pub, shared_key, CURVE25519_SIZE) == 0) + return SSH_ERR_KEY_INVALID_EC_VALUE; crypto_scalarmult_curve25519(shared_key, key, pub); #ifdef DEBUG_KEXECDH dump_digest("shared secret", shared_key, CURVE25519_SIZE); #endif - buffer_clear(out); - buffer_put_bignum2_from_string(out, shared_key, CURVE25519_SIZE); + sshbuf_reset(out); + r = sshbuf_put_bignum2_bytes(out, shared_key, CURVE25519_SIZE); explicit_bzero(shared_key, CURVE25519_SIZE); + return r; } -void +int kex_c25519_hash( int hash_alg, - char *client_version_string, - char *server_version_string, - char *ckexinit, int ckexinitlen, - char *skexinit, int skexinitlen, - u_char *serverhostkeyblob, int sbloblen, + const char *client_version_string, + const char *server_version_string, + const char *ckexinit, size_t ckexinitlen, + const char *skexinit, size_t skexinitlen, + const u_char *serverhostkeyblob, size_t sbloblen, const u_char client_dh_pub[CURVE25519_SIZE], const u_char server_dh_pub[CURVE25519_SIZE], - const u_char *shared_secret, u_int secretlen, - u_char **hash, u_int *hashlen) + const u_char *shared_secret, size_t secretlen, + u_char *hash, size_t *hashlen) { - Buffer b; - static u_char digest[SSH_DIGEST_MAX_LENGTH]; - - buffer_init(&b); - buffer_put_cstring(&b, client_version_string); - buffer_put_cstring(&b, server_version_string); - - /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ - buffer_put_int(&b, ckexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, ckexinit, ckexinitlen); - buffer_put_int(&b, skexinitlen+1); - buffer_put_char(&b, SSH2_MSG_KEXINIT); - buffer_append(&b, skexinit, skexinitlen); - - buffer_put_string(&b, serverhostkeyblob, sbloblen); - buffer_put_string(&b, client_dh_pub, CURVE25519_SIZE); - buffer_put_string(&b, server_dh_pub, CURVE25519_SIZE); - buffer_append(&b, shared_secret, secretlen); - + struct sshbuf *b; + int r; + + if (*hashlen < ssh_digest_bytes(hash_alg)) + return SSH_ERR_INVALID_ARGUMENT; + if ((b = sshbuf_new()) == NULL) + return SSH_ERR_ALLOC_FAIL; + if ((r = sshbuf_put_cstring(b, client_version_string)) < 0 || + (r = sshbuf_put_cstring(b, server_version_string)) < 0 || + /* kexinit messages: fake header: len+SSH2_MSG_KEXINIT */ + (r = sshbuf_put_u32(b, ckexinitlen+1)) < 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || + (r = sshbuf_put(b, ckexinit, ckexinitlen)) < 0 || + (r = sshbuf_put_u32(b, skexinitlen+1)) < 0 || + (r = sshbuf_put_u8(b, SSH2_MSG_KEXINIT)) < 0 || + (r = sshbuf_put(b, skexinit, skexinitlen)) < 0 || + (r = sshbuf_put_string(b, serverhostkeyblob, sbloblen)) < 0 || + (r = sshbuf_put_string(b, client_dh_pub, CURVE25519_SIZE)) < 0 || + (r = sshbuf_put_string(b, server_dh_pub, CURVE25519_SIZE)) < 0 || + (r = sshbuf_put(b, shared_secret, secretlen)) < 0) { + sshbuf_free(b); + return r; + } #ifdef DEBUG_KEX - buffer_dump(&b); + sshbuf_dump(b, stderr); #endif - if (ssh_digest_buffer(hash_alg, &b, digest, sizeof(digest)) != 0) - fatal("%s: digest_buffer failed", __func__); - - buffer_free(&b); - + if (ssh_digest_buffer(hash_alg, b, hash, *hashlen) != 0) { + sshbuf_free(b); + return SSH_ERR_LIBCRYPTO_ERROR; + } + sshbuf_free(b); + *hashlen = ssh_digest_bytes(hash_alg); #ifdef DEBUG_KEX - dump_digest("hash", digest, ssh_digest_bytes(hash_alg)); + dump_digest("hash", hash, *hashlen); #endif - *hash = digest; - *hashlen = ssh_digest_bytes(hash_alg); + return 0; } |