diff --git a/Makefile.in b/Makefile.in index a12ade44..43266c6d 100644 --- a/Makefile.in +++ b/Makefile.in @@ -64,8 +64,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) am__CONFIG_DISTCLEAN_FILES = config.status config.cache config.log \ diff --git a/aclocal.m4 b/aclocal.m4 index e9136d93..479e0806 100644 --- a/aclocal.m4 +++ b/aclocal.m4 @@ -1172,3 +1172,4 @@ m4_include([m4/ltversion.m4]) m4_include([m4/lt~obsolete.m4]) m4_include([m4/openssl.m4]) m4_include([m4/polarssl.m4]) +m4_include([m4/mbedtls.m4]) diff --git a/configure b/configure index af155784..e381273f 100755 --- a/configure +++ b/configure @@ -783,6 +783,9 @@ with_openssl_lib with_polarssl with_polarssl_include with_polarssl_lib +with_mbedtls +with_mbedtls_include +with_mbedtls_lib enable_applecc enable_assert enable_largefile @@ -1440,7 +1443,7 @@ Optional Packages: (or the compiler's sysroot if not specified). --with-crypto-library=library build with the given crypto library, - TYPE=openssl|polarssl [default=openssl] + TYPE=openssl|polarssl|mbedtls [default=openssl] --with-openssl=DIR OpenSSL base directory, or: --with-openssl-include=DIR OpenSSL headers directory (without trailing @@ -1451,6 +1454,11 @@ Optional Packages: PolarSSL headers directory (without trailing /polarssl) --with-polarssl-lib=DIR PolarSSL library directory + --with-mbedtls=DIR mbed TLS base directory, or: + --with-mbedtls-include=DIR + mbed TLS headers directory (without trailing + /mbedtls) + --with-mbedtls-lib=DIR mbed TLS library directory Some influential environment variables: CC C compiler command @@ -11724,7 +11732,7 @@ CC="$lt_save_CC" if test "${with_crypto_library+set}" = set; then : withval=$with_crypto_library; case "${withval}" in - openssl|polarssl) ;; + openssl|polarssl|mbedtls) ;; *) as_fn_error $? "bad value ${withval} for --with-crypto-library" "$LINENO" 5 ;; esac @@ -13134,6 +13142,114 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext $as_echo "#define USE_CRYPTO_POLARSSL 1" >>confdefs.h + ;; + mbedtls) + + + +# Check whether --with-mbedtls was given. +if test "${with_mbedtls+set}" = set; then : + withval=$with_mbedtls; mbedtls="$withval" + CFLAGS="$CFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib" + +fi + + + +# Check whether --with-mbedtls-include was given. +if test "${with_mbedtls_include+set}" = set; then : + withval=$with_mbedtls_include; mbedtls_include="$withval" + CFLAGS="$CFLAGS -I$withval" + +fi + + + +# Check whether --with-mbedtls-lib was given. +if test "${with_mbedtls_lib+set}" = set; then : + withval=$with_mbedtls_lib; mbedtls_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval" + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking for mbedtls_cipher_setup in -lmbedcrypto" >&5 +$as_echo_n "checking for mbedtls_cipher_setup in -lmbedcrypto... " >&6; } +if ${ac_cv_lib_mbedtls_mbedtls_cipher_setup+:} false; then : + $as_echo_n "(cached) " >&6 +else + ac_check_lib_save_LIBS=$LIBS +LIBS="-lmbedcrypto $LIBS" +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +/* Override any GCC internal prototype to avoid an error. + Use char because int might match the return type of a GCC + builtin and then its argument prototype would still apply. */ +#ifdef __cplusplus +extern "C" +#endif +char mbedtls_cipher_setup (); +int +main () +{ +return mbedtls_cipher_setup (); + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO"; then : + ac_cv_lib_mbedtls_mbedtls_cipher_setup=yes +else + ac_cv_lib_mbedtls_mbedtls_cipher_setup=no +fi +rm -f core conftest.err conftest.$ac_objext \ + conftest$ac_exeext conftest.$ac_ext +LIBS=$ac_check_lib_save_LIBS +fi +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_mbedtls_mbedtls_cipher_setup" >&5 +$as_echo "$ac_cv_lib_mbedtls_mbedtls_cipher_setup" >&6; } +if test "x$ac_cv_lib_mbedtls_mbedtls_cipher_setup" = xyes; then : + LIBS="-lmbedcrypto $LIBS" +else + as_fn_error $? "mbed TLS libraries not found." "$LINENO" 5 + +fi + + + { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether mbedtls support Cipher Feedback mode or not" >&5 +$as_echo_n "checking whether mbedtls support Cipher Feedback mode or not... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +#include + +int +main () +{ + +#ifndef MBEDTLS_CIPHER_MODE_CFB +#error Cipher Feedback mode a.k.a CFB not supported by your mbed TLS. +#endif + + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO"; then : + { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 +$as_echo "ok" >&6; } +else + as_fn_error $? "MBEDTLS_CIPHER_MODE_CFB required" "$LINENO" 5 + +fi +rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext + + +$as_echo "#define USE_CRYPTO_MBEDTLS 1" >>confdefs.h + ;; esac diff --git a/configure.ac b/configure.ac index 87ce13db..74e1e45f 100755 --- a/configure.ac +++ b/configure.ac @@ -22,10 +22,10 @@ LT_INIT([dlopen]) dnl Checks for crypto library AC_ARG_WITH( [crypto-library], - [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|polarssl @<:@default=openssl@:>@])], + [AS_HELP_STRING([--with-crypto-library=library], [build with the given crypto library, TYPE=openssl|polarssl|mbedtls @<:@default=openssl@:>@])], [ case "${withval}" in - openssl|polarssl) ;; + openssl|polarssl|mbedtls) ;; *) AC_MSG_ERROR([bad value ${withval} for --with-crypto-library]) ;; esac ], @@ -66,6 +66,10 @@ case "${with_crypto_library}" in ss_POLARSSL AC_DEFINE([USE_CRYPTO_POLARSSL], [1], [Use PolarSSL library]) ;; + mbedtls) + ss_MBEDTLS + AC_DEFINE([USE_CRYPTO_MBEDTLS], [1], [Use mbed TLS library]) + ;; esac dnl Checks for Apple CommonCrypto API diff --git a/libcork/Makefile.in b/libcork/Makefile.in index 596876ad..92244d3e 100644 --- a/libcork/Makefile.in +++ b/libcork/Makefile.in @@ -77,8 +77,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/libev/Makefile.in b/libev/Makefile.in index c30edb91..4f0e2995 100644 --- a/libev/Makefile.in +++ b/libev/Makefile.in @@ -61,8 +61,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/libipset/Makefile.in b/libipset/Makefile.in index 4fc2709a..e21e69be 100644 --- a/libipset/Makefile.in +++ b/libipset/Makefile.in @@ -77,8 +77,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/libudns/Makefile.in b/libudns/Makefile.in index da14515d..4db660ff 100644 --- a/libudns/Makefile.in +++ b/libudns/Makefile.in @@ -77,8 +77,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/m4/mbedtls.m4 b/m4/mbedtls.m4 new file mode 100644 index 00000000..8a8c8b52 --- /dev/null +++ b/m4/mbedtls.m4 @@ -0,0 +1,45 @@ +dnl Check to find the mbed TLS headers/libraries + +AC_DEFUN([ss_MBEDTLS], +[ + + AC_ARG_WITH(mbedtls, + AS_HELP_STRING([--with-mbedtls=DIR], [mbed TLS base directory, or:]), + [mbedtls="$withval" + CFLAGS="$CFLAGS -I$withval/include" + LDFLAGS="$LDFLAGS -L$withval/lib"] + ) + + AC_ARG_WITH(mbedtls-include, + AS_HELP_STRING([--with-mbedtls-include=DIR], [mbed TLS headers directory (without trailing /mbedtls)]), + [mbedtls_include="$withval" + CFLAGS="$CFLAGS -I$withval"] + ) + + AC_ARG_WITH(mbedtls-lib, + AS_HELP_STRING([--with-mbedtls-lib=DIR], [mbed TLS library directory]), + [mbedtls_lib="$withval" + LDFLAGS="$LDFLAGS -L$withval"] + ) + + AC_CHECK_LIB(mbedcrypto, mbedtls_cipher_setup, + [LIBS="-lmbedcrypto $LIBS"], + [AC_MSG_ERROR([mbed TLS libraries not found.])] + ) + + AC_MSG_CHECKING([whether mbedtls support Cipher Feedback mode or not]) + AC_COMPILE_IFELSE( + [AC_LANG_PROGRAM( + [[ +#include + ]], + [[ +#ifndef MBEDTLS_CIPHER_MODE_CFB +#error Cipher Feedback mode a.k.a CFB not supported by your mbed TLS. +#endif + ]] + )], + [AC_MSG_RESULT([ok])], + [AC_MSG_ERROR([MBEDTLS_CIPHER_MODE_CFB required])] + ) +]) diff --git a/openwrt/Makefile b/openwrt/Makefile index 963d07bc..55d1cc41 100644 --- a/openwrt/Makefile +++ b/openwrt/Makefile @@ -38,11 +38,19 @@ define Package/shadowsocks-libev-polarssl DEPENDS:=+libpolarssl +libpthread endef +define Package/shadowsocks-libev-mbedtls + $(call Package/shadowsocks-libev/Default) + TITLE+= (mbedTLS) + VARIANT:=mbedtls + DEPENDS:=+libmbedtls +libpthread +endef + define Package/shadowsocks-libev/description Shadowsocks-libev is a lightweight secured socks5 proxy for embedded devices and low end boxes. endef Package/shadowsocks-libev-polarssl/description=$(Package/shadowsocks-libev/description) +Package/shadowsocks-libev-mbedtls/description=$(Package/shadowsocks-libev/description) define Package/shadowsocks-libev/conffiles /etc/shadowsocks.json @@ -52,6 +60,10 @@ ifeq ($(BUILD_VARIANT),polarssl) CONFIGURE_ARGS += --with-crypto-library=polarssl endif +ifeq ($(BUILD_VARIANT),mbedtls) + CONFIGURE_ARGS += --with-crypto-library=mbedtls +endif + define Package/shadowsocks-libev/install $(INSTALL_DIR) $(1)/etc/init.d $(INSTALL_CONF) ./files/shadowsocks.json $(1)/etc @@ -61,6 +73,8 @@ define Package/shadowsocks-libev/install endef Package/shadowsocks-libev-polarssl/install=$(Package/shadowsocks-libev/install) +Package/shadowsocks-libev-mbedtls/install=$(Package/shadowsocks-libev/install) $(eval $(call BuildPackage,shadowsocks-libev)) $(eval $(call BuildPackage,shadowsocks-libev-polarssl)) +$(eval $(call BuildPackage,shadowsocks-libev-mbedtls)) diff --git a/src/Makefile.in b/src/Makefile.in index 545e103a..9f7561c2 100644 --- a/src/Makefile.in +++ b/src/Makefile.in @@ -68,8 +68,8 @@ am__aclocal_m4_deps = $(top_srcdir)/m4/acx_pthread.m4 \ $(top_srcdir)/m4/libtool.m4 $(top_srcdir)/m4/ltoptions.m4 \ $(top_srcdir)/m4/ltsugar.m4 $(top_srcdir)/m4/ltversion.m4 \ $(top_srcdir)/m4/lt~obsolete.m4 $(top_srcdir)/m4/openssl.m4 \ - $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/libev/libev.m4 \ - $(top_srcdir)/configure.ac + $(top_srcdir)/m4/polarssl.m4 $(top_srcdir)/m4/mbedtls.m4 \ + $(top_srcdir)/libev/libev.m4 $(top_srcdir)/configure.ac am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ $(ACLOCAL_M4) mkinstalldirs = $(install_sh) -d diff --git a/src/encrypt.c b/src/encrypt.c index b90a1550..348f94f3 100644 --- a/src/encrypt.c +++ b/src/encrypt.c @@ -47,6 +47,22 @@ #include #endif +#elif defined(USE_CRYPTO_MBEDTLS) + +#include +#include +#include +#include +#define CIPHER_UNSUPPORTED "unsupported" + +#include +#ifdef _WIN32 +#include +#include +#else +#include +#endif + #endif #include @@ -119,6 +135,30 @@ static const char * supported_ciphers_polarssl[CIPHER_NUM] = }; #endif +#ifdef USE_CRYPTO_MBEDTLS +// FIXME: check it +static const char * supported_ciphers_mbedtls[CIPHER_NUM] = +{ + "table", + "ARC4-128", + "ARC4-128", + "AES-128-CFB128", + "AES-192-CFB128", + "AES-256-CFB128", + "BLOWFISH-CFB64", + "CAMELLIA-128-CFB128", + "CAMELLIA-192-CFB128", + "CAMELLIA-256-CFB128", + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + CIPHER_UNSUPPORTED, + "salsa20", + "chacha20" +}; +#endif + #ifdef USE_CRYPTO_APPLECC static const CCAlgorithm supported_ciphers_applecc[CIPHER_NUM] = { @@ -261,6 +301,13 @@ unsigned char *enc_md5(const unsigned char *d, size_t n, unsigned char *md) } md5(d, n, md); return md; +#elif defined(USE_CRYPTO_MBEDTLS) + static unsigned char m[16]; + if (md == NULL) { + md = m; + } + mbedtls_md5(d, n, md); + return md; #endif } @@ -295,7 +342,8 @@ int cipher_iv_size(const cipher_kt_t *cipher) { #if defined(USE_CRYPTO_OPENSSL) return EVP_CIPHER_iv_length(cipher); -#elif defined(USE_CRYPTO_POLARSSL) +#elif defined(USE_CRYPTO_POLARSSL) || defined(USE_CRYPTO_MBEDTLS) + //FIXME: check data structure of cipher if (cipher == NULL) { return 0; } @@ -317,6 +365,21 @@ int cipher_key_size(const cipher_kt_t *cipher) return 128 / 8; } return cipher->key_length / 8; +#elif defined(USE_CRYPTO_MBEDTLS) + // FIXME: ditto, cipher data structure + /* + * Semi-API changes (technically public, morally private) + * Renamed a few headers to include _internal in the name. Those headers are + not supposed to be included by users. + * Changed md_info_t into an opaque structure (use md_get_xxx() accessors). + * Changed pk_info_t into an opaque structure. + * Changed cipher_base_t into an opaque structure. + */ + if (cipher == NULL) { + return 0; + } + /* From Version 1.2.7 released 2013-04-13 Default Blowfish keysize is now 128-bits */ + return cipher->key_bitlen / 8; #endif } @@ -416,6 +479,123 @@ int bytes_to_key(const cipher_kt_t *cipher, const digest_type_t *md, md_free_ctx(&c); memset(md_buf, 0, MAX_MD_SIZE); return rv; +#elif defined(USE_CRYPTO_MBEDTLS) +/* + * + * Generic message digest context. + +typedef struct { + Information about the associated message digest + const mbedtls_md_info_t *md_info; + + Digest-specific context + void *md_ctx; + + HMAC part of the context + void *hmac_ctx; +} mbedtls_md_context_t; // mbedtls 2.0.0 + +typedef struct { + Information about the associated message digest + const md_info_t *md_info; + + Digest-specific context + void *md_ctx; +} md_context_t; //polarssl 1.3 + + */ + // NOTE: different struct body, initialize new param hmac 0 to disable HMAC + mbedtls_md_context_t c; + unsigned char md_buf[MAX_MD_SIZE]; + int niv; + int nkey; + int addmd; + unsigned int mds; + unsigned int i; + int rv; + + nkey = cipher_key_size(cipher); + niv = cipher_iv_size(cipher); + rv = nkey; + if (pass == NULL) { + return nkey; + } + + memset(&c, 0, sizeof(mbedtls_md_context_t)); + //FIXME: md_init_ctx superseded by mbedtls_md_setup() in 2.0.0 + // new param hmac 0 to save some meory(maybe a typo? memory?) is HMAC will not be use, + // non-zero is HMAC is going to be used with this context. + if (mbedtls_md_setup(&c, md, 0)) { + return 0; + } + addmd = 0; + mds = mbedtls_md_get_size(md); + for (;; ) { + int error; + do { + error = 1; + if (mbedtls_md_starts(&c)) { + break; + } + if (addmd) { + if (mbedtls_md_update(&c, &(md_buf[0]), mds)) { + break; + } + } else { + addmd = 1; + } + if (mbedtls_md_update(&c, pass, datal)) { + break; + } + if (mbedtls_md_finish(&c, &(md_buf[0]))) { + break; + } + error = 0; + } while (0); + if (error) { + mbedtls_md_free(&c); //md_free_ctx deprecated, Use mbedtls_md_free() instead + memset(md_buf, 0, MAX_MD_SIZE); + return 0; + } + + i = 0; + if (nkey) { + for (;; ) { + if (nkey == 0) { + break; + } + if (i == mds) { + break; + } + if (key != NULL) { + *(key++) = md_buf[i]; + } + nkey--; + i++; + } + } + if (niv && (i != mds)) { + for (;; ) { + if (niv == 0) { + break; + } + if (i == mds) { + break; + } + if (iv != NULL) { + *(iv++) = md_buf[i]; + } + niv--; + i++; + } + } + if ((nkey == 0) && (niv == 0)) { + break; + } + } + mbedtls_md_free(&c); //NOTE: md_free_ctx deprecated, Use mbedtls_md_free() instead + memset(md_buf, 0, MAX_MD_SIZE); + return rv; #endif } @@ -482,6 +662,66 @@ int rand_bytes(uint8_t *output, int len) len -= blen; } return 1; +#elif defined(USE_CRYPTO_MBEDTLS) + static mbedtls_entropy_context ec = {}; + // FIXME: ctr_drbg_context changed, [if defined(MBEDTLS_THREADING_C) mbedtls_threading_mutex_t mutex;] + static mbedtls_ctr_drbg_context cd_ctx = {}; + static unsigned char rand_initialised = 0; + const size_t blen = min(len, MBEDTLS_CTR_DRBG_MAX_REQUEST); + + if (!rand_initialised) { +#ifdef _WIN32 + HCRYPTPROV hProvider; + union { + unsigned __int64 seed; + BYTE buffer[8]; + } rand_buffer; + + hProvider = 0; + if (CryptAcquireContext(&hProvider, 0, 0, PROV_RSA_FULL, \ + CRYPT_VERIFYCONTEXT | CRYPT_SILENT)) { + CryptGenRandom(hProvider, 8, rand_buffer.buffer); + CryptReleaseContext(hProvider, 0); + } else { + rand_buffer.seed = (unsigned __int64)clock(); + } +#else + FILE *urand; + union { + uint64_t seed; + uint8_t buffer[8]; + } rand_buffer; + + urand = fopen("/dev/urandom", "r"); + if (urand) { + int read = fread(&rand_buffer.seed, sizeof(rand_buffer.seed), 1, + urand); + fclose(urand); + if (read <= 0) { + rand_buffer.seed = (uint64_t)clock(); + } + } else { + rand_buffer.seed = (uint64_t)clock(); + } +#endif + mbedtls_entropy_init(&ec); + // FIXME: ctr_drbg_init changed, seems we should initialize it before calling mbedtls_ctr_drbg_seed() + mbedtls_ctr_drbg_init(&cd_ctx); + if (mbedtls_ctr_drbg_seed(&cd_ctx, mbedtls_entropy_func, &ec, + (const unsigned char *)rand_buffer.buffer, 8) != 0) { + mbedtls_entropy_free(&ec); + FATAL("mbed TLS: Failed to initialize random generator"); + } + rand_initialised = 1; + } + while (len > 0) { + if (mbedtls_ctr_drbg_random(&cd_ctx, output, blen) != 0) { + return 0; + } + output += blen; + len -= blen; + } + return 1; #endif } @@ -511,6 +751,14 @@ const cipher_kt_t *get_cipher_type(int method) return NULL; } return cipher_info_from_string(polarname); +#elif defined(USE_CRYPTO_MBEDTLS) + const char *mbedtlsname = supported_ciphers_mbedtls[method]; + if (strcmp(mbedtlsname, CIPHER_UNSUPPORTED) == 0) { + LOGE("Cipher %s currently is not supported by mbed TLS library", + ciphername); + return NULL; + } + return mbedtls_cipher_info_from_string(mbedtlsname); #endif } @@ -525,6 +773,8 @@ const digest_type_t *get_digest_type(const char *digest) return EVP_get_digestbyname(digest); #elif defined(USE_CRYPTO_POLARSSL) return md_info_from_string(digest); +#elif defined(USE_CRYPTO_MBEDTLS) + return mbedtls_md_info_from_string(digest); #endif } @@ -588,6 +838,19 @@ void cipher_context_init(cipher_ctx_t *ctx, int method, int enc) if (cipher_init_ctx(evp, cipher) != 0) { FATAL("Cannot initialize PolarSSL cipher context"); } +#elif defined(USE_CRYPTO_MBEDTLS) +//FIXME: mbedtls_cipher_setup future change +//NOTE: Currently also clears structure. In future versions you will be required to call +// mbedtls_cipher_init() on the structure first. +// void mbedtls_cipher_init( mbedtls_cipher_context_t *ctx ); + if (cipher == NULL) { + LOGE("Cipher %s not found in mbed TLS library", ciphername); + FATAL("Cannot initialize mbed TLS cipher"); + } + mbedtls_cipher_init(evp); + if (mbedtls_cipher_setup(evp, cipher) != 0) { + FATAL("Cannot initialize mbed TLS cipher context"); + } #endif } @@ -664,6 +927,7 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, FATAL("Cannot set key and IV"); } #elif defined(USE_CRYPTO_POLARSSL) +//FIXME: PolarSSL 1.3.11: cipher_free_ctx deprecated, Use cipher_free() instead. if (cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { cipher_free_ctx(evp); FATAL("Cannot set PolarSSL cipher key"); @@ -683,6 +947,21 @@ void cipher_context_set_iv(cipher_ctx_t *ctx, uint8_t *iv, size_t iv_len, FATAL("Cannot set PolarSSL cipher IV"); } #endif +#elif defined(USE_CRYPTO_MBEDTLS) +//FIXME: cipher_free_ctx deprecated, Use cipher_free() instead in PolarSSL 1.3.11 + if (mbedtls_cipher_setkey(evp, true_key, enc_key_len * 8, enc) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot set mbed TLS cipher key"); + } + + if (mbedtls_cipher_set_iv(evp, iv, iv_len) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot set mbed TLS cipher IV"); + } + if (mbedtls_cipher_reset(evp) != 0) { + mbedtls_cipher_free(evp); + FATAL("Cannot finalize mbed TLS cipher context"); + } #endif #ifdef DEBUG @@ -711,7 +990,11 @@ void cipher_context_release(cipher_ctx_t *ctx) #if defined(USE_CRYPTO_OPENSSL) EVP_CIPHER_CTX_cleanup(evp); #elif defined(USE_CRYPTO_POLARSSL) +//NOTE: cipher_free_ctx deprecated in PolarSSL 1.3.11 cipher_free_ctx(evp); +#elif defined(USE_CRYPTO_MBEDTLS) +//NOTE: cipher_free_ctx deprecated + mbedtls_cipher_free(evp); #endif } @@ -734,6 +1017,9 @@ static int cipher_context_update(cipher_ctx_t *ctx, uint8_t *output, int *olen, #elif defined(USE_CRYPTO_POLARSSL) return !cipher_update(evp, (const uint8_t *)input, (size_t)ilen, (uint8_t *)output, (size_t *)olen); +#elif defined(USE_CRYPTO_MBEDTLS) + return !mbedtls_cipher_update(evp, (const uint8_t *)input, (size_t)ilen, + (uint8_t *)output, (size_t *)olen); #endif } @@ -1073,6 +1359,12 @@ void enc_key_init(int method, const char *pass) cipher->base = NULL; cipher->key_length = supported_ciphers_key_size[method] * 8; cipher->iv_size = supported_ciphers_iv_size[method]; +#endif +#if defined(USE_CRYPTO_MBEDTLS) +//FIXME: key_length changed to key_bitlen in mbed TLS 2.0.0 + cipher->base = NULL; + cipher->key_bitlen = supported_ciphers_key_size[method] * 8; + cipher->iv_size = supported_ciphers_iv_size[method]; #endif } else { cipher = (cipher_kt_t *)get_cipher_type(method); @@ -1088,6 +1380,16 @@ void enc_key_init(int method, const char *pass) cipher = (cipher_kt_t *)&cipher_info; break; } +#endif +#if defined(USE_CRYPTO_MBEDTLS) && defined(USE_CRYPTO_APPLECC) +//FIXME: key_length changed to key_bitlen in mbed TLS 2.0.0 + if (supported_ciphers_applecc[method] != kCCAlgorithmInvalid) { + cipher_info.base = NULL; + cipher_info.key_bitlen = supported_ciphers_key_size[method] * 8; + cipher_info.iv_size = supported_ciphers_iv_size[method]; + cipher = (cipher_kt_t *)&cipher_info; + break; + } #endif LOGE("Cipher %s not found in crypto library", supported_ciphers[method]); diff --git a/src/encrypt.h b/src/encrypt.h index 5c897d34..df20c3a5 100644 --- a/src/encrypt.h +++ b/src/encrypt.h @@ -63,6 +63,22 @@ typedef md_info_t digest_type_t; #define MAX_IV_LENGTH POLARSSL_MAX_IV_LENGTH #define MAX_MD_SIZE POLARSSL_MD_MAX_SIZE +#elif defined(USE_CRYPTO_MBEDTLS) + +#include +#include +typedef mbedtls_cipher_info_t cipher_kt_t; +typedef mbedtls_cipher_context_t cipher_evp_t; +typedef mbedtls_md_info_t digest_type_t; +#define MAX_KEY_LENGTH 64 +#define MAX_IV_LENGTH MBEDTLS_MAX_IV_LENGTH +#define MAX_MD_SIZE MBEDTLS_MD_MAX_SIZE + +/* we must have MBEDTLS_CIPHER_MODE_CFB defined */ +#if !defined(MBEDTLS_CIPHER_MODE_CFB) +#error Cipher Feedback mode a.k.a CFB not supported by your mbed TLS. +#endif + #endif #ifdef USE_CRYPTO_APPLECC