diff options
Diffstat (limited to 'libs/libssh2/src/mbedtls.c')
-rw-r--r-- | libs/libssh2/src/mbedtls.c | 733 |
1 files changed, 0 insertions, 733 deletions
diff --git a/libs/libssh2/src/mbedtls.c b/libs/libssh2/src/mbedtls.c deleted file mode 100644 index 8bbcfd8d0d..0000000000 --- a/libs/libssh2/src/mbedtls.c +++ /dev/null @@ -1,733 +0,0 @@ -/* Copyright (c) 2016, Art <https://github.com/wildart> - * All rights reserved. - * - * 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" - -#ifdef LIBSSH2_MBEDTLS /* compile only if we build with mbedtls */ - -/*******************************************************************/ -/* - * mbedTLS backend: Global context handles - */ - -static mbedtls_entropy_context _libssh2_mbedtls_entropy; -static mbedtls_ctr_drbg_context _libssh2_mbedtls_ctr_drbg; - -/*******************************************************************/ -/* - * mbedTLS backend: Generic functions - */ - -void -_libssh2_mbedtls_init(void) -{ - int ret; - - mbedtls_entropy_init(&_libssh2_mbedtls_entropy); - mbedtls_ctr_drbg_init(&_libssh2_mbedtls_ctr_drbg); - - ret = mbedtls_ctr_drbg_seed(&_libssh2_mbedtls_ctr_drbg, - mbedtls_entropy_func, - &_libssh2_mbedtls_entropy, NULL, 0); - if(ret != 0) - mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); -} - -void -_libssh2_mbedtls_free(void) -{ - mbedtls_ctr_drbg_free(&_libssh2_mbedtls_ctr_drbg); - mbedtls_entropy_free(&_libssh2_mbedtls_entropy); -} - -int -_libssh2_mbedtls_random(unsigned char *buf, int len) -{ - int ret; - ret = mbedtls_ctr_drbg_random(&_libssh2_mbedtls_ctr_drbg, buf, len); - return ret == 0 ? 0 : -1; -} - -static void -_libssh2_mbedtls_safe_free(void *buf, int len) -{ -#ifndef LIBSSH2_CLEAR_MEMORY - (void)len; -#endif - - if(!buf) - return; - -#ifdef LIBSSH2_CLEAR_MEMORY - if(len > 0) - memset(buf, 0, len); -#endif - - mbedtls_free(buf); -} - -int -_libssh2_mbedtls_cipher_init(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - unsigned char *iv, - unsigned char *secret, - int encrypt) -{ - const mbedtls_cipher_info_t *cipher_info; - int ret, op; - - if(!ctx) - return -1; - - op = encrypt == 0 ? MBEDTLS_ENCRYPT : MBEDTLS_DECRYPT; - - cipher_info = mbedtls_cipher_info_from_type(algo); - if(!cipher_info) - return -1; - - mbedtls_cipher_init(ctx); - ret = mbedtls_cipher_setup(ctx, cipher_info); - if(!ret) - ret = mbedtls_cipher_setkey(ctx, secret, cipher_info->key_bitlen, op); - - if(!ret) - ret = mbedtls_cipher_set_iv(ctx, iv, cipher_info->iv_size); - - return ret == 0 ? 0 : -1; -} - -int -_libssh2_mbedtls_cipher_crypt(_libssh2_cipher_ctx *ctx, - _libssh2_cipher_type(algo), - int encrypt, - unsigned char *block, - size_t blocklen) -{ - int ret; - unsigned char *output; - size_t osize, olen, finish_olen; - - (void) encrypt; - (void) algo; - - osize = blocklen + mbedtls_cipher_get_block_size(ctx); - - output = (unsigned char *)mbedtls_calloc(osize, sizeof(char)); - if(output) { - ret = mbedtls_cipher_reset(ctx); - - if(!ret) - ret = mbedtls_cipher_update(ctx, block, blocklen, output, &olen); - - if(!ret) - ret = mbedtls_cipher_finish(ctx, output + olen, &finish_olen); - - if(!ret) { - olen += finish_olen; - memcpy(block, output, olen); - } - - _libssh2_mbedtls_safe_free(output, osize); - } - else - ret = -1; - - return ret == 0 ? 0 : -1; -} - -void -_libssh2_mbedtls_cipher_dtor(_libssh2_cipher_ctx *ctx) -{ - mbedtls_cipher_free(ctx); -} - - -int -_libssh2_mbedtls_hash_init(mbedtls_md_context_t *ctx, - mbedtls_md_type_t mdtype, - const unsigned char *key, unsigned long keylen) -{ - const mbedtls_md_info_t *md_info; - int ret, hmac; - - md_info = mbedtls_md_info_from_type(mdtype); - if(!md_info) - return 0; - - hmac = key == NULL ? 0 : 1; - - mbedtls_md_init(ctx); - ret = mbedtls_md_setup(ctx, md_info, hmac); - if(!ret) { - if(hmac) - ret = mbedtls_md_hmac_starts(ctx, key, keylen); - else - ret = mbedtls_md_starts(ctx); - } - - return ret == 0 ? 1 : 0; -} - -int -_libssh2_mbedtls_hash_final(mbedtls_md_context_t *ctx, unsigned char *hash) -{ - int ret; - - ret = mbedtls_md_finish(ctx, hash); - mbedtls_md_free(ctx); - - return ret == 0 ? 0 : -1; -} - -int -_libssh2_mbedtls_hash(const unsigned char *data, unsigned long datalen, - mbedtls_md_type_t mdtype, unsigned char *hash) -{ - const mbedtls_md_info_t *md_info; - int ret; - - md_info = mbedtls_md_info_from_type(mdtype); - if(!md_info) - return 0; - - ret = mbedtls_md(md_info, data, datalen, hash); - - return ret == 0 ? 0 : -1; -} - -/*******************************************************************/ -/* - * mbedTLS backend: BigNumber functions - */ - -_libssh2_bn * -_libssh2_mbedtls_bignum_init(void) -{ - _libssh2_bn *bignum; - - bignum = (_libssh2_bn *)mbedtls_calloc(1, sizeof(_libssh2_bn)); - if(bignum) { - mbedtls_mpi_init(bignum); - } - - return bignum; -} - -void -_libssh2_mbedtls_bignum_free(_libssh2_bn *bn) -{ - if(bn) { - mbedtls_mpi_free(bn); - mbedtls_free(bn); - } -} - -static int -_libssh2_mbedtls_bignum_random(_libssh2_bn *bn, int bits, int top, int bottom) -{ - size_t len; - int err; - int i; - - if(!bn || bits <= 0) - return -1; - - len = (bits + 7) >> 3; - err = mbedtls_mpi_fill_random(bn, len, mbedtls_ctr_drbg_random, - &_libssh2_mbedtls_ctr_drbg); - if(err) - return -1; - - /* Zero unsued bits above the most significant bit*/ - for(i = len*8 - 1; bits <= i; --i) { - err = mbedtls_mpi_set_bit(bn, i, 0); - if(err) - return -1; - } - - /* If `top` is -1, the most significant bit of the random number can be - zero. If top is 0, the most significant bit of the random number 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. - */ - for(i = 0; i <= top; ++i) { - err = mbedtls_mpi_set_bit(bn, bits-i-1, 1); - if(err) - return -1; - } - - /* make odd by setting first bit in least significant byte */ - if(bottom) { - err = mbedtls_mpi_set_bit(bn, 0, 1); - if(err) - return -1; - } - - return 0; -} - - -/*******************************************************************/ -/* - * mbedTLS backend: RSA functions - */ - -int -_libssh2_mbedtls_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) -{ - int ret; - libssh2_rsa_ctx *ctx; - - ctx = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); - if(ctx != NULL) { - mbedtls_rsa_init(ctx, MBEDTLS_RSA_PKCS_V15, 0); - } - else - return -1; - - /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ - if((ret = mbedtls_mpi_read_binary(&(ctx->E), edata, elen) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->N), ndata, nlen) ) != 0) { - ret = -1; - } - - if(!ret) { - ctx->len = mbedtls_mpi_size(&(ctx->N)); - } - - if(!ret && ddata) { - /* !checksrc! disable ASSIGNWITHINCONDITION 1 */ - if((ret = mbedtls_mpi_read_binary(&(ctx->D), ddata, dlen) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->P), pdata, plen) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->Q), qdata, qlen) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->DP), e1data, e1len) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->DQ), e2data, e2len) ) != 0 || - (ret = mbedtls_mpi_read_binary(&(ctx->QP), coeffdata, coefflen) ) - != 0) { - ret = -1; - } - ret = mbedtls_rsa_check_privkey(ctx); - } - else if(!ret) { - ret = mbedtls_rsa_check_pubkey(ctx); - } - - if(ret && ctx) { - _libssh2_mbedtls_rsa_free(ctx); - ctx = NULL; - } - *rsa = ctx; - return ret; -} - -int -_libssh2_mbedtls_rsa_new_private(libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - const char *filename, - const unsigned char *passphrase) -{ - int ret; - mbedtls_pk_context pkey; - mbedtls_rsa_context *pk_rsa; - - *rsa = (libssh2_rsa_ctx *) LIBSSH2_ALLOC(session, sizeof(libssh2_rsa_ctx)); - if(*rsa == NULL) - return -1; - - mbedtls_rsa_init(*rsa, MBEDTLS_RSA_PKCS_V15, 0); - mbedtls_pk_init(&pkey); - - ret = mbedtls_pk_parse_keyfile(&pkey, filename, (char *)passphrase); - if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { - mbedtls_pk_free(&pkey); - mbedtls_rsa_free(*rsa); - LIBSSH2_FREE(session, *rsa); - *rsa = NULL; - return -1; - } - - pk_rsa = mbedtls_pk_rsa(pkey); - mbedtls_rsa_copy(*rsa, pk_rsa); - mbedtls_pk_free(&pkey); - - return 0; -} - -int -_libssh2_mbedtls_rsa_new_private_frommemory(libssh2_rsa_ctx **rsa, - LIBSSH2_SESSION *session, - const char *filedata, - size_t filedata_len, - unsigned const char *passphrase) -{ - int ret; - mbedtls_pk_context pkey; - mbedtls_rsa_context *pk_rsa; - void *filedata_nullterm; - size_t pwd_len; - - *rsa = (libssh2_rsa_ctx *) mbedtls_calloc(1, sizeof(libssh2_rsa_ctx)); - if(*rsa == NULL) - return -1; - - /* - mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" - private-key from memory will fail if the last byte is not a null byte - */ - filedata_nullterm = mbedtls_calloc(filedata_len + 1, 1); - if(filedata_nullterm == NULL) { - return -1; - } - memcpy(filedata_nullterm, filedata, filedata_len); - - mbedtls_pk_init(&pkey); - - pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; - ret = mbedtls_pk_parse_key(&pkey, (unsigned char *)filedata_nullterm, - filedata_len + 1, - passphrase, pwd_len); - _libssh2_mbedtls_safe_free(filedata_nullterm, filedata_len); - - if(ret != 0 || mbedtls_pk_get_type(&pkey) != MBEDTLS_PK_RSA) { - mbedtls_pk_free(&pkey); - mbedtls_rsa_free(*rsa); - LIBSSH2_FREE(session, *rsa); - *rsa = NULL; - return -1; - } - - pk_rsa = mbedtls_pk_rsa(pkey); - mbedtls_rsa_copy(*rsa, pk_rsa); - mbedtls_pk_free(&pkey); - - return 0; -} - -int -_libssh2_mbedtls_rsa_sha1_verify(libssh2_rsa_ctx *rsa, - const unsigned char *sig, - unsigned long sig_len, - const unsigned char *m, - unsigned long m_len) -{ - unsigned char hash[SHA_DIGEST_LENGTH]; - int ret; - - ret = _libssh2_mbedtls_hash(m, m_len, MBEDTLS_MD_SHA1, hash); - if(ret) - return -1; /* failure */ - - ret = mbedtls_rsa_pkcs1_verify(rsa, NULL, NULL, MBEDTLS_RSA_PUBLIC, - MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, - hash, sig); - - return (ret == 0) ? 0 : -1; -} - -int -_libssh2_mbedtls_rsa_sha1_sign(LIBSSH2_SESSION *session, - libssh2_rsa_ctx *rsa, - const unsigned char *hash, - size_t hash_len, - unsigned char **signature, - size_t *signature_len) -{ - int ret; - unsigned char *sig; - unsigned int sig_len; - - (void)hash_len; - - sig_len = rsa->len; - sig = LIBSSH2_ALLOC(session, sig_len); - if(!sig) { - return -1; - } - - ret = mbedtls_rsa_pkcs1_sign(rsa, NULL, NULL, MBEDTLS_RSA_PRIVATE, - MBEDTLS_MD_SHA1, SHA_DIGEST_LENGTH, - hash, sig); - if(ret) { - LIBSSH2_FREE(session, sig); - return -1; - } - - *signature = sig; - *signature_len = sig_len; - - return (ret == 0) ? 0 : -1; -} - -void -_libssh2_mbedtls_rsa_free(libssh2_rsa_ctx *ctx) -{ - mbedtls_rsa_free(ctx); - mbedtls_free(ctx); -} - -static unsigned char * -gen_publickey_from_rsa(LIBSSH2_SESSION *session, - mbedtls_rsa_context *rsa, - size_t *keylen) -{ - int e_bytes, n_bytes; - unsigned long len; - unsigned char *key; - unsigned char *p; - - e_bytes = mbedtls_mpi_size(&rsa->E); - n_bytes = mbedtls_mpi_size(&rsa->N); - - /* Key form is "ssh-rsa" + e + n. */ - len = 4 + 7 + 4 + e_bytes + 4 + n_bytes; - - key = LIBSSH2_ALLOC(session, len); - if(!key) { - return NULL; - } - - /* Process key encoding. */ - p = key; - - _libssh2_htonu32(p, 7); /* Key type. */ - p += 4; - memcpy(p, "ssh-rsa", 7); - p += 7; - - _libssh2_htonu32(p, e_bytes); - p += 4; - mbedtls_mpi_write_binary(&rsa->E, p, e_bytes); - - _libssh2_htonu32(p, n_bytes); - p += 4; - mbedtls_mpi_write_binary(&rsa->N, p, n_bytes); - - *keylen = (size_t)(p - key); - return key; -} - -static int -_libssh2_mbedtls_pub_priv_key(LIBSSH2_SESSION *session, - unsigned char **method, - size_t *method_len, - unsigned char **pubkeydata, - size_t *pubkeydata_len, - mbedtls_pk_context *pkey) -{ - unsigned char *key = NULL, *mth = NULL; - size_t keylen = 0, mthlen = 0; - int ret; - mbedtls_rsa_context *rsa; - - if(mbedtls_pk_get_type(pkey) != MBEDTLS_PK_RSA) { - mbedtls_pk_free(pkey); - return _libssh2_error(session, LIBSSH2_ERROR_FILE, - "Key type not supported"); - } - - /* write method */ - mthlen = 7; - mth = LIBSSH2_ALLOC(session, mthlen); - if(mth) { - memcpy(mth, "ssh-rsa", mthlen); - } - else { - ret = -1; - } - - rsa = mbedtls_pk_rsa(*pkey); - key = gen_publickey_from_rsa(session, rsa, &keylen); - if(key == NULL) { - ret = -1; - } - - /* write output */ - if(ret) { - if(mth) - LIBSSH2_FREE(session, mth); - if(key) - LIBSSH2_FREE(session, key); - } - else { - *method = mth; - *method_len = mthlen; - *pubkeydata = key; - *pubkeydata_len = keylen; - } - - return ret; -} - -int -_libssh2_mbedtls_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) -{ - mbedtls_pk_context pkey; - char buf[1024]; - int ret; - - mbedtls_pk_init(&pkey); - ret = mbedtls_pk_parse_keyfile(&pkey, privatekey, passphrase); - if(ret != 0) { - mbedtls_strerror(ret, (char *)buf, sizeof(buf)); - mbedtls_pk_free(&pkey); - return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); - } - - ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, - pubkeydata, pubkeydata_len, &pkey); - - mbedtls_pk_free(&pkey); - - return ret; -} - -int -_libssh2_mbedtls_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) -{ - mbedtls_pk_context pkey; - char buf[1024]; - int ret; - void *privatekeydata_nullterm; - size_t pwd_len; - - /* - mbedtls checks in "mbedtls/pkparse.c:1184" if "key[keylen - 1] != '\0'" - private-key from memory will fail if the last byte is not a null byte - */ - privatekeydata_nullterm = mbedtls_calloc(privatekeydata_len + 1, 1); - if(privatekeydata_nullterm == NULL) { - return -1; - } - memcpy(privatekeydata_nullterm, privatekeydata, privatekeydata_len); - - mbedtls_pk_init(&pkey); - - pwd_len = passphrase != NULL ? strlen((const char *)passphrase) : 0; - ret = mbedtls_pk_parse_key(&pkey, - (unsigned char *)privatekeydata_nullterm, - privatekeydata_len + 1, - (const unsigned char *)passphrase, pwd_len); - _libssh2_mbedtls_safe_free(privatekeydata_nullterm, privatekeydata_len); - - if(ret != 0) { - mbedtls_strerror(ret, (char *)buf, sizeof(buf)); - mbedtls_pk_free(&pkey); - return _libssh2_error(session, LIBSSH2_ERROR_FILE, buf); - } - - ret = _libssh2_mbedtls_pub_priv_key(session, method, method_len, - pubkeydata, pubkeydata_len, &pkey); - - mbedtls_pk_free(&pkey); - - return ret; -} - -void _libssh2_init_aes_ctr(void) -{ - /* no implementation */ -} - - -/*******************************************************************/ -/* - * mbedTLS backend: Diffie-Hellman functions - */ - -void -_libssh2_dh_init(_libssh2_dh_ctx *dhctx) -{ - *dhctx = _libssh2_mbedtls_bignum_init(); /* Random from client */ -} - -int -_libssh2_dh_key_pair(_libssh2_dh_ctx *dhctx, _libssh2_bn *public, - _libssh2_bn *g, _libssh2_bn *p, int group_order) -{ - /* Generate x and e */ - _libssh2_mbedtls_bignum_random(*dhctx, group_order * 8 - 1, 0, -1); - mbedtls_mpi_exp_mod(public, g, *dhctx, p, NULL); - return 0; -} - -int -_libssh2_dh_secret(_libssh2_dh_ctx *dhctx, _libssh2_bn *secret, - _libssh2_bn *f, _libssh2_bn *p) -{ - /* Compute the shared secret */ - mbedtls_mpi_exp_mod(secret, f, *dhctx, p, NULL); - return 0; -} - -void -_libssh2_dh_dtor(_libssh2_dh_ctx *dhctx) -{ - _libssh2_mbedtls_bignum_free(*dhctx); - *dhctx = NULL; -} - -#endif /* LIBSSH2_MBEDTLS */ |