tor  0.4.0.1-alpha
crypto_s2k.c
Go to the documentation of this file.
1 /* Copyright (c) 2001, Matej Pfajfar.
2  * Copyright (c) 2001-2004, Roger Dingledine.
3  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
4  * Copyright (c) 2007-2019, The Tor Project, Inc. */
5 /* See LICENSE for licensing information */
6 
13 #define CRYPTO_S2K_PRIVATE
14 
21 #include "lib/ctime/di_ops.h"
22 #include "lib/log/util_bug.h"
23 #include "lib/intmath/cmp.h"
24 
25 #ifdef ENABLE_OPENSSL
26 #include <openssl/evp.h>
27 #endif
28 #ifdef ENABLE_NSS
29 #include <pk11pub.h>
30 #endif
31 
32 #if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
33 #define HAVE_SCRYPT
34 #include <libscrypt.h>
35 #endif
36 
37 #include <string.h>
38 
39 /* Encoded secrets take the form:
40 
41  u8 type;
42  u8 salt_and_parameters[depends on type];
43  u8 key[depends on type];
44 
45  As a special case, if the encoded secret is exactly 29 bytes long,
46  type 0 is understood.
47 
48  Recognized types are:
49  00 -- RFC2440. salt_and_parameters is 9 bytes. key is 20 bytes.
50  salt_and_parameters is 8 bytes random salt,
51  1 byte iteration info.
52  01 -- PKBDF2_SHA1. salt_and_parameters is 17 bytes. key is 20 bytes.
53  salt_and_parameters is 16 bytes random salt,
54  1 byte iteration info.
55  02 -- SCRYPT_SALSA208_SHA256. salt_and_parameters is 18 bytes. key is
56  32 bytes.
57  salt_and_parameters is 18 bytes random salt, 2 bytes iteration
58  info.
59 */
60 
61 #define S2K_TYPE_RFC2440 0
62 #define S2K_TYPE_PBKDF2 1
63 #define S2K_TYPE_SCRYPT 2
64 
65 #define PBKDF2_SPEC_LEN 17
66 #define PBKDF2_KEY_LEN 20
67 
68 #define SCRYPT_SPEC_LEN 18
69 #define SCRYPT_KEY_LEN 32
70 
74 static int
76 {
77  switch (type) {
78  case S2K_TYPE_RFC2440:
80  case S2K_TYPE_PBKDF2:
81  return PBKDF2_SPEC_LEN;
82  case S2K_TYPE_SCRYPT:
83  return SCRYPT_SPEC_LEN;
84  default:
85  return -1;
86  }
87 }
88 
91 static int
92 secret_to_key_key_len(uint8_t type)
93 {
94  switch (type) {
95  case S2K_TYPE_RFC2440:
96  return DIGEST_LEN;
97  case S2K_TYPE_PBKDF2:
98  return DIGEST_LEN;
99  case S2K_TYPE_SCRYPT:
100  return DIGEST256_LEN;
101  // LCOV_EXCL_START
102  default:
104  return -1;
105  // LCOV_EXCL_STOP
106  }
107 }
108 
116 static int
117 secret_to_key_get_type(const uint8_t *spec_and_key, size_t spec_and_key_len,
118  int key_included, int *legacy_out)
119 {
120  size_t legacy_len = S2K_RFC2440_SPECIFIER_LEN;
121  uint8_t type;
122  int total_len;
123 
124  if (key_included)
125  legacy_len += DIGEST_LEN;
126 
127  if (spec_and_key_len == legacy_len) {
128  *legacy_out = 1;
129  return S2K_TYPE_RFC2440;
130  }
131 
132  *legacy_out = 0;
133  if (spec_and_key_len == 0)
134  return S2K_BAD_LEN;
135 
136  type = spec_and_key[0];
137  total_len = secret_to_key_spec_len(type);
138  if (total_len < 0)
139  return S2K_BAD_ALGORITHM;
140  if (key_included) {
141  int keylen = secret_to_key_key_len(type);
142  if (keylen < 0)
143  return S2K_BAD_ALGORITHM;
144  total_len += keylen;
145  }
146 
147  if ((size_t)total_len + 1 == spec_and_key_len)
148  return type;
149  else
150  return S2K_BAD_LEN;
151 }
152 
158 static int
159 make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
160 {
161  int speclen = secret_to_key_spec_len(type);
162  if (speclen < 0)
163  return S2K_BAD_ALGORITHM;
164 
165  crypto_rand((char*)spec_out, speclen);
166  switch (type) {
167  case S2K_TYPE_RFC2440:
168  /* Hash 64 k of data. */
169  spec_out[S2K_RFC2440_SPECIFIER_LEN-1] = 96;
170  break;
171  case S2K_TYPE_PBKDF2:
172  /* 131 K iterations */
173  spec_out[PBKDF2_SPEC_LEN-1] = 17;
174  break;
175  case S2K_TYPE_SCRYPT:
176  if (flags & S2K_FLAG_LOW_MEM) {
177  /* N = 1<<12 */
178  spec_out[SCRYPT_SPEC_LEN-2] = 12;
179  } else {
180  /* N = 1<<15 */
181  spec_out[SCRYPT_SPEC_LEN-2] = 15;
182  }
183  /* r = 8; p = 2. */
184  spec_out[SCRYPT_SPEC_LEN-1] = (3u << 4) | (1u << 0);
185  break;
186  // LCOV_EXCL_START - we should have returned above.
187  default:
189  return S2K_BAD_ALGORITHM;
190  // LCOV_EXCL_STOP
191  }
192 
193  return speclen;
194 }
195 
202 void
203 secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret,
204  size_t secret_len, const char *s2k_specifier)
205 {
206  crypto_digest_t *d;
207  uint8_t c;
208  size_t count, tmplen;
209  char *tmp;
210  uint8_t buf[DIGEST_LEN];
211  tor_assert(key_out_len < SIZE_T_CEILING);
212 
213 #define EXPBIAS 6
214  c = s2k_specifier[8];
215  count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
216 #undef EXPBIAS
217 
218  d = crypto_digest_new();
219  tmplen = 8+secret_len;
220  tmp = tor_malloc(tmplen);
221  memcpy(tmp,s2k_specifier,8);
222  memcpy(tmp+8,secret,secret_len);
223  secret_len += 8;
224  while (count) {
225  if (count >= secret_len) {
226  crypto_digest_add_bytes(d, tmp, secret_len);
227  count -= secret_len;
228  } else {
229  crypto_digest_add_bytes(d, tmp, count);
230  count = 0;
231  }
232  }
233  crypto_digest_get_digest(d, (char*)buf, sizeof(buf));
234 
235  if (key_out_len <= sizeof(buf)) {
236  memcpy(key_out, buf, key_out_len);
237  } else {
239  (const uint8_t*)s2k_specifier, 8,
240  (const uint8_t*)"EXPAND", 6,
241  (uint8_t*)key_out, key_out_len);
242  }
243  memwipe(tmp, 0, tmplen);
244  memwipe(buf, 0, sizeof(buf));
245  tor_free(tmp);
246  crypto_digest_free(d);
247 }
248 
257 STATIC int
258 secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len,
259  const uint8_t *spec, size_t spec_len,
260  const char *secret, size_t secret_len,
261  int type)
262 {
263  int rv;
264  if (key_out_len > INT_MAX)
265  return S2K_BAD_LEN;
266 
267  switch (type) {
268  case S2K_TYPE_RFC2440:
269  secret_to_key_rfc2440((char*)key_out, key_out_len, secret, secret_len,
270  (const char*)spec);
271  return (int)key_out_len;
272 
273  case S2K_TYPE_PBKDF2: {
274  uint8_t log_iters;
275  if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
276  return S2K_BAD_LEN;
277  log_iters = spec[spec_len-1];
278  if (log_iters > 31)
279  return S2K_BAD_PARAMS;
280 #ifdef ENABLE_OPENSSL
281  rv = PKCS5_PBKDF2_HMAC_SHA1(secret, (int)secret_len,
282  spec, (int)spec_len-1,
283  (1<<log_iters),
284  (int)key_out_len, key_out);
285  if (rv < 0)
286  return S2K_FAILED;
287  return (int)key_out_len;
288 #else
289  SECItem passItem = { .type = siBuffer,
290  .data = (unsigned char *) secret,
291  .len = (int)secret_len };
292  SECItem saltItem = { .type = siBuffer,
293  .data = (unsigned char *) spec,
294  .len = (int)spec_len - 1 };
295  SECAlgorithmID *alg = NULL;
296  PK11SymKey *key = NULL;
297 
298  rv = S2K_FAILED;
299  alg = PK11_CreatePBEV2AlgorithmID(
300  SEC_OID_PKCS5_PBKDF2, SEC_OID_HMAC_SHA1, SEC_OID_HMAC_SHA1,
301  (int)key_out_len, (1<<log_iters), &saltItem);
302  if (alg == NULL)
303  return S2K_FAILED;
304 
305  key = PK11_PBEKeyGen(NULL /* slot */,
306  alg,
307  &passItem,
308  false,
309  NULL);
310 
311  SECStatus st = PK11_ExtractKeyValue(key);
312  if (st != SECSuccess)
313  goto nss_pbkdf_err;
314 
315  const SECItem *iptr = PK11_GetKeyData(key);
316  if (iptr == NULL)
317  goto nss_pbkdf_err;
318 
319  rv = MIN((int)iptr->len, (int)key_out_len);
320  memcpy(key_out, iptr->data, rv);
321 
322  nss_pbkdf_err:
323  if (key)
324  PK11_FreeSymKey(key);
325  if (alg)
326  SECOID_DestroyAlgorithmID(alg, PR_TRUE);
327  return rv;
328 #endif
329  }
330 
331  case S2K_TYPE_SCRYPT: {
332 #ifdef HAVE_SCRYPT
333  uint8_t log_N, log_r, log_p;
334  uint64_t N;
335  uint32_t r, p;
336  if (spec_len < 2)
337  return S2K_BAD_LEN;
338  log_N = spec[spec_len-2];
339  log_r = (spec[spec_len-1]) >> 4;
340  log_p = (spec[spec_len-1]) & 15;
341  if (log_N > 63)
342  return S2K_BAD_PARAMS;
343  N = ((uint64_t)1) << log_N;
344  r = 1u << log_r;
345  p = 1u << log_p;
346  rv = libscrypt_scrypt((const uint8_t*)secret, secret_len,
347  spec, spec_len-2, N, r, p, key_out, key_out_len);
348  if (rv != 0)
349  return S2K_FAILED;
350  return (int)key_out_len;
351 #else /* !(defined(HAVE_SCRYPT)) */
352  return S2K_NO_SCRYPT_SUPPORT;
353 #endif /* defined(HAVE_SCRYPT) */
354  }
355  default:
356  return S2K_BAD_ALGORITHM;
357  }
358 }
359 
369 int
370 secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len,
371  const uint8_t *spec, size_t spec_len,
372  const char *secret, size_t secret_len)
373 {
374  int legacy_format = 0;
375  int type = secret_to_key_get_type(spec, spec_len, 0, &legacy_format);
376  int r;
377 
378  if (type < 0)
379  return type;
380 #ifndef HAVE_SCRYPT
381  if (type == S2K_TYPE_SCRYPT)
382  return S2K_NO_SCRYPT_SUPPORT;
383  #endif
384 
385  if (! legacy_format) {
386  ++spec;
387  --spec_len;
388  }
389 
390  r = secret_to_key_compute_key(key_out, key_out_len, spec, spec_len,
391  secret, secret_len, type);
392  if (r < 0)
393  return r;
394  else
395  return S2K_OKAY;
396 }
397 
404 int
405 secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags)
406 {
407  int rv;
408  int spec_len;
409 #ifdef HAVE_SCRYPT
410  uint8_t type = S2K_TYPE_SCRYPT;
411 #else
412  uint8_t type = S2K_TYPE_RFC2440;
413 #endif
414 
415  if (flags & S2K_FLAG_NO_SCRYPT)
416  type = S2K_TYPE_RFC2440;
417  if (flags & S2K_FLAG_USE_PBKDF2)
418  type = S2K_TYPE_PBKDF2;
419 
420  spec_len = secret_to_key_spec_len(type);
421 
422  if ((int)buf_len < spec_len + 1)
423  return S2K_TRUNCATED;
424 
425  buf[0] = type;
426  rv = make_specifier(buf+1, type, flags);
427  if (rv < 0)
428  return rv;
429  else
430  return rv + 1;
431 }
432 
441 int
442 secret_to_key_new(uint8_t *buf,
443  size_t buf_len,
444  size_t *len_out,
445  const char *secret, size_t secret_len,
446  unsigned flags)
447 {
448  int key_len;
449  int spec_len;
450  int type;
451  int rv;
452 
453  spec_len = secret_to_key_make_specifier(buf, buf_len, flags);
454 
455  if (spec_len < 0)
456  return spec_len;
457 
458  type = buf[0];
459  key_len = secret_to_key_key_len(type);
460 
461  if (key_len < 0)
462  return key_len;
463 
464  if ((int)buf_len < key_len + spec_len)
465  return S2K_TRUNCATED;
466 
467  rv = secret_to_key_compute_key(buf + spec_len, key_len,
468  buf + 1, spec_len-1,
469  secret, secret_len, type);
470  if (rv < 0)
471  return rv;
472 
473  *len_out = spec_len + key_len;
474 
475  return S2K_OKAY;
476 }
477 
485 int
486 secret_to_key_check(const uint8_t *spec_and_key, size_t spec_and_key_len,
487  const char *secret, size_t secret_len)
488 {
489  int is_legacy = 0;
490  int type = secret_to_key_get_type(spec_and_key, spec_and_key_len,
491  1, &is_legacy);
492  uint8_t buf[32];
493  int spec_len;
494  int key_len;
495  int rv;
496 
497  if (type < 0)
498  return type;
499 
500  if (! is_legacy) {
501  spec_and_key++;
502  spec_and_key_len--;
503  }
504 
505  spec_len = secret_to_key_spec_len(type);
506  key_len = secret_to_key_key_len(type);
507  tor_assert(spec_len > 0);
508  tor_assert(key_len > 0);
509  tor_assert(key_len <= (int) sizeof(buf));
510  tor_assert((int)spec_and_key_len == spec_len + key_len);
511  rv = secret_to_key_compute_key(buf, key_len,
512  spec_and_key, spec_len,
513  secret, secret_len, type);
514  if (rv < 0)
515  goto done;
516 
517  if (tor_memeq(buf, spec_and_key + spec_len, key_len))
518  rv = S2K_OKAY;
519  else
520  rv = S2K_BAD_SECRET;
521 
522  done:
523  memwipe(buf, 0, sizeof(buf));
524  return rv;
525 }
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
STATIC int secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len, const uint8_t *spec, size_t spec_len, const char *secret, size_t secret_len, int type)
Definition: crypto_s2k.c:258
Common functions for using (pseudo-)random number generators.
static int secret_to_key_key_len(uint8_t type)
Definition: crypto_s2k.c:92
Headers for di_ops.c.
int secret_to_key_new(uint8_t *buf, size_t buf_len, size_t *len_out, const char *secret, size_t secret_len, unsigned flags)
Definition: crypto_s2k.c:442
Headers for crypto_cipher.c.
Macro definitions for MIN, MAX, and CLAMP.
#define S2K_FAILED
Definition: crypto_s2k.h:41
crypto_digest_t * crypto_digest_new(void)
#define S2K_BAD_LEN
Definition: crypto_s2k.h:54
#define S2K_FLAG_USE_PBKDF2
Definition: crypto_s2k.h:33
static int secret_to_key_spec_len(uint8_t type)
Definition: crypto_s2k.c:75
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:221
#define S2K_OKAY
Definition: crypto_s2k.h:39
#define S2K_NO_SCRYPT_SUPPORT
Definition: crypto_s2k.h:49
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
int secret_to_key_check(const uint8_t *spec_and_key, size_t spec_and_key_len, const char *secret, size_t secret_len)
Definition: crypto_s2k.c:486
#define S2K_BAD_SECRET
Definition: crypto_s2k.h:43
#define DIGEST256_LEN
Definition: digest_sizes.h:23
Headers for crypto_hkdf.h.
#define S2K_FLAG_LOW_MEM
Definition: crypto_s2k.h:30
int crypto_expand_key_material_rfc5869_sha256(const uint8_t *key_in, size_t key_in_len, const uint8_t *salt_in, size_t salt_in_len, const uint8_t *info_in, size_t info_in_len, uint8_t *key_out, size_t key_out_len)
Definition: crypto_hkdf.c:178
Common functions for cryptographic routines.
tor_assert(buffer)
int tor_memeq(const void *a, const void *b, size_t sz)
Definition: di_ops.c:107
void secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret, size_t secret_len, const char *s2k_specifier)
Definition: crypto_s2k.c:203
#define SIZE_T_CEILING
Definition: torint.h:126
#define DIGEST_LEN
Definition: digest_sizes.h:20
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
Header for crypto_s2k.c.
#define S2K_BAD_ALGORITHM
Definition: crypto_s2k.h:45
Headers for crypto_digest.c.
#define S2K_FLAG_NO_SCRYPT
Definition: crypto_s2k.h:27
#define S2K_TRUNCATED
Definition: crypto_s2k.h:52
#define S2K_RFC2440_SPECIFIER_LEN
Definition: crypto_s2k.h:21
static int secret_to_key_get_type(const uint8_t *spec_and_key, size_t spec_and_key_len, int key_included, int *legacy_out)
Definition: crypto_s2k.c:117
int secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len, const uint8_t *spec, size_t spec_len, const char *secret, size_t secret_len)
Definition: crypto_s2k.c:370
int secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags)
Definition: crypto_s2k.c:405
Macros to manage assertions, fatal and non-fatal.
static int make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
Definition: crypto_s2k.c:159
#define S2K_BAD_PARAMS
Definition: crypto_s2k.h:47