logo

oasis

Own branch of Oasis Linux (upstream: <https://git.sr.ht/~mcf/oasis/>) git clone https://anongit.hacktivis.me/git/oasis.git

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