0001-Use-BearSSL-for-SHA1-and-DH-add-fallback-RC4.patch (7595B)
1 From eb8e399417b22099b5a52e5fb468979e44486e73 Mon Sep 17 00:00:00 2001 2 From: Michael Forney <mforney@mforney.org> 3 Date: Sun, 17 Nov 2019 01:27:04 -0800 4 Subject: [PATCH] Use BearSSL for SHA1 and DH, add fallback RC4 5 6 --- 7 libtransmission/crypto-utils-bearssl.c | 234 ++++++++++++++++++++++++ 8 libtransmission/crypto-utils-fallback.c | 77 ++++++++ 9 2 files changed, 311 insertions(+) 10 create mode 100644 libtransmission/crypto-utils-bearssl.c 11 12 diff --git a/libtransmission/crypto-utils-bearssl.c b/libtransmission/crypto-utils-bearssl.c 13 new file mode 100644 14 index 000000000..5672a48df 15 --- /dev/null 16 +++ b/libtransmission/crypto-utils-bearssl.c 17 @@ -0,0 +1,234 @@ 18 +#include <assert.h> 19 +#include <stdlib.h> 20 + 21 +#include <bearssl.h> 22 + 23 +#include "crypto-utils.h" 24 + 25 +#define TR_CRYPTO_DH_SECRET_FALLBACK 26 +#define TR_CRYPTO_X509_FALLBACK 27 +#define TR_CRYPTO_RC4_FALLBACK 28 +#include "crypto-utils-fallback.c" 29 + 30 +/*** 31 +**** 32 +***/ 33 + 34 +#define MY_NAME "tr_crypto_utils" 35 + 36 +tr_sha1_ctx_t tr_sha1_init(void) 37 +{ 38 + br_sha1_context * ctx; 39 + 40 + ctx = tr_malloc(sizeof (*ctx)); 41 + if (!ctx) 42 + { 43 + return NULL; 44 + } 45 + 46 + br_sha1_init(ctx); 47 + 48 + return ctx; 49 +} 50 + 51 +bool tr_sha1_update(tr_sha1_ctx_t handle, void const* data, size_t data_length) 52 +{ 53 + TR_ASSERT(handle != NULL); 54 + 55 + if (data_length == 0) 56 + { 57 + return true; 58 + } 59 + 60 + TR_ASSERT(data != NULL); 61 + 62 + br_sha1_update(handle, data, data_length); 63 + 64 + return true; 65 +} 66 + 67 +bool tr_sha1_final(tr_sha1_ctx_t handle, uint8_t* hash) 68 +{ 69 + if (hash != NULL) 70 + { 71 + TR_ASSERT(handle != NULL); 72 + br_sha1_out(handle, hash); 73 + } 74 + 75 + tr_free(handle); 76 + return true; 77 +} 78 + 79 +/*** 80 +**** 81 +***/ 82 + 83 +typedef struct { 84 + uint8_t const* prime_num; 85 + size_t prime_num_length; 86 + uint8_t const* generator_num; 87 + size_t generator_num_length; 88 + uint8_t* private_key; 89 + size_t private_key_length; 90 +} DH; 91 + 92 +tr_dh_ctx_t tr_dh_new(uint8_t const* prime_num, size_t prime_num_length, uint8_t const* generator_num, 93 + size_t generator_num_length) 94 +{ 95 + DH* handle; 96 + 97 + TR_ASSERT(prime_num != NULL); 98 + TR_ASSERT(generator_num != NULL); 99 + TR_ASSERT(generator_num_length < prime_num_length); 100 + 101 + if (generator_num_length > prime_num_length) 102 + { 103 + return NULL; 104 + } 105 + 106 + handle = tr_malloc(sizeof(*handle)); 107 + if (handle == NULL) 108 + { 109 + return NULL; 110 + } 111 + 112 + handle->prime_num = prime_num; 113 + handle->prime_num_length = prime_num_length; 114 + handle->generator_num = generator_num; 115 + handle->generator_num_length = generator_num_length; 116 + handle->private_key = NULL; 117 + 118 + return handle; 119 +} 120 + 121 +void 122 +tr_dh_free (tr_dh_ctx_t raw_handle) 123 +{ 124 + DH* handle = raw_handle; 125 + 126 + if (handle == NULL) 127 + { 128 + return; 129 + } 130 + 131 + tr_free(handle->private_key); 132 + tr_free(handle); 133 +} 134 + 135 +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) 136 +{ 137 + TR_ASSERT(raw_handle != NULL); 138 + TR_ASSERT(public_key != NULL); 139 + 140 + DH* handle = raw_handle; 141 + br_rsa_public modexp; 142 + br_rsa_public_key key; 143 + uint8_t* x; 144 + size_t xlen; 145 + 146 + modexp = br_rsa_public_get_default(); 147 + 148 + handle->private_key = tr_malloc(private_key_length); 149 + handle->private_key_length = private_key_length; 150 + 151 + if (!handle->private_key) 152 + { 153 + goto fail; 154 + } 155 + 156 + if (!tr_rand_buffer(handle->private_key, handle->private_key_length)) 157 + { 158 + goto fail; 159 + } 160 + 161 + memset(public_key, 0, handle->prime_num_length - handle->generator_num_length); 162 + memcpy(public_key + handle->prime_num_length - handle->generator_num_length, handle->generator_num, handle->generator_num_length); 163 + 164 + key.n = (unsigned char*)handle->prime_num; 165 + key.nlen = handle->prime_num_length; 166 + key.e = handle->private_key; 167 + key.elen = handle->private_key_length; 168 + 169 + if (!modexp(public_key, handle->prime_num_length, &key)) 170 + { 171 + goto fail; 172 + } 173 + 174 + *public_key_length = handle->prime_num_length; 175 + 176 + return true; 177 + 178 +fail: 179 + tr_free(handle->private_key); 180 + handle->private_key = NULL; 181 + return false; 182 +} 183 + 184 +tr_dh_secret_t tr_dh_agree(tr_dh_ctx_t raw_handle, uint8_t const* other_public_key, size_t other_public_key_length) 185 +{ 186 + TR_ASSERT(raw_handle != NULL); 187 + TR_ASSERT(other_public_key != NULL); 188 + 189 + DH* handle = raw_handle; 190 + struct tr_dh_secret* ret; 191 + br_rsa_public modexp; 192 + br_rsa_public_key key; 193 + uint8_t* x; 194 + size_t xlen; 195 + 196 + if (other_public_key_length > handle->prime_num_length) 197 + { 198 + return NULL; 199 + } 200 + 201 + ret = tr_dh_secret_new(handle->prime_num_length); 202 + if (!ret) 203 + { 204 + return NULL; 205 + } 206 + 207 + memset(ret->key, 0, ret->key_length - other_public_key_length); 208 + memcpy(ret->key + ret->key_length - other_public_key_length, other_public_key, other_public_key_length); 209 + 210 + modexp = br_rsa_public_get_default(); 211 + 212 + key.n = (unsigned char*)handle->prime_num; 213 + key.nlen = handle->prime_num_length; 214 + key.e = handle->private_key; 215 + key.elen = handle->private_key_length; 216 + 217 + if (!modexp(ret->key, ret->key_length, &key)) 218 + { 219 + tr_dh_secret_free (ret); 220 + ret = NULL; 221 + } 222 + 223 + return ret; 224 +} 225 + 226 +/*** 227 +**** 228 +***/ 229 + 230 +bool tr_rand_buffer(void* buffer, size_t length) 231 +{ 232 + TR_ASSERT(buffer != NULL); 233 + 234 + static br_hmac_drbg_context ctx; 235 + static bool init; 236 + br_prng_seeder seeder; 237 + 238 + if (!init) 239 + { 240 + br_hmac_drbg_init(&ctx, &br_sha256_vtable, NULL, 0); 241 + seeder = br_prng_seeder_system(NULL); 242 + if (!seeder || !seeder(&ctx.vtable)) 243 + { 244 + return false; 245 + } 246 + init = true; 247 + } 248 + 249 + br_hmac_drbg_generate(&ctx, buffer, length); 250 + return true; 251 +} 252 diff --git a/libtransmission/crypto-utils-fallback.c b/libtransmission/crypto-utils-fallback.c 253 index c17b54e25..a521956a3 100644 254 --- a/libtransmission/crypto-utils-fallback.c 255 +++ b/libtransmission/crypto-utils-fallback.c 256 @@ -92,3 +92,80 @@ void tr_x509_cert_free(tr_x509_cert_t handle) 257 } 258 259 #endif /* TR_CRYPTO_X509_FALLBACK */ 260 + 261 +#ifdef TR_CRYPTO_RC4_FALLBACK 262 + 263 +struct tr_rc4 264 +{ 265 + uint32_t i, j, S[256]; 266 +}; 267 + 268 +tr_rc4_ctx_t 269 +tr_rc4_new (void) 270 +{ 271 + return tr_malloc (sizeof (struct tr_rc4)); 272 +} 273 + 274 +void 275 +tr_rc4_free (tr_rc4_ctx_t handle) 276 +{ 277 + tr_free (handle); 278 +} 279 + 280 +void 281 +tr_rc4_set_key (tr_rc4_ctx_t raw_handle, 282 + const uint8_t * key, 283 + size_t key_length) 284 +{ 285 + struct tr_rc4 * handle = raw_handle; 286 + uint32_t tmp, * S; 287 + size_t i, j; 288 + 289 + assert (handle != NULL); 290 + assert (key != NULL); 291 + 292 + S = handle->S; 293 + for (i = 0; i < 256; ++i) 294 + S[i] = i; 295 + 296 + j = 0; 297 + for (i = 0; i < 256; ++i) { 298 + j = (j + S[i] + key[i % key_length]) & 0xff; 299 + tmp = S[i]; 300 + S[i] = S[j]; 301 + S[j] = tmp; 302 + } 303 + handle->i = 0; 304 + handle->j = 0; 305 +} 306 + 307 +void 308 +tr_rc4_process (tr_rc4_ctx_t raw_handle, 309 + const void * raw_input, 310 + void * raw_output, 311 + size_t length) 312 +{ 313 + struct tr_rc4 * handle = raw_handle; 314 + const uint8_t * input = raw_input; 315 + uint8_t * output = raw_output; 316 + uint32_t * S, i, j, tmp; 317 + 318 + assert (handle != NULL); 319 + assert (handle != NULL); 320 + 321 + i = handle->i; 322 + j = handle->j; 323 + S = handle->S; 324 + while (length--) { 325 + i = (i + 1) & 0xff; 326 + j = (j + S[i]) & 0xff; 327 + tmp = S[i]; 328 + S[i] = S[j]; 329 + S[j] = tmp; 330 + *output++ = S[(S[i] + S[j]) & 0xff] ^ *input++; 331 + } 332 + handle->i = i; 333 + handle->j = j; 334 +} 335 + 336 +#endif /* TR_CRYPTO_RC4_FALLBACK */ 337 -- 338 2.26.2 339