Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
970b919e76 | ||
|
|
d49bfc76c0 | ||
|
|
dea5692a68 | ||
|
|
46325ab0f9 | ||
|
|
917e85b9cc | ||
|
|
a9b364ae91 | ||
|
|
8d9a043966 | ||
|
|
afd88a7d03 | ||
|
|
7fc4e7cd73 | ||
|
|
3eeda15eb9 | ||
|
|
8e4bd6ebdb | ||
|
|
aab12549a9 | ||
|
|
be8026caf9 | ||
|
|
7d5b6c7ec3 | ||
|
|
d58ae05bb7 | ||
|
|
3b4adf2018 | ||
|
|
ef95df4089 | ||
|
|
de4bcb51c8 | ||
|
|
4b8d141ec1 |
No files matched your search
@@ -17,9 +17,9 @@ jobs:
|
||||
target:
|
||||
- ubuntu-20.04
|
||||
- ubuntu-22.04
|
||||
- macos-12
|
||||
- macos-13
|
||||
- macos-14
|
||||
- macos-15
|
||||
- windows-2019
|
||||
- windows-2022
|
||||
config: [default]
|
||||
@@ -100,9 +100,9 @@ jobs:
|
||||
- { target: ubuntu-22.04, config: selinux }
|
||||
- { target: ubuntu-22.04, config: kitchensink }
|
||||
- { target: ubuntu-22.04, config: without-openssl }
|
||||
- { target: macos-12, config: pam }
|
||||
- { target: macos-13, config: pam }
|
||||
- { target: macos-14, config: pam }
|
||||
- { target: macos-15, config: pam }
|
||||
runs-on: ${{ matrix.target }}
|
||||
steps:
|
||||
- name: set cygwin git params
|
||||
|
||||
@@ -28,6 +28,7 @@ ssh-keyscan
|
||||
ssh-keysign
|
||||
ssh-pkcs11-helper
|
||||
ssh-sk-helper
|
||||
sshd-session
|
||||
sshd
|
||||
!regress/misc/fuzz-harness/Makefile
|
||||
!regress/unittests/sshsig/Makefile
|
||||
|
||||
+3
-3
@@ -99,7 +99,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
|
||||
canohost.o channels.o cipher.o cipher-aes.o cipher-aesctr.o \
|
||||
cleanup.o \
|
||||
compat.o fatal.o hostfile.o \
|
||||
log.o match.o moduli.o nchan.o packet.o \
|
||||
log.o match.o moduli.o nchan.o kem.o packet.o \
|
||||
readpass.o ttymodes.o xmalloc.o addr.o addrmatch.o \
|
||||
atomicio.o dispatch.o mac.o misc.o utf8.o \
|
||||
monitor_fdpass.o rijndael.o ssh-dss.o ssh-ecdsa.o ssh-ecdsa-sk.o \
|
||||
@@ -117,7 +117,7 @@ LIBSSH_OBJS=${LIBOPENSSH_OBJS} \
|
||||
|
||||
SKOBJS= ssh-sk-client.o
|
||||
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o \
|
||||
SSHOBJS= ssh.o readconf.o clientloop.o sshtty.o kem.o \
|
||||
sshconnect.o sshconnect2.o mux.o $(SKOBJS)
|
||||
|
||||
SSHDOBJS=sshd.o \
|
||||
@@ -267,7 +267,7 @@ $(MANPAGES): $(MANPAGES_IN)
|
||||
$(FIXPATHSCMD) $${manpage} | $(FIXALGORITHMSCMD) > $@; \
|
||||
fi
|
||||
|
||||
$(CONFIGFILES): $(CONFIGFILES_IN)
|
||||
$(CONFIGFILES): $(CONFIGFILES_IN) Makefile
|
||||
conffile=`echo $@ | sed 's/.out$$//'`; \
|
||||
$(FIXPATHSCMD) $(srcdir)/$${conffile} > $@
|
||||
|
||||
|
||||
+15
@@ -363,10 +363,22 @@
|
||||
don't. */
|
||||
#undef HAVE_DECL_HOWMANY
|
||||
|
||||
/* Define to 1 if you have the declaration of `htole64', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_HTOLE64
|
||||
|
||||
/* Define to 1 if you have the declaration of `h_errno', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_H_ERRNO
|
||||
|
||||
/* Define to 1 if you have the declaration of `le32toh', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_LE32TOH
|
||||
|
||||
/* Define to 1 if you have the declaration of `le64toh', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_LE64TOH
|
||||
|
||||
/* Define to 1 if you have the declaration of `loginfailed', and to 0 if you
|
||||
don't. */
|
||||
#undef HAVE_DECL_LOGINFAILED
|
||||
@@ -1736,6 +1748,9 @@
|
||||
/* Set this to your mail directory if you do not have _PATH_MAILDIR */
|
||||
#undef MAIL_DIRECTORY
|
||||
|
||||
/* Define if your compiler lacks __builtin_popcount */
|
||||
#undef MISSING_BUILTIN_POPCOUNT
|
||||
|
||||
/* Need setpgrp to for controlling tty */
|
||||
#undef NEED_SETPGRP
|
||||
|
||||
|
||||
@@ -11325,6 +11325,65 @@ then :
|
||||
fi
|
||||
|
||||
|
||||
ac_fn_check_decl "$LINENO" "le32toh" "ac_cv_have_decl_le32toh" "
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_le32toh" = xyes
|
||||
then :
|
||||
ac_have_decl=1
|
||||
else $as_nop
|
||||
ac_have_decl=0
|
||||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_LE32TOH $ac_have_decl" >>confdefs.h
|
||||
ac_fn_check_decl "$LINENO" "le64toh" "ac_cv_have_decl_le64toh" "
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_le64toh" = xyes
|
||||
then :
|
||||
ac_have_decl=1
|
||||
else $as_nop
|
||||
ac_have_decl=0
|
||||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_LE64TOH $ac_have_decl" >>confdefs.h
|
||||
ac_fn_check_decl "$LINENO" "htole64" "ac_cv_have_decl_htole64" "
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
|
||||
" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_htole64" = xyes
|
||||
then :
|
||||
ac_have_decl=1
|
||||
else $as_nop
|
||||
ac_have_decl=0
|
||||
fi
|
||||
printf "%s\n" "#define HAVE_DECL_HTOLE64 $ac_have_decl" >>confdefs.h
|
||||
|
||||
|
||||
# On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h]
|
||||
# to be included first.
|
||||
ac_fn_c_check_header_compile "$LINENO" "sys/audit.h" "ac_cv_header_sys_audit_h" "
|
||||
@@ -16726,6 +16785,40 @@ then :
|
||||
fi
|
||||
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether compiler supports __builtin_popcount" >&5
|
||||
printf %s "checking whether compiler supports __builtin_popcount... " >&6; }
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
int x = 123, y;
|
||||
y = __builtin_popcount(123);
|
||||
exit(y == 6 ? 0 : -1);
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5
|
||||
printf "%s\n" "yes" >&6; }
|
||||
else $as_nop
|
||||
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5
|
||||
printf "%s\n" "no" >&6; }
|
||||
|
||||
printf "%s\n" "#define MISSING_BUILTIN_POPCOUNT 1" >>confdefs.h
|
||||
|
||||
|
||||
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
|
||||
ac_fn_check_decl "$LINENO" "bzero" "ac_cv_have_decl_bzero" "$ac_includes_default" "$ac_c_undeclared_builtin_options" "CFLAGS"
|
||||
if test "x$ac_cv_have_decl_bzero" = xyes
|
||||
then :
|
||||
@@ -27710,3 +27803,4 @@ if test "$AUDIT_MODULE" = "bsm" ; then
|
||||
echo "WARNING: BSM audit support is currently considered EXPERIMENTAL."
|
||||
echo "See the Solaris section in README.platform for details."
|
||||
fi
|
||||
|
||||
@@ -536,6 +536,18 @@ AC_CHECK_HEADERS([ \
|
||||
wchar.h \
|
||||
])
|
||||
|
||||
AC_CHECK_DECLS([le32toh, le64toh, htole64], [], [], [
|
||||
#ifdef HAVE_SYS_TYPES_H
|
||||
# include <sys/types.h>
|
||||
#endif
|
||||
#ifdef HAVE_STDINT_H
|
||||
# include <stdint.h>
|
||||
#endif
|
||||
#ifdef HAVE_ENDIAN_H
|
||||
# include <endian.h>
|
||||
#endif
|
||||
])
|
||||
|
||||
# On some platforms (eg SunOS4) sys/audit.h requires sys/[time|types|label.h]
|
||||
# to be included first.
|
||||
AC_CHECK_HEADERS([sys/audit.h], [], [], [
|
||||
@@ -2029,6 +2041,19 @@ AC_CHECK_FUNCS([ \
|
||||
warn \
|
||||
])
|
||||
|
||||
AC_MSG_CHECKING([whether compiler supports __builtin_popcount])
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[
|
||||
#include <stdlib.h>
|
||||
]],
|
||||
[[ int x = 123, y;
|
||||
y = __builtin_popcount(123);
|
||||
exit(y == 6 ? 0 : -1); ]])],
|
||||
[ AC_MSG_RESULT([yes]) ], [
|
||||
AC_MSG_RESULT([no])
|
||||
AC_DEFINE([MISSING_BUILTIN_POPCOUNT], [1], [Define if your compiler lacks __builtin_popcount])
|
||||
]
|
||||
)
|
||||
|
||||
AC_CHECK_DECLS([bzero, memmem])
|
||||
|
||||
dnl Wide character support.
|
||||
|
||||
@@ -646,7 +646,9 @@ struct winsize {
|
||||
# endif /* WORDS_BIGENDIAN */
|
||||
#endif /* BYTE_ORDER */
|
||||
|
||||
#ifndef HAVE_ENDIAN_H
|
||||
#if (defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0) || \
|
||||
(defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0) || \
|
||||
(defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0)
|
||||
# define openssh_swap32(v) \
|
||||
(uint32_t)(((uint32_t)(v) & 0xff) << 24 | \
|
||||
((uint32_t)(v) & 0xff00) << 8 | \
|
||||
@@ -662,13 +664,25 @@ struct winsize {
|
||||
((uint64_t)(v) & 0xff000000000000ULL) >> 40 | \
|
||||
((uint64_t)(v) & 0xff00000000000000ULL) >> 56)
|
||||
# ifdef WORDS_BIGENDIAN
|
||||
# define le32toh(v) (openssh_swap32(v))
|
||||
# define le64toh(v) (openssh_swap64(v))
|
||||
# define htole64(v) (openssh_swap64(v))
|
||||
# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0
|
||||
# define le32toh(v) (openssh_swap32(v))
|
||||
# endif
|
||||
# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0
|
||||
# define le64toh(v) (openssh_swap64(v))
|
||||
# endif
|
||||
# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0
|
||||
# define htole64(v) (openssh_swap64(v))
|
||||
# endif
|
||||
# else
|
||||
# define le32toh(v) ((uint32_t)v)
|
||||
# define le64toh(v) ((uint64_t)v)
|
||||
# define htole64(v) ((uint64_t)v)
|
||||
# if defined(HAVE_DECL_LE32TOH) && HAVE_DECL_LE32TOH == 0
|
||||
# define le32toh(v) ((uint32_t)v)
|
||||
# endif
|
||||
# if defined(HAVE_DECL_LE64TOH) && HAVE_DECL_LE64TOH == 0
|
||||
# define le64toh(v) ((uint64_t)v)
|
||||
# endif
|
||||
# if defined(HAVE_DECL_HTOLE64) && HAVE_DECL_HTOLE64 == 0
|
||||
# define htole64(v) ((uint64_t)v)
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,635 @@
|
||||
#include <sys/types.h>
|
||||
#include "packet.h"
|
||||
#include "kem.h"
|
||||
#include "log.h"
|
||||
#include "ssh2.h"
|
||||
#include "sshbuf.h"
|
||||
#include <openssl/core_names.h>
|
||||
|
||||
|
||||
static void dec2buf(char *, size_t, size_t);
|
||||
static size_t buf2dec(const unsigned char *, size_t);
|
||||
static int pubkey2sshbuf(struct sshbuf *, struct rsa_keys *);
|
||||
static int kem_rsa_keypair(struct kex *);
|
||||
static int kem_rsa_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **);
|
||||
|
||||
|
||||
void print_ossl_error(){
|
||||
unsigned long err = ERR_get_error();
|
||||
char e[256];
|
||||
ERR_error_string(err, e);
|
||||
debug("Error: %s", e);
|
||||
}
|
||||
|
||||
static int kem_rsa_keypair(struct kex *kex){
|
||||
int r;
|
||||
struct sshbuf *buf = NULL;
|
||||
struct rsa_keys *keys = NULL;
|
||||
|
||||
if ((buf = sshbuf_new()) == NULL){
|
||||
return SSH_ERR_ALLOC_FAIL;
|
||||
}
|
||||
|
||||
kex->keys_peer = NULL;
|
||||
//kex->keys_mine = keys;
|
||||
r = init_rsa_keys(&kex->keys_peer);
|
||||
if (r != 0)
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
|
||||
keys = kex->keys_mine;
|
||||
debug("Modulus: %s", keys->n);
|
||||
debug("Exponent: %s", keys->e);
|
||||
debug("Decryption: %s", keys->d);
|
||||
|
||||
/*
|
||||
* Send KEM packet to the peer
|
||||
* This packet contains our public key and the exponent e
|
||||
* Structure of the packet:
|
||||
* size_t len_n
|
||||
* unsigned char *n
|
||||
* size_t len_e
|
||||
* unsigned char *e
|
||||
*/
|
||||
if((r = pubkey2sshbuf(buf, keys)) != 0){
|
||||
sshbuf_free(buf);
|
||||
buf = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
kex->client_pub = buf;
|
||||
buf = NULL;
|
||||
r = 0;
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
|
||||
}
|
||||
int kem_rsa1024_keypair(struct kex *kex) {
|
||||
struct rsa_keys *keys = NULL;
|
||||
int r;
|
||||
|
||||
r = init_rsa_keys(&kex->keys_mine);
|
||||
if (r != 0)
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
|
||||
keys = kex->keys_mine;
|
||||
|
||||
/* Generate RSA keys */
|
||||
r = kem_gen_keys(keys, 1024);
|
||||
if (r != 0)
|
||||
fatal_r(r, "kem_gen_keys");
|
||||
|
||||
debug("Modulus: %s", keys->n);
|
||||
debug("Exponent: %s", keys->e);
|
||||
debug("Decryption: %s", keys->d);
|
||||
|
||||
return kem_rsa_keypair(kex);
|
||||
}
|
||||
int kem_rsa2048_keypair(struct kex *kex) {
|
||||
struct rsa_keys *keys = NULL;
|
||||
int r;
|
||||
|
||||
r = init_rsa_keys(&kex->keys_mine);
|
||||
if (r != 0)
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
|
||||
keys = kex->keys_mine;
|
||||
|
||||
/* Generate RSA keys */
|
||||
r = kem_gen_keys(keys, 2048);
|
||||
if (r != 0)
|
||||
fatal_r(r, "kem_gen_keys");
|
||||
|
||||
return kem_rsa_keypair(kex);
|
||||
}
|
||||
/*
|
||||
* This function put the public key and the exponent e
|
||||
* in the buf which will be send to the peer
|
||||
*/
|
||||
static int pubkey2sshbuf(struct sshbuf *buf, struct rsa_keys *keys){
|
||||
int r = 0;
|
||||
char b[sizeof(size_t)];
|
||||
dec2buf(b, 0, keys->len_n);
|
||||
if ((r = sshbuf_put(buf, b, sizeof(size_t))) != 0)
|
||||
return r;
|
||||
if ((r = sshbuf_put(buf, keys->n, keys->len_n)) != 0)
|
||||
return r;
|
||||
memset(b, 0, sizeof(size_t));
|
||||
dec2buf(b, 0, keys->len_e);
|
||||
if ((r = sshbuf_put(buf, b, sizeof(size_t))) != 0)
|
||||
return r;
|
||||
if ((r = sshbuf_put(buf, keys->e, keys->len_e)) != 0)
|
||||
return r;
|
||||
return r;
|
||||
}
|
||||
static int kem_rsa_enc(struct kex *kex, const struct sshbuf *client_pubkey, struct sshbuf **serverbuf, struct sshbuf **shared_secret) {
|
||||
struct sshbuf *buf = NULL;
|
||||
struct sshbuf *buf_kem = NULL;
|
||||
int r = 0;
|
||||
const u_char *clientpub;
|
||||
size_t len_n = 0, len_e = 0;
|
||||
char *rand = NULL;
|
||||
size_t randlen;
|
||||
struct rsa_keys *keys = NULL, *keys_peer = NULL;
|
||||
unsigned char *ciphertext = NULL;
|
||||
size_t clen;
|
||||
|
||||
*serverbuf = NULL;
|
||||
*shared_secret = NULL;
|
||||
|
||||
clientpub = sshbuf_ptr(client_pubkey);
|
||||
|
||||
/*
|
||||
* Extract the client's public key and store to the struct rsa_keys
|
||||
* The structure of client_pubkey is:
|
||||
* size_t len_n
|
||||
* unsigned char *n
|
||||
* size_t len_e
|
||||
* unsigned char *e
|
||||
*/
|
||||
kex->keys_peer = NULL;
|
||||
if ((r = init_rsa_keys(&kex->keys_peer)) != 0){
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
}
|
||||
|
||||
keys_peer = kex->keys_peer;
|
||||
|
||||
len_n = buf2dec(clientpub, 0);
|
||||
|
||||
if (!(keys_peer->n = (unsigned char*)malloc(len_n))){
|
||||
debug("failed to allocate modulus n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
memset(keys_peer->n, 0, len_n);
|
||||
memcpy(keys_peer->n, clientpub + sizeof(size_t), len_n);
|
||||
|
||||
// Get the exponent e
|
||||
len_e = buf2dec(clientpub, sizeof(size_t) + len_n);
|
||||
if(!(keys_peer->e = (unsigned char *)malloc(len_e)))
|
||||
return -1;
|
||||
keys_peer->len_n = len_n;
|
||||
|
||||
memset(keys_peer->e, 0, len_e);
|
||||
memcpy(keys_peer->e, clientpub + sizeof(size_t) + len_n + sizeof(size_t), len_e);
|
||||
keys_peer->len_e = len_e;
|
||||
|
||||
/* Generate the random key, then encrypt it with the client's pubkey */
|
||||
if ((r = generate_rand_key(&rand, &randlen)) != 0){
|
||||
debug("Failed to generate rand key");
|
||||
fatal_r(r, "generate_rand_key");
|
||||
}
|
||||
|
||||
/* Allocate buffer for the shared key */
|
||||
if((buf = sshbuf_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
debug("Failed init sshbuf");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate buffer for KEM which contains the encrypted random value key
|
||||
* and the server's public key
|
||||
*/
|
||||
if((buf_kem = sshbuf_new()) == NULL) {
|
||||
r = SSH_ERR_ALLOC_FAIL;
|
||||
debug("Failed init sshbuf");
|
||||
goto clean;
|
||||
}
|
||||
|
||||
/* Encrypt the data with the peer's public key
|
||||
* Structure of the message
|
||||
* size_t len_n
|
||||
* unsigned char *pubkey
|
||||
* size_t len_e
|
||||
* unsigned char *e
|
||||
* size_t len_rand
|
||||
* unsigned char *rand -> encrypted with client's pubkey
|
||||
*/
|
||||
keys = kex->keys_mine;
|
||||
if((r = pubkey2sshbuf(buf_kem, keys)) != 0){
|
||||
sshbuf_free(buf);
|
||||
sshbuf_free(buf_kem);
|
||||
buf = NULL;
|
||||
return r;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encrypt the random key value with the client's public key
|
||||
* and put to buf_kem
|
||||
*/
|
||||
if((r = build_pkey(kex->keys_peer)) != 0)
|
||||
goto clean;
|
||||
if((r = encrypt_key(rand, randlen, kex->keys_peer, &ciphertext, &clen)) != 0)
|
||||
goto clean;
|
||||
|
||||
if ((r = sshbuf_put(buf_kem, ciphertext, clen)) != 0)
|
||||
goto clean;
|
||||
|
||||
if ((r = sshbuf_put_string(buf, rand, randlen)) != 0)
|
||||
goto clean;
|
||||
|
||||
*serverbuf = buf_kem;
|
||||
*shared_secret = buf;
|
||||
buf_kem = NULL;
|
||||
buf = NULL;
|
||||
|
||||
clean:
|
||||
sshbuf_free(buf);
|
||||
sshbuf_free(buf_kem);
|
||||
/* We don't use it anymore, we clean it */
|
||||
EVP_PKEY_free(keys->pkey);
|
||||
EVP_PKEY_free(kex->keys_peer->pkey);
|
||||
free(kex->keys_mine);
|
||||
free(kex->keys_peer);
|
||||
return r;
|
||||
}
|
||||
int kem_rsa2048_enc(struct kex *kex, const struct sshbuf *client_pubkey, struct sshbuf **serverbuf, struct sshbuf **shared_secret) {
|
||||
int r;
|
||||
struct rsa_keys *keys = NULL;
|
||||
|
||||
kex->keys_mine = NULL;
|
||||
r = init_rsa_keys(&kex->keys_mine);
|
||||
if (r != 0){
|
||||
debug("Failed to init rsa");
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
}
|
||||
keys = kex->keys_mine;
|
||||
r = kem_gen_keys(keys, 2048);
|
||||
if (r != 0)
|
||||
fatal_r(r, "kem_gen_keys");
|
||||
|
||||
debug("Modulus server: %s", keys->n);
|
||||
debug("Exponent server: %s", keys->e);
|
||||
debug("Decryption server: %s", keys->d);
|
||||
|
||||
return kem_rsa_enc(kex, client_pubkey, serverbuf, shared_secret);
|
||||
}
|
||||
int kem_rsa1024_enc(struct kex *kex, const struct sshbuf *client_pubkey, struct sshbuf **serverbuf, struct sshbuf **shared_secret) {
|
||||
int r;
|
||||
struct rsa_keys *keys = NULL;
|
||||
|
||||
kex->keys_mine = NULL;
|
||||
r = init_rsa_keys(&kex->keys_mine);
|
||||
if (r != 0){
|
||||
debug("Failed to init rsa");
|
||||
fatal_r(r, "init_rsa_keys");
|
||||
}
|
||||
keys = kex->keys_mine;
|
||||
r = kem_gen_keys(keys, 1024);
|
||||
if (r != 0)
|
||||
fatal_r(r, "kem_gen_keys");
|
||||
|
||||
debug("Modulus server: %s", keys->n);
|
||||
debug("Exponent server: %s", keys->e);
|
||||
debug("Decryption server: %s", keys->d);
|
||||
|
||||
return kem_rsa_enc(kex, client_pubkey, serverbuf, shared_secret);
|
||||
}
|
||||
|
||||
int kem_rsa_dec(struct kex *kex, struct sshbuf *serverbuf, struct sshbuf **shared_secret) {
|
||||
struct sshbuf *buf = NULL;
|
||||
const u_char *serverpub;
|
||||
size_t len_n = 0, len_e = 0;
|
||||
unsigned char *n = NULL;
|
||||
unsigned char *e = NULL;
|
||||
unsigned char *ctext = NULL;
|
||||
size_t pos_ctext = 0;
|
||||
size_t bufsize = 0;
|
||||
size_t clen = 0;
|
||||
int r = 0;
|
||||
struct rsa_keys *keys = kex->keys_mine;
|
||||
unsigned char *ptext = NULL;
|
||||
size_t plen = 0;
|
||||
|
||||
*shared_secret = NULL;
|
||||
bufsize = sshbuf_max_size(serverbuf);
|
||||
/* Extract the server's pubkey and the ciphertext
|
||||
* Structure of the message
|
||||
* size_t len_n
|
||||
* unsigned char *pubkey
|
||||
* size_t len_e
|
||||
* unsigned char *e
|
||||
* size_t len_rand
|
||||
* unsigned char *rand -> encrypted with client's pubkey
|
||||
*/
|
||||
serverpub = sshbuf_ptr(serverbuf);
|
||||
len_n = buf2dec(serverpub, 0);
|
||||
|
||||
n = (unsigned char *)malloc(len_n);
|
||||
if (!n)
|
||||
return -1;
|
||||
memset(n, 0, len_n);
|
||||
memcpy(n, serverpub + sizeof(size_t), len_n);
|
||||
|
||||
len_e = buf2dec(serverpub + sizeof(size_t) + len_n, 0);
|
||||
e = (unsigned char *)malloc(len_e);
|
||||
if (!e){
|
||||
free(n);
|
||||
return -1;
|
||||
}
|
||||
memcpy(e, serverpub + sizeof(size_t) + len_n + sizeof(size_t), len_e);
|
||||
pos_ctext = (sizeof(size_t) * 2) + len_n + len_e;
|
||||
|
||||
clen = bufsize - pos_ctext;
|
||||
ctext = (unsigned char*)malloc(clen);
|
||||
if (!ctext){
|
||||
free(n);
|
||||
free(e);
|
||||
return -1;
|
||||
}
|
||||
memset(ctext, 0, clen);
|
||||
memcpy(ctext, serverpub + pos_ctext, clen);
|
||||
|
||||
/* Decrypt key with our private key */
|
||||
if ((r = decrypt_key(ctext, clen, keys, &ptext, &plen)) != 0)
|
||||
goto clean;
|
||||
|
||||
if ((buf = sshbuf_new()) == NULL){
|
||||
r = -1;
|
||||
goto clean;
|
||||
}
|
||||
|
||||
sshbuf_reset(buf);
|
||||
//if ((r = sshbuf_put(buf, ptext, plen)) != 0)
|
||||
if ((r = sshbuf_put_string(buf, ptext, plen)) != 0)
|
||||
goto clean;
|
||||
debug("shared secret: %s %ld", sshbuf_ptr(buf), sshbuf_len(buf));
|
||||
*shared_secret = buf;
|
||||
|
||||
clean:
|
||||
free(n);
|
||||
free(e);
|
||||
free(ctext);
|
||||
n = NULL;
|
||||
e = NULL;
|
||||
ctext = NULL;
|
||||
buf = NULL;
|
||||
sshbuf_free(buf);
|
||||
return r;
|
||||
}
|
||||
|
||||
static size_t buf2dec(const unsigned char *buffer, size_t offset) {
|
||||
size_t r = 0;
|
||||
for(size_t i = 0; i < sizeof(size_t); i++)
|
||||
r += buffer[offset++] << (i * 8);
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int generate_rand_key(char **key, size_t *keylen){
|
||||
int r;
|
||||
BIGNUM *rnd = BN_new();
|
||||
BIGNUM *range = BN_new();
|
||||
char end[10];
|
||||
int i;
|
||||
for (i = 0; i < 10; i++)
|
||||
end[i] = '0' + i;
|
||||
BN_dec2bn(&range, end);
|
||||
|
||||
r = BN_rand_range(rnd, range);
|
||||
|
||||
BN_free(range);
|
||||
if (r == 0){
|
||||
BN_free(rnd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
*key = BN_bn2dec(rnd);
|
||||
*keylen = strlen(*key);
|
||||
|
||||
BN_free(rnd);
|
||||
return 0;
|
||||
}
|
||||
int build_pkey(struct rsa_keys *keys){
|
||||
int r;
|
||||
|
||||
EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL);
|
||||
|
||||
BIGNUM *n = BN_new();
|
||||
BIGNUM *e = BN_new();
|
||||
|
||||
BN_hex2bn(&n, keys->n);
|
||||
BN_hex2bn(&e, keys->e);
|
||||
|
||||
OSSL_PARAM_BLD *params = OSSL_PARAM_BLD_new();
|
||||
|
||||
if((r = OSSL_PARAM_BLD_push_BN(params, OSSL_PKEY_PARAM_RSA_N, n)) != 1)
|
||||
fatal_r(r, "OSSL_PARAM_BLD_push_BN");
|
||||
if((r = OSSL_PARAM_BLD_push_BN(params, OSSL_PKEY_PARAM_RSA_E, e)) != 1)
|
||||
fatal_r(r, "OSSL_PARAM_BLD_push_BN");
|
||||
|
||||
OSSL_PARAM *p = OSSL_PARAM_BLD_to_param(params);
|
||||
if(!p){
|
||||
OSSL_PARAM_BLD_free(params);
|
||||
OSSL_PARAM_free(p);
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_PKEY_fromdata_init(ctx);
|
||||
|
||||
keys->pkey = NULL;
|
||||
|
||||
if((r = EVP_PKEY_fromdata(ctx, &keys->pkey, EVP_PKEY_PUBLIC_KEY, p)) != 1){
|
||||
logit("Failed to build PKEY");
|
||||
OSSL_PARAM_BLD_free(params);
|
||||
OSSL_PARAM_free(p);
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
fatal_r(r, "EVP_PKEY_fromdata");
|
||||
}
|
||||
|
||||
OSSL_PARAM_BLD_free(params);
|
||||
OSSL_PARAM_free(p);
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int decrypt_key(const char *ciphertext, const size_t clen, struct rsa_keys *keys, unsigned char **ptext, size_t *plen) {
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
int r;
|
||||
size_t outlen = 0;
|
||||
BIGNUM *bntmp = NULL;
|
||||
unsigned char *bin = NULL;
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(keys->pkey, NULL);
|
||||
if (!ctx){
|
||||
logit("Failed to init pkey ctx");
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = EVP_PKEY_decrypt_init(ctx);
|
||||
if (r != 1){
|
||||
logit("Failed to init pkey decrypt");
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
|
||||
EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
|
||||
EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256());
|
||||
|
||||
/*
|
||||
* For decrypting, we need the binary
|
||||
*/
|
||||
/* Convert hex to bin */
|
||||
bntmp = BN_new();
|
||||
BN_hex2bn(&bntmp, ciphertext);
|
||||
|
||||
size_t l = BN_num_bytes(bntmp);
|
||||
bin = (unsigned char *)OPENSSL_malloc(l);
|
||||
|
||||
if(!bin) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
BN_free(bntmp);
|
||||
return -1;
|
||||
}
|
||||
|
||||
BN_bn2bin(bntmp, bin);
|
||||
BN_free(bntmp);
|
||||
|
||||
/* We identify the buffer size */
|
||||
r = EVP_PKEY_decrypt(ctx, NULL, &outlen, bin, l);
|
||||
if (r != 1) {
|
||||
logit("Failed to get the size");
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
OPENSSL_free(bin);
|
||||
print_ossl_error();
|
||||
return -1;
|
||||
}
|
||||
|
||||
*ptext = (unsigned char *)OPENSSL_malloc(outlen);
|
||||
|
||||
if (!*ptext) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
OPENSSL_free(bin);
|
||||
return -1;
|
||||
}
|
||||
|
||||
//r = EVP_PKEY_decrypt(ctx, out, &outlen, bin, l);
|
||||
r = EVP_PKEY_decrypt(ctx, *ptext, &outlen, bin, l);
|
||||
if (r != 1) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
OPENSSL_free(bin);
|
||||
logit("Failed to decrypt the ciphertext");
|
||||
print_ossl_error();
|
||||
fatal_r(r, "EVP_PKEY_decrypt");
|
||||
}
|
||||
//*plen = strlen(ptext);
|
||||
*plen = outlen;
|
||||
|
||||
OPENSSL_free(bin);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
||||
int encrypt_key(const char *rand, const size_t randlen, const struct rsa_keys *keys, unsigned char **ctext, size_t *clen) {
|
||||
EVP_PKEY_CTX *ctx = NULL;
|
||||
int r;
|
||||
size_t outlen;
|
||||
unsigned char *out;
|
||||
BIGNUM *tmp = NULL;
|
||||
|
||||
ctx = EVP_PKEY_CTX_new(keys->pkey, NULL);
|
||||
logit("Pkey: %p", keys->pkey);
|
||||
if (!ctx){
|
||||
logit("Failed to init pkey ctx");
|
||||
return -1;
|
||||
}
|
||||
|
||||
debug("Pkey size: %d", EVP_PKEY_get_size(keys->pkey));
|
||||
|
||||
r = EVP_PKEY_encrypt_init(ctx);
|
||||
if (r != 1){
|
||||
logit("Failed to init pkey encrypt");
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING);
|
||||
EVP_PKEY_CTX_set_rsa_oaep_md(ctx, EVP_sha256());
|
||||
EVP_PKEY_CTX_set_rsa_mgf1_md(ctx, EVP_sha256());
|
||||
|
||||
/* We identify the buffer size */
|
||||
r = EVP_PKEY_encrypt(ctx, NULL, &outlen, rand, randlen);
|
||||
debug("Encrypted len: %ld", outlen);
|
||||
|
||||
out = (unsigned char *)OPENSSL_malloc(outlen);
|
||||
|
||||
if (!out) {
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return -1;
|
||||
}
|
||||
|
||||
r = EVP_PKEY_encrypt(ctx, out, &outlen, rand, randlen);
|
||||
|
||||
tmp = BN_new();
|
||||
BN_bin2bn(out, outlen, tmp);
|
||||
*ctext = BN_bn2hex(tmp);
|
||||
*clen = strlen(*ctext);
|
||||
|
||||
OPENSSL_free(out);
|
||||
BN_free(tmp);
|
||||
EVP_PKEY_CTX_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int derive_key(const char *rand, const size_t randlen, char *out){
|
||||
return PKCS5_PBKDF2_HMAC(rand, randlen, NULL, 0, 5, EVP_sha256(), KEY_SIZE, out);
|
||||
}
|
||||
|
||||
int kem_gen_keys(struct rsa_keys *keys, size_t ksize){
|
||||
keys->pkey = EVP_RSA_gen(ksize);
|
||||
|
||||
if (!keys->pkey) {
|
||||
logit("Failed to gen RSA keys");
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* I must extract the modulus n, the exponent and the exponent d */
|
||||
BIGNUM *n = NULL;
|
||||
BIGNUM *e = NULL;
|
||||
BIGNUM *d = NULL;
|
||||
EVP_PKEY_get_bn_param(keys->pkey, OSSL_PKEY_PARAM_RSA_N, &n);
|
||||
EVP_PKEY_get_bn_param(keys->pkey, OSSL_PKEY_PARAM_RSA_E, &e);
|
||||
EVP_PKEY_get_bn_param(keys->pkey, OSSL_PKEY_PARAM_RSA_D, &d);
|
||||
|
||||
keys->n = BN_bn2hex(n);
|
||||
debug("Hex: %s", keys->n);
|
||||
debug("strlen: %ld", strlen(keys->n));
|
||||
debug("size: %ld", sizeof(keys->n));
|
||||
keys->e = BN_bn2hex(e);
|
||||
keys->d = BN_bn2dec(d);
|
||||
|
||||
keys->len_n = strlen(keys->n);
|
||||
keys->len_e = strlen(keys->e);
|
||||
keys->len_d = strlen(keys->d);
|
||||
|
||||
/* We don't use it anymore, freeing them */
|
||||
BN_free(n);
|
||||
BN_free(e);
|
||||
BN_free(d);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int init_rsa_keys(struct rsa_keys **keys) {
|
||||
*keys = (struct rsa_keys*)malloc(sizeof(struct rsa_keys));
|
||||
if (!*keys) {
|
||||
logit("Failed to init RSA keys");
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void dec2buf(char *buffer, size_t offset, size_t in){
|
||||
size_t pos = offset;
|
||||
for (size_t i = 0; i < sizeof(size_t); i++)
|
||||
buffer[pos++] = (in >> (i * 8)) & 0xFF;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifndef KEM_H
|
||||
#define KEM_H
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/sha.h>
|
||||
#include <openssl/err.h>
|
||||
#include <openssl/param_build.h>
|
||||
#include "kex.h"
|
||||
|
||||
struct kex;
|
||||
|
||||
#define MAX_KEM 32
|
||||
#define KEY_SIZE 32
|
||||
|
||||
|
||||
struct rsa_keys {
|
||||
EVP_PKEY *pkey;
|
||||
unsigned char *n;
|
||||
size_t len_n;
|
||||
unsigned char *e;
|
||||
size_t len_e;
|
||||
unsigned char *d;
|
||||
size_t len_d;
|
||||
};
|
||||
|
||||
struct ssh;
|
||||
|
||||
int kem_rsa1024_keypair(struct kex *);
|
||||
int kem_rsa2048_keypair(struct kex *);
|
||||
int kem_rsa1024_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **);
|
||||
int kem_rsa2048_enc(struct kex *, const struct sshbuf *, struct sshbuf **, struct sshbuf **);
|
||||
int kem_rsa_dec(struct kex *, struct sshbuf *, struct sshbuf **);
|
||||
int init_rsa_keys(struct rsa_keys **);
|
||||
int kem_gen_keys(struct rsa_keys *, size_t);
|
||||
int generate_rand_key(char **, size_t *);
|
||||
int build_pkey(struct rsa_keys *);
|
||||
int decrypt_key(const char *, const size_t, struct rsa_keys *, unsigned char **, size_t *);
|
||||
int encrypt_key(const char *, const size_t, const struct rsa_keys *, unsigned char **, size_t *);
|
||||
int derive_key(const char *, const size_t, char *);
|
||||
|
||||
#endif
|
||||
@@ -59,6 +59,8 @@ static const struct kexalg kexalgs[] = {
|
||||
{ KEX_DH16_SHA512, KEX_DH_GRP16_SHA512, 0, SSH_DIGEST_SHA512 },
|
||||
{ KEX_DH18_SHA512, KEX_DH_GRP18_SHA512, 0, SSH_DIGEST_SHA512 },
|
||||
{ KEX_DHGEX_SHA1, KEX_DH_GEX_SHA1, 0, SSH_DIGEST_SHA1 },
|
||||
{ KEX_KEMRSA1024, KEX_KEM_KEMRSA1024, 0, SSH_DIGEST_SHA512 },
|
||||
{ KEX_KEMRSA2048, KEX_KEM_KEMRSA2048, 0, SSH_DIGEST_SHA512 },
|
||||
#ifdef HAVE_EVP_SHA256
|
||||
{ KEX_DHGEX_SHA256, KEX_DH_GEX_SHA256, 0, SSH_DIGEST_SHA256 },
|
||||
#endif /* HAVE_EVP_SHA256 */
|
||||
|
||||
@@ -65,6 +65,8 @@
|
||||
#define KEX_SNTRUP761X25519_SHA512 "sntrup761x25519-sha512"
|
||||
#define KEX_SNTRUP761X25519_SHA512_OLD "[email protected]"
|
||||
#define KEX_MLKEM768X25519_SHA256 "mlkem768x25519-sha256"
|
||||
#define KEX_KEMRSA1024 "kem-rsa-1024"
|
||||
#define KEX_KEMRSA2048 "kem-rsa-2048"
|
||||
|
||||
#define COMP_NONE 0
|
||||
#define COMP_DELAYED 2
|
||||
@@ -97,6 +99,8 @@ enum kex_exchange {
|
||||
KEX_DH_GRP14_SHA256,
|
||||
KEX_DH_GRP16_SHA512,
|
||||
KEX_DH_GRP18_SHA512,
|
||||
KEX_KEM_KEMRSA1024,
|
||||
KEX_KEM_KEMRSA2048,
|
||||
KEX_DH_GEX_SHA1,
|
||||
KEX_DH_GEX_SHA256,
|
||||
KEX_ECDH_SHA2,
|
||||
@@ -138,6 +142,7 @@ struct newkeys {
|
||||
|
||||
struct ssh;
|
||||
struct sshbuf;
|
||||
struct rsa_keys;
|
||||
|
||||
struct kex {
|
||||
struct newkeys *newkeys[MODE_MAX];
|
||||
@@ -183,6 +188,8 @@ struct kex {
|
||||
u_char sntrup761_client_key[crypto_kem_sntrup761_SECRETKEYBYTES]; /* KEM */
|
||||
u_char mlkem768_client_key[crypto_kem_mlkem768_SECRETKEYBYTES]; /* KEM */
|
||||
struct sshbuf *client_pub;
|
||||
struct rsa_keys *keys_mine;
|
||||
struct rsa_keys *keys_peer;
|
||||
};
|
||||
|
||||
int kex_name_valid(const char *);
|
||||
|
||||
@@ -40,6 +40,7 @@
|
||||
#include "sshbuf.h"
|
||||
#include "digest.h"
|
||||
#include "ssherr.h"
|
||||
#include "kem.h"
|
||||
|
||||
static int input_kex_gen_init(int, u_int32_t, struct ssh *);
|
||||
static int input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh);
|
||||
@@ -123,6 +124,12 @@ kex_gen_client(struct ssh *ssh)
|
||||
case KEX_KEM_MLKEM768X25519_SHA256:
|
||||
r = kex_kem_mlkem768x25519_keypair(kex);
|
||||
break;
|
||||
case KEX_KEM_KEMRSA1024:
|
||||
r = kem_rsa1024_keypair(kex);
|
||||
break;
|
||||
case KEX_KEM_KEMRSA2048:
|
||||
r = kem_rsa2048_keypair(kex);
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
break;
|
||||
@@ -199,6 +206,10 @@ input_kex_gen_reply(int type, u_int32_t seq, struct ssh *ssh)
|
||||
r = kex_kem_mlkem768x25519_dec(kex, server_blob,
|
||||
&shared_secret);
|
||||
break;
|
||||
case KEX_KEM_KEMRSA1024:
|
||||
case KEX_KEM_KEMRSA2048:
|
||||
r = kem_rsa_dec(kex, server_blob, &shared_secret);
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
break;
|
||||
@@ -323,6 +334,14 @@ input_kex_gen_init(int type, u_int32_t seq, struct ssh *ssh)
|
||||
r = kex_kem_mlkem768x25519_enc(kex, client_pubkey,
|
||||
&server_pubkey, &shared_secret);
|
||||
break;
|
||||
case KEX_KEM_KEMRSA1024:
|
||||
r = kem_rsa1024_enc(kex, client_pubkey, &server_pubkey,
|
||||
&shared_secret);
|
||||
break;
|
||||
case KEX_KEM_KEMRSA2048:
|
||||
r = kem_rsa2048_enc(kex, client_pubkey, &server_pubkey,
|
||||
&shared_secret);
|
||||
break;
|
||||
default:
|
||||
r = SSH_ERR_INVALID_ARGUMENT;
|
||||
break;
|
||||
|
||||
@@ -177,10 +177,14 @@ static inline uint32_t core_num__u32_8__from_le_bytes(uint8_t buf[4]) {
|
||||
}
|
||||
|
||||
static inline uint32_t core_num__u8_6__count_ones(uint8_t x0) {
|
||||
#ifdef _MSC_VER
|
||||
#if defined(_MSC_VER)
|
||||
return __popcnt(x0);
|
||||
#else
|
||||
#elif !defined(MISSING_BUILTIN_POPCOUNT)
|
||||
return __builtin_popcount(x0);
|
||||
#else
|
||||
const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
||||
return v[x0 & 0xf] + v[(x0 >> 4) & 0xf];
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
+9
-1
@@ -49,6 +49,11 @@ echo '#define KRML_HOST_EPRINTF(...)'
|
||||
echo '#define KRML_HOST_EXIT(x) fatal_f("internal error")'
|
||||
echo
|
||||
|
||||
__builtin_popcount_replacement='
|
||||
const uint8_t v[16] = { 0, 1, 1, 2, 1, 2, 2, 3, 1, 2, 2, 3, 2, 3, 3, 4 };
|
||||
return v[x0 & 0xf] + v[(x0 >> 4) & 0xf];
|
||||
'
|
||||
|
||||
for i in $FILES; do
|
||||
echo "/* from $i */"
|
||||
# Changes to all files:
|
||||
@@ -62,7 +67,10 @@ for i in $FILES; do
|
||||
# Replace endian functions with versions that work.
|
||||
perl -0777 -pe 's/(static inline void core_num__u64_9__to_le_bytes.*\n)([^}]*\n)/\1 v = htole64(v);\n\2/' |
|
||||
perl -0777 -pe 's/(static inline uint64_t core_num__u64_9__from_le_bytes.*?)return v;/\1return le64toh(v);/s' |
|
||||
perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s'
|
||||
perl -0777 -pe 's/(static inline uint32_t core_num__u32_8__from_le_bytes.*?)return v;/\1return le32toh(v);/s' |
|
||||
# Compat for popcount.
|
||||
perl -0777 -pe 's/\#ifdef (_MSC_VER)(.*?return __popcnt\(x0\);)/\#if defined(\1)\2/s' |
|
||||
perl -0777 -pe "s/\\#else(\\n\\s+return __builtin_popcount\\(x0\\);)/\\#elif !defined(MISSING_BUILTIN_POPCOUNT)\\1\\n#else$__builtin_popcount_replacement/s"
|
||||
;;
|
||||
# Default: pass through.
|
||||
*)
|
||||
|
||||
+12
-5
@@ -1,4 +1,4 @@
|
||||
# $OpenBSD: dropbear-kex.sh,v 1.3 2024/06/19 10:10:46 dtucker Exp $
|
||||
# $OpenBSD: dropbear-kex.sh,v 1.4 2025/03/11 07:42:08 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
tid="dropbear kex"
|
||||
@@ -10,8 +10,14 @@ fi
|
||||
cp $OBJ/sshd_proxy $OBJ/sshd_proxy.bak
|
||||
|
||||
kex="curve25519-sha256 [email protected]"
|
||||
if $SSH -Q kex | grep 'diffie-hellman-group14-sha1'; then
|
||||
kex="$kex diffie-hellman-group14-sha256 diffie-hellman-group14-sha1"
|
||||
if $SSH -Q kex | grep 'diffie-hellman-group14-sha256' >/dev/null; then
|
||||
kex="$kex diffie-hellman-group14-sha256"
|
||||
fi
|
||||
# There's no flag to query KEX, so if MACs does not contain SHA1, assume
|
||||
# there's also SHA1-based KEX methods either.
|
||||
if $SSH -Q kex | grep 'diffie-hellman-group14-sha1' >/dev/null && \
|
||||
$DBCLIENT -m help hst 2>&1 | grep -- '-sha1' >/dev/null ; then
|
||||
kex="$kex diffie-hellman-group14-sha1"
|
||||
fi
|
||||
|
||||
for k in $kex; do
|
||||
@@ -19,8 +25,9 @@ for k in $kex; do
|
||||
rm -f ${COPY}
|
||||
# dbclient doesn't have switch for kex, so force in server
|
||||
(cat $OBJ/sshd_proxy.bak; echo "KexAlgorithms $k") >$OBJ/sshd_proxy
|
||||
env HOME=$OBJ dbclient -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \
|
||||
-J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY}
|
||||
env HOME=$OBJ \
|
||||
${DBCLIENT} -y -i $OBJ/.dropbear/id_ed25519 2>$OBJ/dbclient.log \
|
||||
-J "$OBJ/ssh_proxy.sh" somehost cat ${DATA} > ${COPY}
|
||||
if [ $? -ne 0 ]; then
|
||||
fail "ssh cat $DATA failed"
|
||||
fi
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
# $OpenBSD: sshfp-connect.sh,v 1.4 2021/09/01 00:50:27 dtucker Exp $
|
||||
# $OpenBSD: sshfp-connect.sh,v 1.5 2025/03/11 11:46:44 dtucker Exp $
|
||||
# Placed in the Public Domain.
|
||||
|
||||
# This test requires external setup and thus is skipped unless
|
||||
@@ -29,6 +29,12 @@ if ! $SSH -Q key-plain | grep ssh-rsa >/dev/null; then
|
||||
elif [ -z "${TEST_SSH_SSHFP_DOMAIN}" ]; then
|
||||
skip "TEST_SSH_SSHFP_DOMAIN not set."
|
||||
else
|
||||
# Prime any DNS caches and resolvers.
|
||||
for i in sshtest sshtest-sha1 sshtest-sha256; do
|
||||
host -t sshfp ${i}.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1
|
||||
host -t sshfp ${i}-bad.${TEST_SSH_SSHFP_DOMAIN} >/dev/null 2>&1
|
||||
done
|
||||
|
||||
# Set RSA host key to match fingerprints above.
|
||||
mv $OBJ/sshd_proxy $OBJ/sshd_proxy.orig
|
||||
$SUDO cp $SRC/rsa_openssh.prv $OBJ/host.ssh-rsa
|
||||
|
||||
+1
-1
@@ -386,7 +386,7 @@ srclimit_penalise(struct xaddr *addr, int penalty_type)
|
||||
reason = "penalty: connection prohibited by RefuseConnection";
|
||||
break;
|
||||
case SRCLIMIT_PENALTY_GRACE_EXCEEDED:
|
||||
penalty_secs = penalty_cfg.penalty_crash;
|
||||
penalty_secs = penalty_cfg.penalty_grace;
|
||||
reason = "penalty: exceeded LoginGraceTime";
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -268,6 +268,8 @@ ssh_kex2(struct ssh *ssh, char *host, struct sockaddr *hostaddr, u_short port,
|
||||
ssh->kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_client;
|
||||
ssh->kex->kex[KEX_DH_GEX_SHA1] = kexgex_client;
|
||||
ssh->kex->kex[KEX_DH_GEX_SHA256] = kexgex_client;
|
||||
ssh->kex->kex[KEX_KEM_KEMRSA1024] = kex_gen_client;
|
||||
ssh->kex->kex[KEX_KEM_KEMRSA2048] = kex_gen_client;
|
||||
# ifdef OPENSSL_HAS_ECC
|
||||
ssh->kex->kex[KEX_ECDH_SHA2] = kex_gen_client;
|
||||
# endif
|
||||
|
||||
@@ -1459,6 +1459,8 @@ do_ssh2_kex(struct ssh *ssh)
|
||||
kex->kex[KEX_DH_GRP18_SHA512] = kex_gen_server;
|
||||
kex->kex[KEX_DH_GEX_SHA1] = kexgex_server;
|
||||
kex->kex[KEX_DH_GEX_SHA256] = kexgex_server;
|
||||
kex->kex[KEX_KEM_KEMRSA1024] = kex_gen_server;
|
||||
kex->kex[KEX_KEM_KEMRSA2048] = kex_gen_server;
|
||||
#ifdef OPENSSL_HAS_ECC
|
||||
kex->kex[KEX_ECDH_SHA2] = kex_gen_server;
|
||||
#endif
|
||||
|
||||
@@ -2708,14 +2708,6 @@ sshkey_ec_validate_public(const EC_GROUP *group, const EC_POINT *public)
|
||||
* EC_POINT_oct2point then the caller will need to explicitly check.
|
||||
*/
|
||||
|
||||
/*
|
||||
* We shouldn't ever hit this case because bignum_get_ecpoint()
|
||||
* refuses to load GF2m points.
|
||||
*/
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_prime_field)
|
||||
goto out;
|
||||
|
||||
/* Q != infinity */
|
||||
if (EC_POINT_is_at_infinity(group, public))
|
||||
goto out;
|
||||
@@ -2815,11 +2807,6 @@ sshkey_dump_ec_point(const EC_GROUP *group, const EC_POINT *point)
|
||||
fprintf(stderr, "%s: BN_new failed\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (EC_METHOD_get_field_type(EC_GROUP_method_of(group)) !=
|
||||
NID_X9_62_prime_field) {
|
||||
fprintf(stderr, "%s: group is not a prime field\n", __func__);
|
||||
goto out;
|
||||
}
|
||||
if (EC_POINT_get_affine_coordinates_GFp(group, point,
|
||||
x, y, NULL) != 1) {
|
||||
fprintf(stderr, "%s: EC_POINT_get_affine_coordinates_GFp\n",
|
||||
|
||||
Reference in new issue
Block a user