transmission: Use BearSSL for crypto

This commit is contained in:
Michael Forney
2019-11-17 01:29:28 -08:00
parent 34b8700ea7
commit e953697621
3 changed files with 343 additions and 6 deletions
+4 -5
View File
@@ -32,9 +32,9 @@ end)
cflags{
'-D __TRANSMISSION__',
'-I $builddir/pkg/bearssl/include',
'-I $builddir/pkg/curl/include',
'-I $builddir/pkg/libevent/include',
'-I $builddir/pkg/libressl/include',
'-I $builddir/pkg/zlib/include',
'-I $dir',
'-I $srcdir',
@@ -48,10 +48,9 @@ cflags{
}
pkg.deps = {
'pkg/bearssl/headers',
'pkg/curl/headers',
'pkg/libevent/headers',
'pkg/libressl/headers',
'pkg/libressl/headers',
'pkg/libutp/fetch',
'pkg/openbsd/fetch',
'pkg/zlib/headers',
@@ -121,13 +120,13 @@ lib('libtransmission.a', [[
watchdir-inotify.c
file-posix.c
crypto-utils-openssl.c
crypto-utils-bearssl.c
)
libb64.a libdht.a libminiupnp.a libnatpmp.a
$builddir/pkg/(
bearssl/libbearssl.a
curl/libcurl.a.d
libevent/libevent.a
libressl/libcrypto.a.d
libutp/libutp.a
zlib/libz.a
)
@@ -0,0 +1,338 @@
From c8d489d361634413a518d614f02f3ecdaad3d4ec Mon Sep 17 00:00:00 2001
From: Michael Forney <mforney@mforney.org>
Date: Sun, 17 Nov 2019 01:27:04 -0800
Subject: [PATCH] Use BearSSL for SHA1 and DH, add fallback RC4
---
libtransmission/crypto-utils-bearssl.c | 229 ++++++++++++++++++++++++
libtransmission/crypto-utils-fallback.c | 81 +++++++++
2 files changed, 310 insertions(+)
create mode 100644 libtransmission/crypto-utils-bearssl.c
diff --git a/libtransmission/crypto-utils-bearssl.c b/libtransmission/crypto-utils-bearssl.c
new file mode 100644
index 000000000..23bdf5c45
--- /dev/null
+++ b/libtransmission/crypto-utils-bearssl.c
@@ -0,0 +1,229 @@
+#include <assert.h>
+#include <stdlib.h>
+
+#include <bearssl.h>
+
+#include "crypto-utils.h"
+
+#define TR_CRYPTO_DH_SECRET_FALLBACK
+#define TR_CRYPTO_RC4_FALLBACK
+#include "crypto-utils-fallback.c"
+
+/***
+****
+***/
+
+#define MY_NAME "tr_crypto_utils"
+
+tr_sha1_ctx_t
+tr_sha1_init (void)
+{
+ br_sha1_context * ctx;
+
+ ctx = tr_malloc (sizeof (*ctx));
+ if (!ctx)
+ return NULL;
+
+ br_sha1_init (ctx);
+
+ return ctx;
+}
+
+bool
+tr_sha1_update (tr_sha1_ctx_t handle,
+ const void * data,
+ size_t data_length)
+{
+ assert (handle != NULL);
+
+ if (data_length == 0)
+ return true;
+
+ assert (data != NULL);
+
+ br_sha1_update (handle, data, data_length);
+
+ return true;
+}
+
+bool
+tr_sha1_final (tr_sha1_ctx_t handle,
+ uint8_t * hash)
+{
+ if (hash != NULL)
+ {
+ assert (handle != NULL);
+ br_sha1_out (handle, hash);
+ }
+
+ tr_free (handle);
+ return true;
+}
+
+/***
+****
+***/
+
+typedef struct {
+ const uint8_t * prime_num;
+ size_t prime_num_length;
+ const uint8_t * generator_num;
+ size_t generator_num_length;
+ uint8_t * private_key;
+ size_t private_key_length;
+} DH;
+
+tr_dh_ctx_t
+tr_dh_new (const uint8_t * prime_num,
+ size_t prime_num_length,
+ const uint8_t * generator_num,
+ size_t generator_num_length)
+{
+ DH * handle;
+
+ assert (prime_num != NULL);
+ assert (generator_num != NULL);
+ assert (generator_num_length < prime_num_length);
+
+ if (generator_num_length > prime_num_length)
+ return NULL;
+
+ handle = tr_malloc (sizeof(*handle));
+ if (handle == NULL)
+ return NULL;
+
+ handle->prime_num = prime_num;
+ handle->prime_num_length = prime_num_length;
+ handle->generator_num = generator_num;
+ handle->generator_num_length = generator_num_length;
+ handle->private_key = NULL;
+
+ return handle;
+}
+
+void
+tr_dh_free (tr_dh_ctx_t raw_handle)
+{
+ DH * handle = raw_handle;
+
+ if (handle == NULL)
+ return;
+
+ tr_free (handle->private_key);
+ tr_free (handle);
+}
+
+bool
+tr_dh_make_key (tr_dh_ctx_t raw_handle,
+ size_t private_key_length,
+ uint8_t * public_key,
+ size_t * public_key_length)
+{
+ DH * handle = raw_handle;
+ br_rsa_public modexp;
+ br_rsa_public_key key;
+ uint8_t * x;
+ size_t xlen;
+
+ assert (handle != NULL);
+ assert (public_key != NULL);
+
+ modexp = br_rsa_public_get_default ();
+
+ handle->private_key = tr_malloc (private_key_length);
+ handle->private_key_length = private_key_length;
+
+ if (!handle->private_key)
+ goto fail;
+
+ if (!tr_rand_buffer (handle->private_key, handle->private_key_length))
+ goto fail;
+
+ memset (public_key, 0, handle->prime_num_length - handle->generator_num_length);
+ memcpy (public_key + handle->prime_num_length - handle->generator_num_length, handle->generator_num, handle->generator_num_length);
+
+ key.n = (unsigned char *)handle->prime_num;
+ key.nlen = handle->prime_num_length;
+ key.e = handle->private_key;
+ key.elen = handle->private_key_length;
+
+ if (!modexp (public_key, handle->prime_num_length, &key))
+ goto fail;
+
+ *public_key_length = handle->prime_num_length;
+
+ return true;
+
+fail:
+ tr_free(handle->private_key);
+ handle->private_key = NULL;
+ return false;
+}
+
+tr_dh_secret_t
+tr_dh_agree (tr_dh_ctx_t raw_handle,
+ const uint8_t * other_public_key,
+ size_t other_public_key_length)
+{
+ DH * handle = raw_handle;
+ struct tr_dh_secret * ret;
+ br_rsa_public modexp;
+ br_rsa_public_key key;
+ uint8_t * x;
+ size_t xlen;
+
+ assert (handle != NULL);
+ assert (other_public_key != NULL);
+
+ if (other_public_key_length > handle->prime_num_length)
+ return NULL;
+
+ ret = tr_dh_secret_new(handle->prime_num_length);
+ if (!ret)
+ return NULL;
+
+ memset (ret->key, 0, ret->key_length - other_public_key_length);
+ memcpy (ret->key + ret->key_length - other_public_key_length, other_public_key, other_public_key_length);
+
+ modexp = br_rsa_public_get_default ();
+
+ key.n = (unsigned char *)handle->prime_num;
+ key.nlen = handle->prime_num_length;
+ key.e = handle->private_key;
+ key.elen = handle->private_key_length;
+
+ if (!modexp (ret->key, ret->key_length, &key))
+ {
+ tr_dh_secret_free (ret);
+ ret = NULL;
+ }
+
+ return ret;
+}
+
+/***
+****
+***/
+
+bool
+tr_rand_buffer (void * buffer,
+ size_t length)
+{
+ static br_hmac_drbg_context ctx;
+ static bool init;
+ br_prng_seeder seeder;
+
+ assert (buffer != NULL);
+
+ if (!init)
+ {
+ br_hmac_drbg_init (&ctx, &br_sha256_vtable, NULL, 0);
+ seeder = br_prng_seeder_system (NULL);
+ if (!seeder || !seeder(&ctx.vtable))
+ return false;
+ init = true;
+ }
+
+ br_hmac_drbg_generate (&ctx, buffer, length);
+ return true;
+}
diff --git a/libtransmission/crypto-utils-fallback.c b/libtransmission/crypto-utils-fallback.c
index 0ca1ad75e..9fdb044a9 100644
--- a/libtransmission/crypto-utils-fallback.c
+++ b/libtransmission/crypto-utils-fallback.c
@@ -75,3 +75,84 @@ tr_dh_secret_free (tr_dh_secret_t handle)
}
#endif /* TR_CRYPTO_DH_SECRET_FALLBACK */
+
+/***
+****
+***/
+
+#ifdef TR_CRYPTO_RC4_FALLBACK
+
+struct tr_rc4
+{
+ uint32_t i, j, S[256];
+};
+
+tr_rc4_ctx_t
+tr_rc4_new (void)
+{
+ return tr_malloc (sizeof (struct tr_rc4));
+}
+
+void
+tr_rc4_free (tr_rc4_ctx_t handle)
+{
+ tr_free (handle);
+}
+
+void
+tr_rc4_set_key (tr_rc4_ctx_t raw_handle,
+ const uint8_t * key,
+ size_t key_length)
+{
+ struct tr_rc4 * handle = raw_handle;
+ uint32_t tmp, * S;
+ size_t i, j;
+
+ assert (handle != NULL);
+ assert (key != NULL);
+
+ S = handle->S;
+ for (i = 0; i < 256; ++i)
+ S[i] = i;
+
+ j = 0;
+ for (i = 0; i < 256; ++i) {
+ j = (j + S[i] + key[i % key_length]) & 0xff;
+ tmp = S[i];
+ S[i] = S[j];
+ S[j] = tmp;
+ }
+ handle->i = 0;
+ handle->j = 0;
+}
+
+void
+tr_rc4_process (tr_rc4_ctx_t raw_handle,
+ const void * raw_input,
+ void * raw_output,
+ size_t length)
+{
+ struct tr_rc4 * handle = raw_handle;
+ const uint8_t * input = raw_input;
+ uint8_t * output = raw_output;
+ uint32_t * S, i, j, tmp;
+
+ assert (handle != NULL);
+ assert (handle != NULL);
+
+ i = handle->i;
+ j = handle->j;
+ S = handle->S;
+ while (length--) {
+ i = (i + 1) & 0xff;
+ j = (j + S[i]) & 0xff;
+ tmp = S[i];
+ S[i] = S[j];
+ S[j] = tmp;
+ *output++ = S[(S[i] + S[j]) & 0xff] ^ *input++;
+ }
+ handle->i = i;
+ handle->j = j;
+}
+
+#endif /* TR_CRYPTO_RC4_FALLBACK */
--
2.24.0
+1 -1
View File
@@ -1 +1 @@
2.94 r0
2.94 r1