Hi,

Daniel Stenberg wrote:
> > Can that date please be pushed two weeks?  I'm not sure I can
> > find time to finish the code up completely by the 11th.
> 
> Now we're 8 days away from release.  I think you need to subit this
> work ASAP if you still think you can get it into the release - so
> that it gets some time to sink in, get tested and reviewed.

I do think I can get it into the release.

I can't post a complete patch today, but maybe tomorrow night.

I've attached my current git diff master state for review as well as
testing. It has a couple of things which still need to be done, but
is already functional.

The diff also includes a few unrelated cleanups; a few type issues
and not using RSA if the crypto backend does not implement it.


> Otherwise I suggest we aim to get that merged for the next release
> instead.

I would like to get it in now, and look forward to any feedback on
the current patch.


//Peter
diff --git a/Makefile.axTLS.inc b/Makefile.axTLS.inc
new file mode 100644
index 0000000..b63943e
--- /dev/null
+++ b/Makefile.axTLS.inc
@@ -0,0 +1,2 @@
+CRYPTO_CSOURCES = axtls.c
+CRYPTO_HHEADERS = axtls.h
diff --git a/configure.ac b/configure.ac
index d6bdab4..f128494 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,6 +78,7 @@ AC_PATH_PROGS(SSHD, [sshd], [],
 AM_CONDITIONAL(SSHD, test -n "$SSHD")
 AC_LIBTOOL_WIN32_DLL
 AC_PROG_LIBTOOL
+PKG_PROG_PKG_CONFIG
 AC_C_BIGENDIAN
 
 dnl check for how to do large files
@@ -93,6 +94,9 @@ AC_ARG_WITH(libgcrypt,
 AC_ARG_WITH(wincng,
   AC_HELP_STRING([--with-wincng],[Use Windows CNG for crypto]),
   use_wincng=$withval,use_wincng=auto)
+AC_ARG_WITH(axtls,
+  AC_HELP_STRING([--with-axtls],[Use axTLS for crypto]),
+  use_axtls=$withval,use_axtls=auto)
 AC_ARG_WITH(libz,
   AC_HELP_STRING([--with-libz],[Use zlib for compression]),
   use_libz=$withval,use_libz=auto)
@@ -163,6 +167,17 @@ AM_CONDITIONAL(WINCNG, test "$ac_cv_libbcrypt" = "yes")
 
 AM_CONDITIONAL(OS400QC3, false)
 
+# Look for axTLS
+if test "$found_crypto" = "none" && test "$use_axtls" != "no"; then
+  PKG_CHECK_MODULES([AXTLS], [libaxtls], [
+    found_crypto=axTLS
+    AC_DEFINE(LIBSSH2_AXTLS, 1, [Use axTLS])
+    LIBS="$LIBS $AXTLS_LIBS"
+  ])
+fi
+AM_CONDITIONAL(AXTLS, test "$found_crypto" = "axTLS")
+
+
 # Check if crypto library was found
 if test "$found_crypto" = "none"; then
   AC_MSG_ERROR([No crypto library found!
diff --git a/docs/HACKING.CRYPTO b/docs/HACKING.CRYPTO
index a8a6a06..6fdcf71 100644
--- a/docs/HACKING.CRYPTO
+++ b/docs/HACKING.CRYPTO
@@ -316,7 +316,7 @@ _libssh2_bn_ctx
 Type of multiple precision computation context. May not be empty. if not used,
 #define as char, for example.
 
-libssh2_bn_ctx _libssh2_bn_ctx_new(void);
+_libssh2_bn_ctx _libssh2_bn_ctx_new(void);
 Returns a new multiple precision computation context.
 
 void _libssh2_bn_ctx_free(_libssh2_bn_ctx ctx);
@@ -339,7 +339,7 @@ allocates the number. Returns a value of type _libssh2_bn *.
 void _libssh2_bn_free(_libssh2_bn *bn);
 Destroys the multiple precision number at bn.
 
-unsigned long _libssh2_bn_bytes(libssh2_bn *bn);
+unsigned long _libssh2_bn_bytes(_libssh2_bn *bn);
 Get the number of bytes needed to store the bits of the multiple precision
 number at bn.
 
diff --git a/src/Makefile.am b/src/Makefile.am
index 1334c55..cbcc812 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -14,6 +14,9 @@ endif
 if OS400QC3
 include ../Makefile.os400qc3.inc
 endif
+if AXTLS
+include ../Makefile.axTLS.inc
+endif
 
 # Makefile.inc provides the CSOURCES and HHEADERS defines
 include ../Makefile.inc
@@ -60,6 +63,7 @@ VERSION=-version-info 1:1:0
 # set age to 0. (c:r:a=0)
 #
 
+libssh2_la_CFLAGS = $(AXTLS_CFLAGS)
 libssh2_la_LDFLAGS = $(VERSION) -no-undefined \
 	-export-symbols-regex '^libssh2_.*' \
-	$(LTLIBGCRYPT) $(LTLIBSSL) $(LTLIBZ)
+	$(LTLIBGCRYPT) $(LTLIBSSL) $(AXTLS_LDFLAGS) $(LTLIBZ)
diff --git a/src/axtls.c b/src/axtls.c
new file mode 100644
index 0000000..c06429a
--- /dev/null
+++ b/src/axtls.c
@@ -0,0 +1,502 @@
+/* Copyright (c) 2016 Peter Stuge
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ *   Redistributions of source code must retain the above
+ *   copyright notice, this list of conditions and the
+ *   following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials
+ *   provided with the distribution.
+ *
+ *   Neither the name of the copyright holder nor the names
+ *   of any other contributors may be used to endorse or
+ *   promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#include "libssh2_priv.h"
+
+#if LIBSSH2_AXTLS
+
+#include <axTLS/crypto.h>
+#include <stdlib.h>
+
+static BI_CTX *axbictx = NULL;
+
+#ifndef MIN
+#define MIN(x,y) ((x)<(y)?(x):(y))
+#endif
+
+#ifndef MAX
+#define MAX(x,y) ((x)>(y)?(x):(y))
+#endif
+
+
+/* 1) Crypto library initialization/termination. */
+void libssh2_crypto_init(void) {
+	axbictx = bi_initialize();
+	RNG_initialize();
+}
+
+void libssh2_crypto_exit(void) {
+	RNG_terminate();
+	bi_terminate(axbictx);
+}
+
+
+/* 2) HMAC */
+
+static unsigned int hash_blocksize(enum _libssh2_axtls_hmac_type type) {
+	switch (type) {
+	case HMAC_MD5:
+	case HMAC_SHA1:
+	case HMAC_SHA256:
+		return 64;
+	case HMAC_SHA512:
+		return 128;
+	}
+	return 0;
+}
+
+void libssh2_axtls_hmac_ctx_init(libssh2_hmac_ctx *ctx, enum _libssh2_axtls_hmac_type type, const void *key, int keylen) {
+	size_t i, klen = keylen;
+	const unsigned char *k = key;
+
+	ctx->type = type;
+	ctx->k_size = hash_blocksize(type);
+
+	for (i = 0; i < ctx->k_size; i++)
+		ctx->k[i] = (i < klen ? k[i] : 0) ^ 0x36;
+
+	switch (ctx->type) {
+	case HMAC_MD5:
+		ctx->h.md5 = &ctx->hctx.md5;
+		MD5_Init(ctx->h.md5);
+		MD5_Update(ctx->h.md5, ctx->k, ctx->k_size);
+		break;
+
+	case HMAC_SHA1:
+		ctx->h.sha1 = &ctx->hctx.sha1;
+		SHA1_Init(ctx->h.sha1);
+		SHA1_Update(ctx->h.sha1, ctx->k, ctx->k_size);
+		break;
+
+	case HMAC_SHA256:
+		ctx->h.sha256 = &ctx->hctx.sha256;
+		SHA256_Init(ctx->h.sha256);
+		SHA256_Update(ctx->h.sha256, ctx->k, ctx->k_size);
+		break;
+
+	case HMAC_SHA512:
+		ctx->h.sha512 = &ctx->hctx.sha512;
+		SHA512_Init(ctx->h.sha512);
+		SHA512_Update(ctx->h.sha512, ctx->k, ctx->k_size);
+		break;
+	}
+
+	for (i = 0; i < ctx->k_size; i++)
+		ctx->k[i] = (i < klen ? k[i] : 0) ^ 0x5c;
+}
+
+void libssh2_axtls_hmac_update(libssh2_hmac_ctx *ctx, const unsigned char *data, int datalen) {
+	switch (ctx->type) {
+	case HMAC_MD5: MD5_Update(ctx->h.md5, data, datalen); return;
+	case HMAC_SHA1: SHA1_Update(ctx->h.sha1, data, datalen); return;
+	case HMAC_SHA256: SHA256_Update(ctx->h.sha256, data, datalen); return;
+	case HMAC_SHA512: SHA512_Update(ctx->h.sha512, data, datalen); return;
+	}
+}
+
+void libssh2_axtls_hmac_final(libssh2_hmac_ctx *ctx, unsigned char *output) {
+	union {
+		MD5_CTX md5;
+		SHA1_CTX sha1;
+		SHA256_CTX sha256;
+		SHA512_CTX sha512;
+	} hctx;
+	MD5_CTX *md5 = &hctx.md5;
+	SHA1_CTX *sha1 = &hctx.sha1;
+	SHA256_CTX *sha256 = &hctx.sha256;
+	SHA512_CTX *sha512 = &hctx.sha512;
+
+	switch (ctx->type) {
+	case HMAC_MD5:
+		MD5_Final(output, ctx->h.md5);
+		MD5_Init(md5);
+		MD5_Update(md5, ctx->k, ctx->k_size);
+		MD5_Update(md5, output, MD5_SIZE);
+		MD5_Final(output, md5);
+		memset(md5, 0, sizeof hctx.md5);
+		break;
+
+	case HMAC_SHA1:
+		SHA1_Final(output, ctx->h.sha1);
+		SHA1_Init(sha1);
+		SHA1_Update(sha1, ctx->k, ctx->k_size);
+		SHA1_Update(sha1, output, SHA1_SIZE);
+		SHA1_Final(output, sha1);
+		memset(sha1, 0, sizeof hctx.sha1);
+		break;
+
+	case HMAC_SHA256:
+		SHA256_Final(output, ctx->h.sha256);
+		SHA256_Init(sha256);
+		SHA256_Update(sha256, ctx->k, ctx->k_size);
+		SHA256_Update(sha256, output, SHA256_SIZE);
+		SHA256_Final(output, sha256);
+		memset(sha256, 0, sizeof hctx.sha256);
+		break;
+
+	case HMAC_SHA512:
+		SHA512_Final(output, ctx->h.sha512);
+		SHA512_Init(sha512);
+		SHA512_Update(sha512, ctx->k, ctx->k_size);
+		SHA512_Update(sha512, output, SHA512_SIZE);
+		SHA512_Final(output, sha512);
+		memset(sha512, 0, sizeof hctx.sha512);
+		break;
+	}
+}
+
+void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx) {
+	memset(ctx->k, 0, sizeof ctx->k);
+
+	switch (ctx->type) {
+	case HMAC_MD5:
+		memset(ctx->h.md5, 0, sizeof ctx->hctx.md5);
+		break;
+
+	case HMAC_SHA1:
+		memset(ctx->h.sha1, 0, sizeof ctx->hctx.sha1);
+		break;
+
+	case HMAC_SHA256:
+		memset(ctx->h.sha256, 0, sizeof ctx->hctx.sha256);
+		break;
+
+	case HMAC_SHA512:
+		memset(ctx->h.sha512, 0, sizeof ctx->hctx.sha512);
+		break;
+	}
+}
+
+
+/* 3.1) SHA-1 */
+
+int libssh2_sha1_init(libssh2_sha1_ctx *x) {
+	SHA1_Init(x);
+	return 1;
+}
+
+
+/* 3.2) SHA-256 */
+
+int libssh2_sha256_init(libssh2_sha256_ctx *x) {
+	SHA256_Init(x);
+	return 1;
+}
+
+int libssh2_sha256(const unsigned char *message, unsigned long len, unsigned char *output) {
+	SHA256_CTX ctx;
+	SHA256_Init(&ctx);
+	SHA256_Update(&ctx, message, len);
+	SHA256_Final(output, &ctx);
+	return 0;
+}
+
+
+/* 3.4) MD5 */
+
+int libssh2_md5_init(libssh2_md5_ctx *x) {
+	MD5_Init(x);
+	return 1;
+}
+
+
+/* 4) Bidirectional Key ciphers. */
+
+static AES_MODE aes_mode_from_type(_libssh2_cipher_type(algo)) {
+	switch (algo) {
+	case AES_128_CBC: return AES_MODE_128;
+	case AES_256_CBC: return AES_MODE_256;
+	}
+}
+
+int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt) {
+	switch (algo) {
+	case AES_192_CBC:
+		/* not implemented in axTLS */
+		return -1;
+
+	case AES_128_CBC:
+	case AES_256_CBC:
+		AES_set_key(&h->aes, secret, iv, aes_mode_from_type(algo));
+		if (!encrypt)
+			AES_convert_key(&h->aes);
+		break;
+
+	case RC4:
+		RC4_setup(&h->rc4, secret, 16);
+		break;
+	}
+
+	return 0;
+}
+
+int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize) {
+	switch (algo) {
+	case AES_192_CBC:
+		/* not implemented in axTLS */
+		return -1;
+
+	case AES_128_CBC:
+	case AES_256_CBC:
+		if (encrypt)
+			AES_cbc_encrypt(&ctx->aes, block, block, blocksize);
+		else
+			AES_cbc_decrypt(&ctx->aes, block, block, blocksize);
+		break;
+
+	case RC4:
+		RC4_crypt(&ctx->rc4, block, block, blocksize);
+		break;
+	}
+
+	return 0;
+}
+
+void _libssh2_cipher_dtor(_libssh2_cipher_ctx *ctx) {
+	memset(&ctx->aes, 0, sizeof ctx->aes);
+	memset(&ctx->rc4, 0, sizeof ctx->rc4);
+}
+
+
+/* 5) Big numbers. */
+
+_libssh2_bn_ctx *_libssh2_bn_ctx_new(void) {
+	return axbictx;
+}
+
+_libssh2_bn *_libssh2_bn_init(void) {
+	return int_to_bi(axbictx, 0);
+}
+
+_libssh2_bn *_libssh2_bn_init_from_bin(void) {
+	return NULL;
+}
+
+void _libssh2_bn_free(_libssh2_bn *bn) {
+	if (bn)
+		bi_free(axbictx, bn);
+}
+
+unsigned long _libssh2_bn_bytes(_libssh2_bn *bn) {
+	unsigned long n = COMP_BYTE_SIZE * bn->size;
+	comp mask = 0xff;
+
+	for (mask <<= COMP_BIT_SIZE-8; mask; mask >>= 8, n--)
+		if (bn->comps[bn->size - 1] & mask)
+			break;
+
+	return n;
+}
+
+unsigned long _libssh2_bn_bits(_libssh2_bn *bn) {
+	unsigned long n = COMP_BIT_SIZE * bn->size;
+	comp mask = 1;
+
+	for (mask <<= COMP_BIT_SIZE-1; mask; mask >>= 1, n--)
+		if (bn->comps[bn->size - 1] & mask)
+			break;
+
+	return n;
+}
+
+_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_ulong(_libssh2_bn *old, unsigned long val) {
+	_libssh2_bn *ret = int_to_bi(axbictx, val);
+	if (old)
+		bi_free(axbictx, old);
+	return ret;
+}
+
+_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_bin(_libssh2_bn *old, int len, const unsigned char *val) {
+	_libssh2_bn *ret = bi_import(axbictx, val, len);
+	if (old)
+		bi_free(axbictx, old);
+	return ret;
+}
+
+int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val) {
+	unsigned char *b, *buf;
+	int ret = _libssh2_bn_bytes(bn);
+	unsigned long n = COMP_BYTE_SIZE * bn->size;
+
+	b = buf = malloc(n);
+	if (!buf)
+		return -1;
+
+	bi_copy(bn);
+	bi_export(axbictx, bn, buf, n);
+
+	while (!*b)
+		b++;
+
+	memcpy(val, b, ret);
+	free(buf);
+
+	return ret;
+}
+
+
+/* TODO
+Generates a cryptographically strong pseudo-random number of bits in
+length and stores it in bn. If top is -1, the most significant bit of the
+random number can be zero. If top is 0, it is set to 1, and if top is 1, the
+two most significant bits of the number will be set to 1, so that the product
+of two such random numbers will always have 2*bits length. If bottom is true,
+the number will be odd.
+*/
+_libssh2_bn *_libssh2_bn_free_and_new_rand(_libssh2_bn *bn, int bits, int top, int bottom) {
+	int bytes = bits+7/8;
+	unsigned char *buf = malloc(bytes);
+	_libssh2_bn *ret;
+
+	bi_free(axbictx, bn);
+	get_random(bytes, buf);
+	ret = bi_import(axbictx, buf, bytes);
+	free(buf);
+
+	/* TODO: bits top bottom */
+
+	return ret;
+}
+
+
+/* r=a^p % m, May use the given context. */
+_libssh2_bn *_libssh2_axtls_free_and_new_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *ctx) {
+	bi_free(axbictx, r);
+	bi_copy(a);
+	bi_copy(p);
+	bi_copy(m);
+	return bi_mod_power2(ctx, a, m, p);
+}
+
+
+/* 6) Private key algorithms. */
+
+int _libssh2_pub_priv_keyfile(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekey, const char *passphrase) {
+	/* TODO */
+	return -1;
+}
+
+int _libssh2_pub_priv_keyfilememory(LIBSSH2_SESSION *session, unsigned char **method, size_t *method_len, unsigned char **pubkeydata, size_t *pubkeydata_len, const char *privatekeydata, size_t privatekeydata_len, const char *passphrase) {
+	/* TODO */
+	return -1;
+}
+
+
+/* 6.1) RSA */
+
+int _libssh2_rsa_new(libssh2_rsa_ctx **rsa,
+		const unsigned char *edata, unsigned long elen,
+		const unsigned char *ndata, unsigned long nlen,
+		const unsigned char *ddata, unsigned long dlen,
+		const unsigned char *pdata, unsigned long plen,
+		const unsigned char *qdata, unsigned long qlen,
+		const unsigned char *e1data, unsigned long e1len,
+		const unsigned char *e2data, unsigned long e2len,
+		const unsigned char *coeffdata, unsigned long coefflen) {
+	*rsa = NULL;
+	RSA_pub_key_new(rsa, ndata, nlen, edata, elen);
+	return 0;
+}
+
+int _libssh2_rsa_new_private(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *filename, unsigned const char *passphrase) {
+	_libssh2_init_if_needed();
+	/* TODO */
+	return -1;
+}
+
+int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, LIBSSH2_SESSION *session, const char *data, size_t data_len, unsigned const char *passphrase) {
+	_libssh2_init_if_needed();
+	/* TODO */
+	return -1;
+}
+
+#define OID_SHA1_LEN 15
+static const unsigned char oid_sha1[OID_SHA1_LEN] = {
+	0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
+	0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14
+};
+
+int _libssh2_rsa_sha1_verify(libssh2_rsa_ctx *rsa, const unsigned char *sig, unsigned long sig_len, const unsigned char *m, unsigned long m_len) {
+	int ret = -1;
+	SHA1_CTX h;
+	bigint *s, *v;
+	unsigned long vlen;
+	unsigned char *p, *ver, hash[SHA1_SIZE];
+
+	s = bi_import(axbictx, sig, sig_len);
+	v = RSA_public(rsa, s);
+
+	vlen = _libssh2_bn_bytes(v);
+	p = ver = malloc(vlen);
+	if (!ver)
+		return -1;
+
+	bi_export(axbictx, v, ver, vlen);
+
+	if (ver[0] != 0x01)
+		goto done;
+
+	if (vlen < 1 + 1 + sizeof oid_sha1 + sizeof hash)
+		goto done;
+
+	p = ver + (vlen - sizeof hash - sizeof oid_sha1);
+	if (memcmp(p, oid_sha1, sizeof oid_sha1))
+		goto done;
+
+	p += sizeof oid_sha1;
+
+	SHA1_Init(&h);
+	SHA1_Update(&h, m, m_len);
+	SHA1_Final(hash, &h);
+
+	if (memcmp(p, hash, sizeof hash))
+		goto done;
+
+	ret = 0;
+
+done:
+	memset(ver, 0, vlen);
+	memset(&h, 0, sizeof h);
+	free(ver);
+	return ret;
+}
+
+int _libssh2_rsa_sha1_sign(LIBSSH2_SESSION *session, libssh2_rsa_ctx *rsactx, const unsigned char *hash, size_t hash_len, unsigned char **signature, size_t *signature_len) {
+	/* TODO */
+	return -1;
+}
+
+#endif /* LIBSSH2_AXTLS */
diff --git a/src/axtls.h b/src/axtls.h
new file mode 100644
index 0000000..27bcfaa
--- /dev/null
+++ b/src/axtls.h
@@ -0,0 +1,227 @@
+/* Copyright (c) 2016 Peter Stuge
+ *
+ * Redistribution and use in source and binary forms,
+ * with or without modification, are permitted provided
+ * that the following conditions are met:
+ *
+ *   Redistributions of source code must retain the above
+ *   copyright notice, this list of conditions and the
+ *   following disclaimer.
+ *
+ *   Redistributions in binary form must reproduce the above
+ *   copyright notice, this list of conditions and the following
+ *   disclaimer in the documentation and/or other materials
+ *   provided with the distribution.
+ *
+ *   Neither the name of the copyright holder nor the names
+ *   of any other contributors may be used to endorse or
+ *   promote products derived from this software without
+ *   specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+ * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+ * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
+ * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
+ * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
+ * OF SUCH DAMAGE.
+ */
+
+#ifndef _AXTLS_H_
+#define _AXTLS_H_
+
+#include <axTLS/crypto.h>
+
+
+/* 1) Crypto library initialization/termination. */
+void libssh2_crypto_init(void);
+void libssh2_crypto_exit(void);
+
+
+/* 2) HMAC */
+enum _libssh2_axtls_hmac_type {
+	HMAC_MD5 = 0,
+	HMAC_SHA1,
+	HMAC_SHA256,
+	HMAC_SHA512
+};
+
+typedef struct _libssh2_axtls_hmac_ctx {
+	enum _libssh2_axtls_hmac_type type;
+
+	unsigned char k[128];
+	unsigned char k_size;
+
+	union {
+		MD5_CTX md5;
+		SHA1_CTX sha1;
+		SHA256_CTX sha256;
+		SHA512_CTX sha512;
+	} hctx;
+	union {
+		MD5_CTX *md5;
+		SHA1_CTX *sha1;
+		SHA256_CTX *sha256;
+		SHA512_CTX *sha512;
+	} h;
+} libssh2_hmac_ctx;
+
+void libssh2_axtls_hmac_ctx_init(libssh2_hmac_ctx *ctx, enum _libssh2_axtls_hmac_type type, const void *key, int keylen);
+void libssh2_axtls_hmac_update(libssh2_hmac_ctx *ctx, const unsigned char *data, int datalen);
+void libssh2_axtls_hmac_final(libssh2_hmac_ctx *ctx, unsigned char *output);
+
+#define libssh2_hmac_ctx_init(x) do { } while (0)
+#define libssh2_hmac_update(ctx, data, datalen) libssh2_axtls_hmac_update(&(ctx), data, datalen)
+#define libssh2_hmac_final(ctx, output) libssh2_axtls_hmac_final(&(ctx), output)
+
+void libssh2_hmac_cleanup(libssh2_hmac_ctx *ctx);
+
+
+/* 3.1) SHA-1 */
+#define SHA_DIGEST_LENGTH SHA1_SIZE
+typedef SHA1_CTX libssh2_sha1_ctx;
+int libssh2_sha1_init(libssh2_sha1_ctx *x);
+#define libssh2_sha1_update(ctx, data, len) SHA1_Update(&ctx, data, len)
+#define libssh2_sha1_final(ctx, output) SHA1_Final(output, &ctx)
+#define libssh2_hmac_sha1_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA1, key, keylen)
+
+
+/* 3.2) SHA-256 */
+#define SHA256_DIGEST_LENGTH SHA256_SIZE
+typedef SHA256_CTX libssh2_sha256_ctx;
+int libssh2_sha256_init(libssh2_sha256_ctx *x);
+#define libssh2_sha256_update(ctx, data, len) SHA256_Update(&ctx, data, len)
+#define libssh2_sha256_final(ctx, output) SHA256_Final(output, &ctx)
+int libssh2_sha256(const unsigned char *message, unsigned long len, unsigned char *output);
+
+#define LIBSSH2_HMAC_SHA256 1
+#define libssh2_hmac_sha256_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA256, key, keylen)
+
+
+/* 3.3) SHA-512 (HMAC-SHA512) */
+#define LIBSSH2_HMAC_SHA512 1
+#define libssh2_hmac_sha512_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_SHA512, key, keylen)
+
+
+/* 3.4) MD5 */
+#define LIBSSH2_MD5 1
+#define MD5_DIGEST_LENGTH MD5_SIZE
+typedef MD5_CTX libssh2_md5_ctx;
+int libssh2_md5_init(libssh2_md5_ctx *x);
+#define libssh2_md5_update(ctx, data, len) MD5_Update(&ctx, data, len)
+#define libssh2_md5_final(ctx, output) MD5_Final(output, &ctx)
+#define libssh2_hmac_md5_init(ctx, key, keylen) libssh2_axtls_hmac_ctx_init(ctx, HMAC_MD5, key, keylen)
+
+
+/* 3.5) RIPEMD-160 */
+#define LIBSSH2_HMAC_RIPEMD 0
+
+
+/* 4) Bidirectional Key ciphers. */
+
+enum _libssh2_axtls_cipher_type {
+	AES_128_CBC = 0,
+	AES_192_CBC,
+	AES_256_CBC,
+	RC4
+};
+
+typedef union _libssh2_axtls_cipher_ctx {
+	AES_CTX aes;
+	RC4_CTX rc4;
+} _libssh2_cipher_ctx;
+
+#define _libssh2_cipher_type(name) enum _libssh2_axtls_cipher_type name
+
+int _libssh2_cipher_init(_libssh2_cipher_ctx *h, _libssh2_cipher_type(algo), unsigned char *iv, unsigned char *secret, int encrypt);
+int _libssh2_cipher_crypt(_libssh2_cipher_ctx *ctx, _libssh2_cipher_type(algo), int encrypt, unsigned char *block, size_t blocksize);
+void _libssh2_cipher_dtor(_libssh2_cipher_ctx *ctx);
+
+
+
+/* 4.1) AES
+4.1.1) AES in CBC block mode. */
+#define LIBSSH2_AES 1
+#define _libssh2_cipher_aes128 AES_128_CBC
+#define _libssh2_cipher_aes192 AES_192_CBC
+#define _libssh2_cipher_aes256 AES_256_CBC
+
+
+/* 4.1.2) AES in CTR block mode. */
+#define LIBSSH2_AES_CTR 0
+
+
+/* 4.2) Blowfish in CBC block mode. */
+#define LIBSSH2_BLOWFISH 0
+
+
+/* 4.3) RC4. */
+#define LIBSSH2_RC4 1
+#define _libssh2_cipher_arcfour RC4
+
+
+/* 4.4) CAST5 in CBC block mode. */
+#define LIBSSH2_CAST 0
+
+
+/* 4.5) Tripple DES in CBC block mode. */
+#define LIBSSH2_3DES 0
+
+
+/* 5) Big numbers. */
+typedef BI_CTX _libssh2_bn_ctx;
+
+_libssh2_bn_ctx *_libssh2_bn_ctx_new(void);
+#define _libssh2_bn_ctx_free(ctx) do { } while (0)
+
+typedef bigint _libssh2_bn;
+
+_libssh2_bn *_libssh2_bn_init(void);
+_libssh2_bn *_libssh2_bn_init_from_bin(void);
+void _libssh2_bn_free(_libssh2_bn *bn);
+unsigned long _libssh2_bn_bytes(_libssh2_bn *bn);
+unsigned long _libssh2_bn_bits(_libssh2_bn *bn);
+
+_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_ulong(_libssh2_bn *old, unsigned long val);
+/* this is supposed to return 1, but nobody checks it */
+#define _libssh2_bn_set_word(bn, val) bn = _libssh2_axtls_bn_free_and_new_from_ulong(bn, val)
+
+_libssh2_bn *_libssh2_axtls_bn_free_and_new_from_bin(_libssh2_bn *old, int len, const unsigned char *val);
+/* this is supposed to return NULL on error, but nobody checks it */
+#define _libssh2_bn_from_bin(bn, len, val) bn = _libssh2_axtls_bn_free_and_new_from_bin(bn, len, val)
+
+int _libssh2_bn_to_bin(_libssh2_bn *bn, unsigned char *val);
+
+_libssh2_bn *_libssh2_bn_free_and_new_rand(_libssh2_bn *bn, int bits, int top, int bottom);
+#define _libssh2_bn_rand(bn, bits, top, bottom) bn = _libssh2_bn_free_and_new_rand(bn, bits, top, bottom)
+
+_libssh2_bn *_libssh2_axtls_free_and_new_bn_mod_exp(_libssh2_bn *r, _libssh2_bn *a, _libssh2_bn *p, _libssh2_bn *m, _libssh2_bn_ctx *ctx);
+#define _libssh2_bn_mod_exp(r, a, p, m, ctx) r = _libssh2_axtls_free_and_new_bn_mod_exp(r, a, p, m, ctx)
+
+
+/* 6.1) RSA */
+#define LIBSSH2_RSA 1
+
+typedef RSA_CTX libssh2_rsa_ctx;
+
+#define _libssh2_rsa_free RSA_free
+
+
+/* 6.2) DSA */
+#define LIBSSH2_DSA 0
+
+
+/* 7) Miscellaneous */
+
+#define libssh2_prepare_iovec(vector, len) do { } while (0)
+#define _libssh2_random(buf, len) get_random(len, buf)
+
+
+#endif /* _AXTLS_H_ */
diff --git a/src/crypto.h b/src/crypto.h
index caad19f..452505a 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -54,6 +54,11 @@
 #include "os400qc3.h"
 #endif
 
+#ifdef LIBSSH2_AXTLS
+#include "axtls.h"
+#endif
+
+#if LIBSSH2_RSA
 int _libssh2_rsa_new(libssh2_rsa_ctx ** rsa,
                      const unsigned char *edata,
                      unsigned long elen,
@@ -88,6 +93,7 @@ int _libssh2_rsa_new_private_frommemory(libssh2_rsa_ctx ** rsa,
                                         LIBSSH2_SESSION * session,
                                         const char *filedata, size_t filedata_len,
                                         unsigned const char *passphrase);
+#endif
 
 #if LIBSSH2_DSA
 int _libssh2_dsa_new(libssh2_dsa_ctx ** dsa,
diff --git a/src/global.c b/src/global.c
index dc45e70..353ffce 100644
--- a/src/global.c
+++ b/src/global.c
@@ -46,7 +46,9 @@ libssh2_init(int flags)
 {
     if (_libssh2_initialized == 0 && !(flags & LIBSSH2_INIT_NO_CRYPTO)) {
         libssh2_crypto_init();
+#if LIBSSH2_AES_CTR
         _libssh2_init_aes_ctr();
+#endif
     }
 
     _libssh2_initialized++;
diff --git a/src/kex.c b/src/kex.c
index 65b722f..fcf6c41 100644
--- a/src/kex.c
+++ b/src/kex.c
@@ -357,7 +357,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
             libssh2_sha1_update(exchange_hash_ctx,
                                 exchange_state->h_sig_comp, 4);
             libssh2_sha1_update(exchange_hash_ctx,
-                                (char *) session->local.banner,
+                                session->local.banner,
                                 strlen((char *) session->local.banner) - 2);
         } else {
             _libssh2_htonu32(exchange_state->h_sig_comp,
@@ -365,7 +365,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
             libssh2_sha1_update(exchange_hash_ctx,
                                 exchange_state->h_sig_comp, 4);
             libssh2_sha1_update(exchange_hash_ctx,
-                                LIBSSH2_SSH_DEFAULT_BANNER,
+                                (const unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER,
                                 sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
         }
 
@@ -517,14 +517,14 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
                                                         session->local.crypt->
-                                                        iv_len, "A");
+                                                        iv_len, (unsigned char *)"A");
             if (!iv) {
                 ret = -1;
                 goto clean_exit;
             }
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
                                                         session->local.crypt->
-                                                        secret_len, "C");
+                                                        secret_len, (unsigned char *)"C");
             if (!secret) {
                 LIBSSH2_FREE(session, iv);
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
@@ -564,14 +564,14 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(iv,
                                                         session->remote.crypt->
-                                                        iv_len, "B");
+                                                        iv_len, (unsigned char *)"B");
             if (!iv) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
             }
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(secret,
                                                         session->remote.crypt->
-                                                        secret_len, "D");
+                                                        secret_len, (unsigned char *)"D");
             if (!secret) {
                 LIBSSH2_FREE(session, iv);
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
@@ -609,7 +609,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
                                                         session->local.mac->
-                                                        key_len, "E");
+                                                        key_len, (unsigned char *)"E");
             if (!key) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
@@ -635,7 +635,7 @@ static int diffie_hellman_sha1(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA1_HASH(key,
                                                         session->remote.mac->
-                                                        key_len, "F");
+                                                        key_len, (unsigned char *)"F");
             if (!key) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
@@ -977,7 +977,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
             libssh2_sha256_update(exchange_hash_ctx,
                                   exchange_state->h_sig_comp, 4);
             libssh2_sha256_update(exchange_hash_ctx,
-                                  (char *) session->local.banner,
+                                  session->local.banner,
                                   strlen((char *) session->local.banner) - 2);
         } else {
             _libssh2_htonu32(exchange_state->h_sig_comp,
@@ -985,7 +985,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
             libssh2_sha256_update(exchange_hash_ctx,
                                   exchange_state->h_sig_comp, 4);
             libssh2_sha256_update(exchange_hash_ctx,
-                                  LIBSSH2_SSH_DEFAULT_BANNER,
+                                  (unsigned char *)LIBSSH2_SSH_DEFAULT_BANNER,
                                   sizeof(LIBSSH2_SSH_DEFAULT_BANNER) - 1);
         }
 
@@ -1139,14 +1139,14 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv,
                                                           session->local.crypt->
-                                                          iv_len, "A");
+                                                          iv_len, (unsigned char *)"A");
             if (!iv) {
                 ret = -1;
                 goto clean_exit;
             }
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret,
                                                           session->local.crypt->
-                                                          secret_len, "C");
+                                                          secret_len, (unsigned char *)"C");
             if (!secret) {
                 LIBSSH2_FREE(session, iv);
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
@@ -1186,14 +1186,14 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(iv,
                                                           session->remote.crypt->
-                                                          iv_len, "B");
+                                                          iv_len, (unsigned char *)"B");
             if (!iv) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
             }
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(secret,
                                                           session->remote.crypt->
-                                                          secret_len, "D");
+                                                          secret_len, (unsigned char *)"D");
             if (!secret) {
                 LIBSSH2_FREE(session, iv);
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
@@ -1231,7 +1231,7 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key,
                                                           session->local.mac->
-                                                          key_len, "E");
+                                                          key_len, (unsigned char *)"E");
             if (!key) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
@@ -1256,8 +1256,8 @@ static int diffie_hellman_sha256(LIBSSH2_SESSION *session,
             int free_key = 0;
 
             LIBSSH2_KEX_METHOD_DIFFIE_HELLMAN_SHA256_HASH(key,
-                                                          session->remote.mac->
-                                                          key_len, "F");
+                                                          session->remote.mac->key_len,
+                                                          (unsigned char *)"F");
             if (!key) {
                 ret = LIBSSH2_ERROR_KEX_FAILURE;
                 goto clean_exit;
diff --git a/src/userauth.c b/src/userauth.c
index cdfa25e..51c6afb 100644
--- a/src/userauth.c
+++ b/src/userauth.c
@@ -786,6 +786,10 @@ userauth_hostbased_fromfile(LIBSSH2_SESSION *session,
 {
     int rc;
 
+#if !LIBSSH2_RSA
+    return -1;
+#endif
+
     if (session->userauth_host_state == libssh2_NB_state_idle) {
         const LIBSSH2_HOSTKEY_METHOD *privkeyobj;
         unsigned char *pubkeydata, *sig = NULL;
@@ -1378,6 +1382,10 @@ userauth_publickey_frommemory(LIBSSH2_SESSION *session,
     void *abstract = &privkey_file;
     int rc;
 
+#if !LIBSSH2_RSA
+    return -1;
+#endif
+
     privkey_file.filename = privatekeydata;
     privkey_file.passphrase = passphrase;
 
@@ -1435,6 +1443,10 @@ userauth_publickey_fromfile(LIBSSH2_SESSION *session,
     void *abstract = &privkey_file;
     int rc;
 
+#if !LIBSSH2_RSA
+    return -1;
+#endif
+
     privkey_file.filename = privatekey;
     privkey_file.passphrase = passphrase;
 
_______________________________________________
libssh2-devel https://cool.haxx.se/cgi-bin/mailman/listinfo/libssh2-devel

Reply via email to