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

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

Fix copyright years and SVN attributes on new files

  • Property svn:keywords set to Date Rev Author Id
File size: 6.3 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-cyassl.c 14442 2015-01-07 13:20:56Z mikedld $
8 */
9
10#include <assert.h>
11
12#include <cyassl/ctaocrypt/arc4.h>
13#include <cyassl/ctaocrypt/dh.h>
14#include <cyassl/ctaocrypt/error-crypt.h>
15#include <cyassl/ctaocrypt/random.h>
16#include <cyassl/ctaocrypt/sha.h>
17#include <cyassl/version.h>
18
19#include "transmission.h"
20#include "crypto-utils.h"
21#include "log.h"
22#include "platform.h"
23#include "utils.h"
24
25#define TR_CRYPTO_DH_SECRET_FALLBACK
26#include "crypto-utils-fallback.c"
27
28struct tr_dh_ctx
29{
30  DhKey     dh;
31  word32    key_length;
32  uint8_t * private_key;
33  word32    private_key_length;
34};
35
36/***
37****
38***/
39
40#define MY_NAME "tr_crypto_utils"
41
42static void
43log_cyassl_error (int          error_code,
44                  const char * file,
45                  int          line)
46{
47  if (tr_logLevelIsActive (TR_LOG_ERROR))
48    {
49#if LIBCYASSL_VERSION_HEX >= 0x03000002
50      const char * error_message = CTaoCryptGetErrorString (error_code);
51#else
52      char error_message[CYASSL_MAX_ERROR_SZ];
53      CTaoCryptErrorString (error_code, error_message);
54#endif
55
56      tr_logAddMessage (file, line, TR_LOG_ERROR, MY_NAME, "CyaSSL error: %s", error_message);
57    }
58}
59
60static bool
61check_cyassl_result (int          result,
62                     const char * file,
63                     int          line)
64{
65  const bool ret = result == 0;
66  if (!ret)
67    log_cyassl_error (result, file, line);
68  return ret;
69}
70
71#define check_result(result) check_cyassl_result ((result), __FILE__, __LINE__)
72
73/***
74****
75***/
76
77static RNG *
78get_rng (void)
79{
80  static RNG rng;
81  static bool rng_initialized = false;
82
83  if (!rng_initialized)
84    {
85      if (!check_result (InitRng (&rng)))
86        return NULL;
87      rng_initialized = true;
88    }
89
90  return &rng;
91}
92
93static tr_lock *
94get_rng_lock (void)
95{
96  static tr_lock * lock = NULL;
97
98  if (lock == NULL)
99    lock = tr_lockNew ();
100
101  return lock;
102}
103
104/***
105****
106***/
107
108tr_sha1_ctx_t
109tr_sha1_init (void)
110{
111  Sha * handle = tr_new (Sha, 1);
112
113  if (check_result (InitSha (handle)))
114    return handle;
115
116  tr_free (handle);
117  return NULL;
118}
119
120bool
121tr_sha1_update (tr_sha1_ctx_t   handle,
122                const void    * data,
123                size_t          data_length)
124{
125  assert (handle != NULL);
126
127  if (data_length == 0)
128    return true;
129
130  assert (data != NULL);
131
132  return check_result (ShaUpdate (handle, data, data_length));
133}
134
135bool
136tr_sha1_final (tr_sha1_ctx_t   handle,
137               uint8_t       * hash)
138{
139  bool ret = true;
140
141  if (hash != NULL)
142    {
143      assert (handle != NULL);
144
145      ret = check_result (ShaFinal (handle, hash));
146    }
147
148  tr_free (handle);
149  return ret;
150}
151
152/***
153****
154***/
155
156tr_rc4_ctx_t
157tr_rc4_new (void)
158{
159  return tr_new0 (Arc4, 1);
160}
161
162void
163tr_rc4_free (tr_rc4_ctx_t handle)
164{
165  tr_free (handle);
166}
167
168void
169tr_rc4_set_key (tr_rc4_ctx_t    handle,
170                const uint8_t * key,
171                size_t          key_length)
172{
173  assert (handle != NULL);
174  assert (key != NULL);
175
176  Arc4SetKey (handle, key, key_length);
177}
178
179void
180tr_rc4_process (tr_rc4_ctx_t   handle,
181                const void   * input,
182                void         * output,
183                size_t         length)
184{
185  assert (handle != NULL);
186
187  if (length == 0)
188    return;
189
190  assert (input != NULL);
191  assert (output != NULL);
192
193  Arc4Process (handle, output, input, length);
194}
195
196/***
197****
198***/
199
200tr_dh_ctx_t
201tr_dh_new (const uint8_t * prime_num,
202           size_t          prime_num_length,
203           const uint8_t * generator_num,
204           size_t          generator_num_length)
205{
206  struct tr_dh_ctx * handle = tr_new0 (struct tr_dh_ctx, 1);
207
208  assert (prime_num != NULL);
209  assert (generator_num != NULL);
210
211  InitDhKey (&handle->dh);
212  if (!check_result (DhSetKey (&handle->dh,
213                               prime_num, prime_num_length,
214                               generator_num, generator_num_length)))
215    {
216      tr_free (handle);
217      return NULL;
218    }
219
220  handle->key_length = prime_num_length;
221
222  return handle;
223}
224
225void
226tr_dh_free (tr_dh_ctx_t raw_handle)
227{
228  struct tr_dh_ctx * handle = raw_handle;
229
230  if (handle == NULL)
231    return;
232
233  FreeDhKey (&handle->dh);
234  tr_free (handle->private_key);
235  tr_free (handle);
236}
237
238bool
239tr_dh_make_key (tr_dh_ctx_t   raw_handle,
240                size_t        private_key_length UNUSED,
241                uint8_t     * public_key,
242                size_t      * public_key_length)
243{
244  struct tr_dh_ctx * handle = raw_handle;
245  word32 my_private_key_length, my_public_key_length;
246  tr_lock * rng_lock = get_rng_lock ();
247
248  assert (handle != NULL);
249  assert (public_key != NULL);
250
251  if (handle->private_key == NULL)
252    handle->private_key = tr_malloc (handle->key_length);
253
254  tr_lockLock (rng_lock);
255
256  if (!check_result (DhGenerateKeyPair (&handle->dh, get_rng (),
257                                        handle->private_key, &my_private_key_length,
258                                        public_key, &my_public_key_length)))
259    {
260      tr_lockUnlock (rng_lock);
261      return false;
262    }
263
264  tr_lockUnlock (rng_lock);
265
266  tr_dh_align_key (public_key, my_public_key_length, handle->key_length);
267
268  handle->private_key_length = my_private_key_length;
269
270  if (public_key_length != NULL)
271    *public_key_length = handle->key_length;
272
273  return true;
274}
275
276tr_dh_secret_t
277tr_dh_agree (tr_dh_ctx_t     raw_handle,
278             const uint8_t * other_public_key,
279             size_t          other_public_key_length)
280{
281  struct tr_dh_ctx * handle = raw_handle;
282  struct tr_dh_secret * ret;
283  word32 my_secret_key_length;
284
285  assert (handle != NULL);
286  assert (other_public_key != NULL);
287
288  ret = tr_dh_secret_new (handle->key_length);
289
290  if (check_result (DhAgree (&handle->dh,
291                             ret->key, &my_secret_key_length,
292                             handle->private_key, handle->private_key_length,
293                             other_public_key, other_public_key_length)))
294    {
295      tr_dh_secret_align (ret, my_secret_key_length);
296    }
297  else
298    {
299      tr_dh_secret_free (ret);
300      ret = NULL;
301    }
302
303  return ret;
304}
305
306/***
307****
308***/
309
310bool
311tr_rand_buffer (void   * buffer,
312                size_t   length)
313{
314  bool ret;
315  tr_lock * rng_lock = get_rng_lock ();
316
317  assert (buffer != NULL);
318
319  tr_lockLock (rng_lock);
320  ret = check_result (RNG_GenerateBlock (get_rng (), buffer, length));
321  tr_lockUnlock (rng_lock);
322
323  return ret;
324}
Note: See TracBrowser for help on using the repository browser.