source: trunk/libtransmission/crypto-utils-polarssl.c

Last change on this file was 14444, checked in by mikedld, 6 years ago

Further adjustments to support PolarSSL 1.2

  • Property svn:keywords set to Date Rev Author Id
File size: 6.4 KB
Line 
1/*
2 * This file Copyright (C) 2014-2015 Mnemosyne LLC
3 *
4 * It may be used under the GNU GPL versions 2 or 3
5 * or any future license endorsed by Mnemosyne LLC.
6 *
7 * $Id: crypto-utils-polarssl.c 14444 2015-01-07 14:05:58Z mikedld $
8 */
9
10#include <assert.h>
11
12#include <polarssl/arc4.h>
13#include <polarssl/base64.h>
14#include <polarssl/ctr_drbg.h>
15#include <polarssl/dhm.h>
16#include <polarssl/error.h>
17#include <polarssl/sha1.h>
18#include <polarssl/version.h>
19
20#include "transmission.h"
21#include "crypto-utils.h"
22#include "log.h"
23#include "platform.h"
24#include "utils.h"
25
26#define TR_CRYPTO_DH_SECRET_FALLBACK
27#include "crypto-utils-fallback.c"
28
29/***
30****
31***/
32
33#define MY_NAME "tr_crypto_utils"
34
35static void
36log_polarssl_error (int          error_code,
37                    const char * file,
38                    int          line)
39{
40  if (tr_logLevelIsActive (TR_LOG_ERROR))
41    {
42      char error_message[256];
43
44#if POLARSSL_VERSION_NUMBER >= 0x01030000
45      polarssl_strerror (error_code, error_message, sizeof (error_message));
46#else
47      error_strerror (error_code, error_message, sizeof (error_message));
48#endif
49
50      tr_logAddMessage (file, line, TR_LOG_ERROR, MY_NAME, "PolarSSL error: %s", error_message);
51    }
52}
53
54#define log_error(error_code) log_polarssl_error(error_code, __FILE__, __LINE__)
55
56static bool
57check_polarssl_result (int          result,
58                       int          expected_result,
59                       const char * file,
60                       int          line)
61{
62  const bool ret = result == expected_result;
63  if (!ret)
64    log_polarssl_error (result, file, line);
65  return ret;
66}
67
68#define check_result(result) check_polarssl_result ((result), 0, __FILE__, __LINE__)
69#define check_result_eq(result, x_result) check_polarssl_result ((result), (x_result), __FILE__, __LINE__)
70
71/***
72****
73***/
74
75static int
76my_rand (void * context UNUSED, unsigned char * buffer, size_t buffer_size)
77{
78  size_t i;
79
80  for (i = 0; i < buffer_size; ++i)
81    buffer[i] = tr_rand_int_weak (256);
82
83  return 0;
84}
85
86static ctr_drbg_context *
87get_rng (void)
88{
89  static ctr_drbg_context rng;
90  static bool rng_initialized = false;
91
92  if (!rng_initialized)
93    {
94      if (!check_result (ctr_drbg_init (&rng, &my_rand, NULL, NULL, 0)))
95        return NULL;
96      rng_initialized = true;
97    }
98
99  return &rng;
100}
101
102static tr_lock *
103get_rng_lock (void)
104{
105  static tr_lock * lock = NULL;
106
107  if (lock == NULL)
108    lock = tr_lockNew ();
109
110  return lock;
111}
112
113/***
114****
115***/
116
117tr_sha1_ctx_t
118tr_sha1_init (void)
119{
120  sha1_context * handle = tr_new0 (sha1_context, 1);
121
122#if POLARSSL_VERSION_NUMBER >= 0x01030800
123  sha1_init (handle);
124#endif
125
126  sha1_starts (handle);
127  return handle;
128}
129
130bool
131tr_sha1_update (tr_sha1_ctx_t   handle,
132                const void    * data,
133                size_t          data_length)
134{
135  assert (handle != NULL);
136
137  if (data_length == 0)
138    return true;
139
140  assert (data != NULL);
141
142  sha1_update (handle, data, data_length);
143  return true;
144}
145
146bool
147tr_sha1_final (tr_sha1_ctx_t   handle,
148               uint8_t       * hash)
149{
150  if (hash != NULL)
151    {
152      assert (handle != NULL);
153
154      sha1_finish (handle, hash);
155    }
156
157#if POLARSSL_VERSION_NUMBER >= 0x01030800
158  sha1_free (handle);
159#endif
160
161  tr_free (handle);
162  return true;
163}
164
165/***
166****
167***/
168
169tr_rc4_ctx_t
170tr_rc4_new (void)
171{
172  arc4_context * handle = tr_new0 (arc4_context, 1);
173
174#if POLARSSL_VERSION_NUMBER >= 0x01030800
175  arc4_init (handle);
176#endif
177
178  return handle;
179}
180
181void
182tr_rc4_free (tr_rc4_ctx_t handle)
183{
184#if POLARSSL_VERSION_NUMBER >= 0x01030800
185  arc4_free (handle);
186#endif
187
188  tr_free (handle);
189}
190
191void
192tr_rc4_set_key (tr_rc4_ctx_t    handle,
193                const uint8_t * key,
194                size_t          key_length)
195{
196  assert (handle != NULL);
197  assert (key != NULL);
198
199  arc4_setup (handle, key, key_length);
200}
201
202void
203tr_rc4_process (tr_rc4_ctx_t   handle,
204                const void   * input,
205                void         * output,
206                size_t         length)
207{
208  assert (handle != NULL);
209
210  if (length == 0)
211    return;
212
213  assert (input != NULL);
214  assert (output != NULL);
215
216  arc4_crypt (handle, length, input, output);
217}
218
219/***
220****
221***/
222
223tr_dh_ctx_t
224tr_dh_new (const uint8_t * prime_num,
225           size_t          prime_num_length,
226           const uint8_t * generator_num,
227           size_t          generator_num_length)
228{
229  dhm_context * handle = tr_new0 (dhm_context, 1);
230
231  assert (prime_num != NULL);
232  assert (generator_num != NULL);
233
234#if POLARSSL_VERSION_NUMBER >= 0x01030800
235  dhm_init (handle);
236#endif
237
238  if (!check_result (mpi_read_binary (&handle->P, prime_num, prime_num_length)) ||
239      !check_result (mpi_read_binary (&handle->G, generator_num, generator_num_length)))
240    {
241      dhm_free (handle);
242      return NULL;
243    }
244
245  handle->len = prime_num_length;
246
247  return handle;
248}
249
250void
251tr_dh_free (tr_dh_ctx_t handle)
252{
253  if (handle == NULL)
254    return;
255
256  dhm_free (handle);
257}
258
259bool
260tr_dh_make_key (tr_dh_ctx_t   raw_handle,
261                size_t        private_key_length,
262                uint8_t     * public_key,
263                size_t      * public_key_length)
264{
265  dhm_context * handle = raw_handle;
266
267  assert (handle != NULL);
268  assert (public_key != NULL);
269
270  if (public_key_length != NULL)
271    *public_key_length = handle->len;
272
273  return check_result (dhm_make_public (handle, private_key_length, public_key,
274                                        handle->len, my_rand, NULL));
275}
276
277tr_dh_secret_t
278tr_dh_agree (tr_dh_ctx_t     raw_handle,
279             const uint8_t * other_public_key,
280             size_t          other_public_key_length)
281{
282  dhm_context * handle = raw_handle;
283  struct tr_dh_secret * ret;
284  size_t secret_key_length;
285
286  assert (handle != NULL);
287  assert (other_public_key != NULL);
288
289  if (!check_result (dhm_read_public (handle, other_public_key,
290                                      other_public_key_length)))
291    return NULL;
292
293  ret = tr_dh_secret_new (handle->len);
294
295  secret_key_length = handle->len;
296
297#if POLARSSL_VERSION_NUMBER >= 0x01030000
298  if (!check_result (dhm_calc_secret (handle, ret->key,
299                                      &secret_key_length, my_rand, NULL)))
300#else
301  if (!check_result (dhm_calc_secret (handle, ret->key, &secret_key_length)))
302#endif
303    {
304      tr_dh_secret_free (ret);
305      return NULL;
306    }
307
308  tr_dh_secret_align (ret, secret_key_length);
309
310  return ret;
311}
312
313/***
314****
315***/
316
317bool
318tr_rand_buffer (void   * buffer,
319                size_t   length)
320{
321  bool ret;
322  tr_lock * rng_lock = get_rng_lock ();
323
324  assert (buffer != NULL);
325
326  tr_lockLock (rng_lock);
327  ret = check_result (ctr_drbg_random (get_rng (), buffer, length));
328  tr_lockUnlock (rng_lock);
329
330  return ret;
331}
Note: See TracBrowser for help on using the repository browser.