From d8df6943acde5b3c813efd9b116ddf2d1d4ff00e Mon Sep 17 00:00:00 2001 From: Guus Sliepen Date: Thu, 17 Apr 2014 18:51:16 +0200 Subject: [PATCH] Get rid of OpenSSL entirely. \o/ --- COPYING.README | 6 - README | 8 +- README.android | 9 +- README.git | 1 - configure.ac | 2 - m4/openssl.m4 | 56 -------- src/Makefile.am | 9 +- src/openssl/cipher.c | 289 ----------------------------------------- src/openssl/crypto.c | 49 ------- src/openssl/digest.c | 140 -------------------- src/openssl/digest.h | 32 ----- src/openssl/ecdh.c | 96 -------------- src/openssl/ecdsa.c | 131 ------------------- src/openssl/ecdsagen.c | 58 --------- src/openssl/prf.c | 84 ------------ 15 files changed, 7 insertions(+), 963 deletions(-) delete mode 100644 COPYING.README delete mode 100644 m4/openssl.m4 delete mode 100644 src/openssl/cipher.c delete mode 100644 src/openssl/crypto.c delete mode 100644 src/openssl/digest.c delete mode 100644 src/openssl/digest.h delete mode 100644 src/openssl/ecdh.c delete mode 100644 src/openssl/ecdsa.c delete mode 100644 src/openssl/ecdsagen.c delete mode 100644 src/openssl/prf.c diff --git a/COPYING.README b/COPYING.README deleted file mode 100644 index bb776e71..00000000 --- a/COPYING.README +++ /dev/null @@ -1,6 +0,0 @@ -The following applies to MeshLink: - -This program is released under the GPL with the additional exemption that -compiling, linking, and/or using OpenSSL is allowed. You may provide binary -packages linked to the OpenSSL libraries, provided that all other requirements -of the GPL are met. diff --git a/README b/README index 57c28699..714d8211 100644 --- a/README +++ b/README @@ -21,11 +21,7 @@ Please do not use this library yet. Requirements ------------ -In order to compile MeshLink, you will need a GNU C compiler environment. Please -ensure you have the latest stable versions of all the required libraries: - -- OpenSSL (http://www.openssl.org/) version 1.0.0 or later, with support for - elliptic curve cryptography (ECC) and Galois counter mode (GCM) enabled. +In order to compile MeshLink, you will need a GNU C compiler environment. The following libraries are used by default, but can be disabled if necessary: @@ -46,4 +42,4 @@ Other noteworthy features are: - IPv6 support - NAT traversal (requires at least one node that is not behind a NAT) - Ed25519 keys (TBD) -- AES-256-GCM encryption and message authentication +- ChaCha-Poly1305 encryption and message authentication diff --git a/README.android b/README.android index 4d8a0e9a..42b21368 100644 --- a/README.android +++ b/README.android @@ -5,16 +5,9 @@ wget http://dl.google.com/android/ndk/android-ndk-r8b-linux-x86.tar.bz2 tar xfj android-ndk-r8b-linux-x86.tar.bz2 ./android-ndk-r8b/build/tools/make-standalone-toolchain.sh --platform=android-5 --install-dir=/tmp/my-android-toolchain -- Download and cross-compile openSSL for ARM: -wget http://www.openssl.org/source/openssl-1.0.1c.tar.gz -tar xfz openssl-1.0.1c.tar.gz -cd openssl-1.0.1c -./Configure dist -make CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc AR="/tmp/my-android-toolchain/bin/arm-linux-androideabi-ar r" RANLIB=/tmp/my-android-toolchain/bin/arm-linux-androideabi-ranlib - - Clone and cross-compile MeshLink: git clone git://meshlink.io/meshlink cd meshlink autoreconf -fsi -CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux --disable-lzo --with-openssl-lib=$HOME/android/openssl-1.0.1c --with-openssl-include=$HOME/android/openssl-1.0.1c/include/ +CC=/tmp/my-android-toolchain/bin/arm-linux-androideabi-gcc ./configure --host=arm-linux make -j5 diff --git a/README.git b/README.git index 21488936..d973ca23 100644 --- a/README.git +++ b/README.git @@ -1,7 +1,6 @@ Before you can start compiling MeshLink from a fresh git clone, you have to install the very latest versions of the following packages: -- OpenSSL - zlib - GCC - automake diff --git a/configure.ac b/configure.ac index 454f2d9a..b163474a 100644 --- a/configure.ac +++ b/configure.ac @@ -179,8 +179,6 @@ dnl These are defined in files in m4/ MeshLink_ZLIB -MeshLink_OPENSSL - AC_CONFIG_FILES([Makefile src/Makefile doc/Makefile m4/Makefile test/Makefile]) AC_OUTPUT diff --git a/m4/openssl.m4 b/m4/openssl.m4 deleted file mode 100644 index fba06fd3..00000000 --- a/m4/openssl.m4 +++ /dev/null @@ -1,56 +0,0 @@ -dnl Check to find the OpenSSL headers/libraries - -AC_DEFUN([MeshLink_OPENSSL], -[ - case $host_os in - *mingw*) - ;; - *) - AC_CHECK_FUNC(dlopen, - [], - [AC_CHECK_LIB(dl, dlopen, - [LIBS="$LIBS -ldl"], - [AC_MSG_ERROR([OpenSSL depends on libdl.]); break] - )] - ) - ;; - esac - - AC_ARG_WITH(openssl, - AS_HELP_STRING([--with-openssl=DIR], [OpenSSL base directory, or:]), - [openssl="$withval" - CPPFLAGS="$CPPFLAGS -I$withval/include" - LDFLAGS="$LDFLAGS -L$withval/lib"] - ) - - AC_ARG_WITH(openssl-include, - AS_HELP_STRING([--with-openssl-include=DIR], [OpenSSL headers directory (without trailing /openssl)]), - [openssl_include="$withval" - CPPFLAGS="$CPPFLAGS -I$withval"] - ) - - AC_ARG_WITH(openssl-lib, - AS_HELP_STRING([--with-openssl-lib=DIR], [OpenSSL library directory]), - [openssl_lib="$withval" - LDFLAGS="$LDFLAGS -L$withval"] - ) - - AC_CHECK_HEADERS([openssl/evp.h openssl/rsa.h openssl/rand.h openssl/err.h openssl/sha.h openssl/pem.h openssl/engine.h openssl/ecdh.h openssl/ec.h], - [], - [AC_MSG_ERROR([OpenSSL header files not found.]); break] - ) - - AC_CHECK_LIB(crypto, EVP_EncryptInit_ex, - [LIBS="-lcrypto $LIBS"], - [AC_MSG_ERROR([OpenSSL libraries not found.])] - ) - - AC_CHECK_FUNCS([RAND_pseudo_bytes EVP_EncryptInit_ex ECDH_compute_key ECDSA_verify], , - [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], - ) - - AC_CHECK_DECLS([OpenSSL_add_all_algorithms, EVP_CTRL_GCM_GET_TAG], , - [AC_MSG_ERROR([Missing OpenSSL functionality, make sure you have installed the latest version.]); break], - [#include ] - ) -]) diff --git a/src/Makefile.am b/src/Makefile.am index 2682c4c1..8f02c06d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -29,6 +29,7 @@ chacha_poly1305_SOURCES = \ chacha-poly1305/poly1305.c chacha-poly1305/poly1305.h sptps_test_SOURCES = \ + crypto.c crypto.h \ logger.c logger.h \ prf.c prf.h \ sptps.c sptps.h \ @@ -38,11 +39,13 @@ sptps_test_SOURCES = \ $(chacha_poly1305_SOURCES) sptps_keypair_SOURCES = \ + crypto.c crypto.h \ sptps_keypair.c \ utils.c utils.h \ $(ed25519_SOURCES) sptps_speed_SOURCES = \ + crypto.c crypto.h \ logger.c logger.h \ prf.c prf.h \ sptps.c sptps.h \ @@ -59,7 +62,7 @@ libmeshlink_la_SOURCES = \ cipher.h \ conf.c conf.h \ connection.c connection.h \ - crypto.h \ + crypto.c crypto.h \ dropin.c dropin.h \ ecdh.h \ ecdsa.h \ @@ -102,19 +105,15 @@ libmeshlink_la_CFLAGS = -fPIC libmeshlink_la_LIBADD = -lpthread libmeshlink_la_SOURCES += \ - openssl/crypto.c \ ed25519/ecdh.c \ ed25519/ecdsa.c \ ed25519/ecdsagen.c sptps_test_SOURCES += \ - openssl/crypto.c \ ed25519/ecdh.c \ ed25519/ecdsa.c sptps_keypair_SOURCES += \ - openssl/crypto.c \ ed25519/ecdsagen.c sptps_speed_SOURCES += \ - openssl/crypto.c \ ed25519/ecdh.c \ ed25519/ecdsa.c \ ed25519/ecdsagen.c diff --git a/src/openssl/cipher.c b/src/openssl/cipher.c deleted file mode 100644 index 8faed39d..00000000 --- a/src/openssl/cipher.c +++ /dev/null @@ -1,289 +0,0 @@ -/* - cipher.c -- Symmetric block cipher handling - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include - -#include "../cipher.h" -#include "../logger.h" -#include "../xalloc.h" - -struct cipher { - EVP_CIPHER_CTX ctx; - const EVP_CIPHER *cipher; - struct cipher_counter *counter; -}; - -typedef struct cipher_counter { - unsigned char counter[CIPHER_MAX_IV_SIZE]; - unsigned char block[CIPHER_MAX_IV_SIZE]; - int n; -} cipher_counter_t; - -static cipher_t *cipher_open(const EVP_CIPHER *evp_cipher) { - cipher_t *cipher = xzalloc(sizeof *cipher); - cipher->cipher = evp_cipher; - EVP_CIPHER_CTX_init(&cipher->ctx); - - return cipher; -} - -cipher_t *cipher_open_by_name(const char *name) { - const EVP_CIPHER *evp_cipher = EVP_get_cipherbyname(name); - if(!evp_cipher) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher name '%s'!", name); - return NULL; - } - - return cipher_open(evp_cipher); -} - -cipher_t *cipher_open_by_nid(int nid) { - const EVP_CIPHER *evp_cipher = EVP_get_cipherbynid(nid); - if(!evp_cipher) { - logger(DEBUG_ALWAYS, LOG_ERR, "Unknown cipher nid %d!", nid); - return NULL; - } - - return cipher_open(evp_cipher); -} - -cipher_t *cipher_open_blowfish_ofb(void) { - return cipher_open(EVP_bf_ofb()); -} - -void cipher_close(cipher_t *cipher) { - if(!cipher) - return; - - EVP_CIPHER_CTX_cleanup(&cipher->ctx); - free(cipher->counter); - free(cipher); -} - -size_t cipher_keylength(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) - return 0; - - return cipher->cipher->key_len + cipher->cipher->iv_len; -} - -bool cipher_set_key(cipher_t *cipher, void *key, bool encrypt) { - bool result; - - if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); - else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, (unsigned char *)key + cipher->cipher->key_len); - - if(result) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_set_key_from_rsa(cipher_t *cipher, void *key, size_t len, bool encrypt) { - bool result; - - if(encrypt) - result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); - else - result = EVP_DecryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key + len - cipher->cipher->key_len, (unsigned char *)key + len - cipher->cipher->iv_len - cipher->cipher->key_len); - - if(result) - return true; - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_set_counter(cipher_t *cipher, const void *counter, size_t len) { - if(len > cipher->cipher->iv_len - 4) { - logger(DEBUG_ALWAYS, LOG_ERR, "Counter too long"); - return false; - } - - memcpy(cipher->counter->counter, counter, len); - cipher->counter->n = 0; - - return true; -} - -bool cipher_set_counter_key(cipher_t *cipher, void *key) { - int result = EVP_EncryptInit_ex(&cipher->ctx, cipher->cipher, NULL, (unsigned char *)key, NULL); - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while setting key: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!cipher->counter) - cipher->counter = xzalloc(sizeof *cipher->counter); - else - cipher->counter->n = 0; - - memcpy(cipher->counter->counter, (unsigned char *)key + cipher->cipher->key_len, cipher->cipher->iv_len); - - return true; -} - -bool cipher_gcm_encrypt_start(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - int len = 0; - if(!EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, cipher->counter->counter) - || (inlen && !EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - if(outlen) - *outlen = len; - return true; -} - -bool cipher_gcm_encrypt_finish(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - int len = 0, pad = 0; - if((inlen && !EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen)) - || !EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - EVP_CIPHER_CTX_ctrl(&cipher->ctx, EVP_CTRL_GCM_GET_TAG, 16, (unsigned char *)outdata + len + pad); - if(outlen) - *outlen = len + pad + 16; - return true; -} - -bool cipher_gcm_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - int len = 0, pad = 0; - if(!EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, cipher->counter->counter) || - !EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen) || - !EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - EVP_CIPHER_CTX_ctrl(&cipher->ctx, EVP_CTRL_GCM_GET_TAG, 16, (unsigned char *)outdata + len + pad); - if(outlen) - *outlen = len + pad + 16; - return true; -} - -bool cipher_gcm_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - if(inlen < 16) - return false; - - int len = 0, pad = 0; - if(!EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, cipher->counter->counter)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - EVP_CIPHER_CTX_ctrl(&cipher->ctx, EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)indata + inlen - 16); - - if(!EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen - 16) || - !EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - if(outlen) - *outlen = len; - return true; -} - -bool cipher_gcm_decrypt_start(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - int len = 0; - if(!EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, cipher->counter->counter) - || (inlen && !EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen))) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - if(outlen) - *outlen = len; - return true; -} - -bool cipher_gcm_decrypt_finish(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen) { - if(inlen < 16) - return false; - - EVP_CIPHER_CTX_ctrl(&cipher->ctx, EVP_CTRL_GCM_SET_TAG, 16, (unsigned char *)indata + inlen - 16); - - int len = 0, pad = 0; - if((inlen > 16 && !EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, (unsigned char *)indata, inlen - 16)) - || !EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - return true; -} - - -bool cipher_encrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - if(EVP_EncryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_EncryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_EncryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; - return true; - } - } else { - int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while encrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -bool cipher_decrypt(cipher_t *cipher, const void *indata, size_t inlen, void *outdata, size_t *outlen, bool oneshot) { - if(oneshot) { - int len, pad; - if(EVP_DecryptInit_ex(&cipher->ctx, NULL, NULL, NULL, NULL) - && EVP_DecryptUpdate(&cipher->ctx, (unsigned char *)outdata, &len, indata, inlen) - && EVP_DecryptFinal(&cipher->ctx, (unsigned char *)outdata + len, &pad)) { - if(outlen) *outlen = len + pad; - return true; - } - } else { - int len; - if(EVP_EncryptUpdate(&cipher->ctx, outdata, &len, indata, inlen)) { - if(outlen) *outlen = len; - return true; - } - } - - logger(DEBUG_ALWAYS, LOG_ERR, "Error while decrypting: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; -} - -int cipher_get_nid(const cipher_t *cipher) { - if(!cipher || !cipher->cipher) - return 0; - - return cipher->cipher->nid; -} - -bool cipher_active(const cipher_t *cipher) { - return cipher && cipher->cipher && cipher->cipher->nid != 0; -} diff --git a/src/openssl/crypto.c b/src/openssl/crypto.c deleted file mode 100644 index 8fc63e3c..00000000 --- a/src/openssl/crypto.c +++ /dev/null @@ -1,49 +0,0 @@ -/* - crypto.c -- Cryptographic miscellaneous functions and initialisation - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include - -#include "../crypto.h" - -void crypto_init(void) { - RAND_load_file("/dev/urandom", 1024); - - ENGINE_load_builtin_engines(); - ENGINE_register_all_complete(); - - ERR_load_crypto_strings(); - OpenSSL_add_all_algorithms(); - - if(!RAND_status()) { - fprintf(stderr, "Not enough entropy for the PRNG!\n"); - abort(); - } -} - -void crypto_exit(void) { - EVP_cleanup(); -} - -void randomize(void *out, size_t outlen) { - RAND_pseudo_bytes(out, outlen); -} diff --git a/src/openssl/digest.c b/src/openssl/digest.c deleted file mode 100644 index 8d6e64da..00000000 --- a/src/openssl/digest.c +++ /dev/null @@ -1,140 +0,0 @@ -/* - digest.c -- Digest handling - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" -#include "../utils.h" -#include "../xalloc.h" - -#include -#include - -#include "digest.h" -#include "../digest.h" -#include "../logger.h" - -static digest_t *digest_open(const EVP_MD *evp_md, int maclength) { - digest_t *digest = xzalloc(sizeof *digest); - digest->digest = evp_md; - - int digestlen = EVP_MD_size(digest->digest); - - if(maclength > digestlen || maclength < 0) - digest->maclength = digestlen; - else - digest->maclength = maclength; - - return digest; -} - -digest_t *digest_open_by_name(const char *name, int maclength) { - const EVP_MD *evp_md = EVP_get_digestbyname(name); - - if(!evp_md) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest name '%s'!", name); - return false; - } - - return digest_open(evp_md, maclength); -} - -digest_t *digest_open_by_nid(int nid, int maclength) { - const EVP_MD *evp_md = EVP_get_digestbynid(nid); - - if(!evp_md) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Unknown digest nid %d!", nid); - return false; - } - - return digest_open(evp_md, maclength); -} - -digest_t *digest_open_sha1(int maclength) { - return digest_open(EVP_sha1(), maclength); -} - -bool digest_set_key(digest_t *digest, const void *key, size_t len) { - digest->key = xrealloc(digest->key, len); - memcpy(digest->key, key, len); - digest->keylength = len; - return true; -} - -void digest_close(digest_t *digest) { - if(!digest) - return; - - free(digest->key); - free(digest); -} - -bool digest_create(digest_t *digest, const void *indata, size_t inlen, void *outdata) { - size_t len = EVP_MD_size(digest->digest); - unsigned char tmpdata[len]; - - if(digest->key) { - if(!HMAC(digest->digest, digest->key, digest->keylength, indata, inlen, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - } else { - EVP_MD_CTX ctx; - - if(!EVP_DigestInit(&ctx, digest->digest) - || !EVP_DigestUpdate(&ctx, indata, inlen) - || !EVP_DigestFinal(&ctx, tmpdata, NULL)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "Error creating digest: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - } - - memcpy(outdata, tmpdata, digest->maclength); - return true; -} - -bool digest_verify(digest_t *digest, const void *indata, size_t inlen, const void *cmpdata) { - size_t len = digest->maclength; - unsigned char outdata[len]; - - return digest_create(digest, indata, inlen, outdata) && !memcmp(cmpdata, outdata, digest->maclength); -} - -int digest_get_nid(const digest_t *digest) { - if(!digest || !digest->digest) - return 0; - - return digest->digest->type; -} - -size_t digest_keylength(const digest_t *digest) { - if(!digest || !digest->digest) - return 0; - - return digest->digest->md_size; -} - -size_t digest_length(const digest_t *digest) { - if(!digest) - return 0; - - return digest->maclength; -} - -bool digest_active(const digest_t *digest) { - return digest && digest->digest && digest->digest->type != 0; -} diff --git a/src/openssl/digest.h b/src/openssl/digest.h deleted file mode 100644 index 0a0c9125..00000000 --- a/src/openssl/digest.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - digest.h -- header file digest.c - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#ifndef __TINC_OPENSSL_DIGEST_H__ -#define __TINC_OPENSSL_DIGEST_H__ - -#include - -struct digest { - const EVP_MD *digest; - int maclength; - int keylength; - char *key; -}; - -#endif diff --git a/src/openssl/ecdh.c b/src/openssl/ecdh.c deleted file mode 100644 index 14e62176..00000000 --- a/src/openssl/ecdh.c +++ /dev/null @@ -1,96 +0,0 @@ -/* - ecdh.c -- Diffie-Hellman key exchange handling - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include -#include - -#define __TINC_ECDH_INTERNAL__ -typedef EC_KEY ecdh_t; - -#include "../ecdh.h" -#include "../logger.h" -#include "../utils.h" -#include "../xalloc.h" - -ecdh_t *ecdh_generate_public(void *pubkey) { - ecdh_t *ecdh = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!ecdh) { - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - if(!EC_KEY_generate_key(ecdh)) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - const EC_POINT *point = EC_KEY_get0_public_key(ecdh); - if(!point) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Getting public key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - size_t result = EC_POINT_point2oct(EC_KEY_get0_group(ecdh), point, POINT_CONVERSION_COMPRESSED, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Converting EC_POINT to binary failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - return ecdh; -} - -bool ecdh_compute_shared(ecdh_t *ecdh, const void *pubkey, void *shared) { - EC_POINT *point = EC_POINT_new(EC_KEY_get0_group(ecdh)); - if(!point) { - logger(DEBUG_ALWAYS, LOG_ERR, "EC_POINT_new() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - EC_KEY_free(ecdh); - return false; - } - - int result = EC_POINT_oct2point(EC_KEY_get0_group(ecdh), point, pubkey, ECDH_SIZE, NULL); - if(!result) { - EC_POINT_free(point); - EC_KEY_free(ecdh); - logger(DEBUG_ALWAYS, LOG_ERR, "Converting binary to EC_POINT failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - result = ECDH_compute_key(shared, ECDH_SIZE, point, ecdh, NULL); - EC_POINT_free(point); - EC_KEY_free(ecdh); - - if(!result) { - logger(DEBUG_ALWAYS, LOG_ERR, "Computing Elliptic Curve Diffie-Hellman shared key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -void ecdh_free(ecdh_t *ecdh) { - if(ecdh) - EC_KEY_free(ecdh); -} diff --git a/src/openssl/ecdsa.c b/src/openssl/ecdsa.c deleted file mode 100644 index d0307455..00000000 --- a/src/openssl/ecdsa.c +++ /dev/null @@ -1,131 +0,0 @@ -/* - ecdsa.c -- ECDSA key handling - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include - -#define __TINC_ECDSA_INTERNAL__ -typedef EC_KEY ecdsa_t; - -#include "../logger.h" -#include "../ecdsa.h" -#include "../utils.h" -#include "../xalloc.h" - -// Get and set ECDSA keys -// -ecdsa_t *ecdsa_set_base64_public_key(const char *p) { - ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - if(!ecdsa) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "EC_KEY_new_by_curve_name failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return NULL; - } - - int len = strlen(p); - unsigned char pubkey[len / 4 * 3 + 3]; - const unsigned char *ppubkey = pubkey; - len = b64decode(p, (char *)pubkey, len); - - if(!o2i_ECPublicKey(&ecdsa, &ppubkey, len)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "o2i_ECPublicKey failed: %s", ERR_error_string(ERR_get_error(), NULL)); - EC_KEY_free(ecdsa); - return NULL; - } - - return ecdsa; -} - -char *ecdsa_get_base64_public_key(ecdsa_t *ecdsa) { - unsigned char *pubkey = NULL; - int len = i2o_ECPublicKey(ecdsa, &pubkey); - - char *base64 = xmalloc(len * 4 / 3 + 5); - b64encode((char *)pubkey, base64, len); - - free(pubkey); - - return base64; -} - -// Read PEM ECDSA keys - -ecdsa_t *ecdsa_read_pem_public_key(FILE *fp) { - ecdsa_t *ecdsa = PEM_read_EC_PUBKEY(fp, NULL, NULL, NULL); - - if(!ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA public key: %s", ERR_error_string(ERR_get_error(), NULL)); - - return ecdsa; -} - -ecdsa_t *ecdsa_read_pem_private_key(FILE *fp) { - ecdsa_t *ecdsa = PEM_read_ECPrivateKey(fp, NULL, NULL, NULL); - - if(!ecdsa) - logger(DEBUG_ALWAYS, LOG_ERR, "Unable to read ECDSA private key: %s", ERR_error_string(ERR_get_error(), NULL)); - - return ecdsa; -} - -size_t ecdsa_size(ecdsa_t *ecdsa) { - return ECDSA_size(ecdsa); -} - -// TODO: standardise output format? - -bool ecdsa_sign(ecdsa_t *ecdsa, const void *in, size_t len, void *sig) { - unsigned int siglen = ECDSA_size(ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - memset(sig, 0, siglen); - - if(!ECDSA_sign(0, hash, sizeof hash, sig, &siglen, ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_sign() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_verify(ecdsa_t *ecdsa, const void *in, size_t len, const void *sig) { - unsigned int siglen = ECDSA_size(ecdsa); - - unsigned char hash[SHA512_DIGEST_LENGTH]; - SHA512(in, len, hash); - - if(!ECDSA_verify(0, hash, sizeof hash, sig, siglen, ecdsa)) { - logger(DEBUG_ALWAYS, LOG_DEBUG, "ECDSA_verify() failed: %s", ERR_error_string(ERR_get_error(), NULL)); - return false; - } - - return true; -} - -bool ecdsa_active(ecdsa_t *ecdsa) { - return ecdsa; -} - -void ecdsa_free(ecdsa_t *ecdsa) { - if(ecdsa) - EC_KEY_free(ecdsa); -} diff --git a/src/openssl/ecdsagen.c b/src/openssl/ecdsagen.c deleted file mode 100644 index 8794da03..00000000 --- a/src/openssl/ecdsagen.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - ecdsagen.c -- ECDSA key generation and export - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include -#include -#include - -#define __TINC_ECDSA_INTERNAL__ -typedef EC_KEY ecdsa_t; - -#include "../ecdsagen.h" -#include "../utils.h" -#include "../xalloc.h" - -// Generate ECDSA key - -ecdsa_t *ecdsa_generate(void) { - ecdsa_t *ecdsa = EC_KEY_new_by_curve_name(NID_secp521r1); - - if(!ecdsa || !EC_KEY_generate_key(ecdsa)) { - fprintf(stderr, "Generating EC key failed: %s", ERR_error_string(ERR_get_error(), NULL)); - ecdsa_free(ecdsa); - return false; - } - - EC_KEY_set_asn1_flag(ecdsa, OPENSSL_EC_NAMED_CURVE); - EC_KEY_set_conv_form(ecdsa, POINT_CONVERSION_COMPRESSED); - - return ecdsa; -} - -// Write PEM ECDSA keys - -bool ecdsa_write_pem_public_key(ecdsa_t *ecdsa, FILE *fp) { - return PEM_write_EC_PUBKEY(fp, ecdsa); -} - -bool ecdsa_write_pem_private_key(ecdsa_t *ecdsa, FILE *fp) { - return PEM_write_ECPrivateKey(fp, ecdsa, NULL, NULL, 0, NULL, NULL); -} diff --git a/src/openssl/prf.c b/src/openssl/prf.c deleted file mode 100644 index 88bb914b..00000000 --- a/src/openssl/prf.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - prf.c -- Pseudo-Random Function for key material generation - Copyright (C) 2014 Guus Sliepen - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. -*/ - -#include "../system.h" - -#include - -#include "digest.h" -#include "../digest.h" -#include "../prf.h" - -/* Generate key material from a master secret and a seed, based on RFC 4346 section 5. - We use SHA512 instead of MD5 and SHA1. - */ - -static bool prf_xor(int nid, const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, ssize_t outlen) { - digest_t *digest = digest_open_by_nid(nid, -1); - - if(!digest) - return false; - - if(!digest_set_key(digest, secret, secretlen)) { - digest_close(digest); - return false; - } - - size_t len = digest_length(digest); - - /* Data is what the "inner" HMAC function processes. - It consists of the previous HMAC result plus the seed. - */ - - char data[len + seedlen]; - memset(data, 0, len); - memcpy(data + len, seed, seedlen); - - char hash[len]; - - while(outlen > 0) { - /* Inner HMAC */ - if(!digest_create(digest, data, len + seedlen, data)) { - digest_close(digest); - return false; - } - - /* Outer HMAC */ - if(!digest_create(digest, data, len + seedlen, hash)) { - digest_close(digest); - return false; - } - - /* XOR the results of the outer HMAC into the out buffer */ - for(int i = 0; i < len && i < outlen; i++) - *out++ ^= hash[i]; - - outlen -= len; - } - - digest_close(digest); - return true; -} - -bool prf(const char *secret, size_t secretlen, char *seed, size_t seedlen, char *out, size_t outlen) { - /* This construction allows us to easily switch back to a scheme where the PRF is calculated using two different digest algorithms. */ - memset(out, 0, outlen); - - return prf_xor(NID_sha512, secret, secretlen, seed, seedlen, out, outlen); -} -- 2.39.2