tor  0.4.2.0-alpha-dev
crypto_digest_nss.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 
16 #include "lib/log/log.h"
17 #include "lib/log/util_bug.h"
18 
19 #include "keccak-tiny/keccak-tiny.h"
20 
21 #include <stdlib.h>
22 #include <string.h>
23 
24 #include "lib/arch/bytes.h"
25 
26 DISABLE_GCC_WARNING(strict-prototypes)
27 #include <pk11pub.h>
28 ENABLE_GCC_WARNING(strict-prototypes)
29 
30 
33 static SECOidTag
34 digest_alg_to_nss_oid(digest_algorithm_t alg)
35 {
36  switch (alg) {
37  case DIGEST_SHA1: return SEC_OID_SHA1;
38  case DIGEST_SHA256: return SEC_OID_SHA256;
39  case DIGEST_SHA512: return SEC_OID_SHA512;
40  case DIGEST_SHA3_256: /* Fall through */
41  case DIGEST_SHA3_512: /* Fall through */
42  default:
43  return SEC_OID_UNKNOWN;
44  }
45 }
46 
47 /* Helper: get an unkeyed digest via pk11wrap */
48 static int
49 digest_nss_internal(SECOidTag alg,
50  char *digest, unsigned len_out,
51  const char *msg, size_t msg_len)
52 {
53  if (alg == SEC_OID_UNKNOWN)
54  return -1;
55  tor_assert(msg_len <= UINT_MAX);
56 
57  int rv = -1;
58  SECStatus s;
59  PK11Context *ctx = PK11_CreateDigestContext(alg);
60  if (!ctx)
61  return -1;
62 
63  s = PK11_DigestBegin(ctx);
64  if (s != SECSuccess)
65  goto done;
66 
67  s = PK11_DigestOp(ctx, (const unsigned char *)msg, (unsigned int)msg_len);
68  if (s != SECSuccess)
69  goto done;
70 
71  unsigned int len = 0;
72  s = PK11_DigestFinal(ctx, (unsigned char *)digest, &len, len_out);
73  if (s != SECSuccess)
74  goto done;
75 
76  rv = 0;
77  done:
78  PK11_DestroyContext(ctx, PR_TRUE);
79  return rv;
80 }
81 
84 static bool
85 library_supports_digest(digest_algorithm_t alg)
86 {
87  switch (alg) {
88  case DIGEST_SHA1: /* Fall through */
89  case DIGEST_SHA256: /* Fall through */
90  case DIGEST_SHA512: /* Fall through */
91  return true;
92  case DIGEST_SHA3_256: /* Fall through */
93  case DIGEST_SHA3_512: /* Fall through */
94  default:
95  return false;
96  }
97 }
98 
99 /* Crypto digest functions */
100 
106 crypto_digest,(char *digest, const char *m, size_t len))
107 {
108  tor_assert(m);
109  tor_assert(digest);
110  return digest_nss_internal(SEC_OID_SHA1, digest, DIGEST_LEN, m, len);
111 }
112 
116 int
117 crypto_digest256(char *digest, const char *m, size_t len,
118  digest_algorithm_t algorithm)
119 {
120  tor_assert(m);
121  tor_assert(digest);
122  tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
123 
124  int ret = 0;
125  if (algorithm == DIGEST_SHA256) {
126  return digest_nss_internal(SEC_OID_SHA256, digest, DIGEST256_LEN, m, len);
127  } else {
128  ret = (sha3_256((uint8_t *)digest, DIGEST256_LEN,(const uint8_t *)m, len)
129  > -1);
130  }
131 
132  if (!ret)
133  return -1;
134  return 0;
135 }
136 
140 int
141 crypto_digest512(char *digest, const char *m, size_t len,
142  digest_algorithm_t algorithm)
143 {
144  tor_assert(m);
145  tor_assert(digest);
146  tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
147 
148  int ret = 0;
149  if (algorithm == DIGEST_SHA512) {
150  return digest_nss_internal(SEC_OID_SHA512, digest, DIGEST512_LEN, m, len);
151  } else {
152  ret = (sha3_512((uint8_t*)digest, DIGEST512_LEN, (const uint8_t*)m, len)
153  > -1);
154  }
155 
156  if (!ret)
157  return -1;
158  return 0;
159 }
160 
163  digest_algorithm_t algorithm;
168  union {
169  PK11Context *ctx;
170  keccak_state sha3;
171  } d;
172 };
173 
174 #ifdef TOR_UNIT_TESTS
175 
176 digest_algorithm_t
177 crypto_digest_get_algorithm(crypto_digest_t *digest)
178 {
179  tor_assert(digest);
180 
181  return digest->algorithm;
182 }
183 
184 #endif /* defined(TOR_UNIT_TESTS) */
185 
191 static size_t
192 crypto_digest_alloc_bytes(digest_algorithm_t alg)
193 {
194  /* Helper: returns the number of bytes in the 'f' field of 'st' */
195 #define STRUCT_FIELD_SIZE(st, f) (sizeof( ((st*)0)->f ))
196  /* Gives the length of crypto_digest_t through the end of the field 'd' */
197 #define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \
198  STRUCT_FIELD_SIZE(crypto_digest_t, f))
199  switch (alg) {
200  case DIGEST_SHA1: /* Fall through */
201  case DIGEST_SHA256: /* Fall through */
202  case DIGEST_SHA512:
203  return END_OF_FIELD(d.ctx);
204  case DIGEST_SHA3_256:
205  case DIGEST_SHA3_512:
206  return END_OF_FIELD(d.sha3);
207  default:
208  tor_assert(0); // LCOV_EXCL_LINE
209  return 0; // LCOV_EXCL_LINE
210  }
211 #undef END_OF_FIELD
212 #undef STRUCT_FIELD_SIZE
213 }
214 
219 static crypto_digest_t *
220 crypto_digest_new_internal(digest_algorithm_t algorithm)
221 {
222  crypto_digest_t *r = tor_malloc(crypto_digest_alloc_bytes(algorithm));
223  r->algorithm = algorithm;
224 
225  switch (algorithm)
226  {
227  case DIGEST_SHA1: /* fall through */
228  case DIGEST_SHA256: /* fall through */
229  case DIGEST_SHA512:
230  r->d.ctx = PK11_CreateDigestContext(digest_alg_to_nss_oid(algorithm));
231  if (BUG(!r->d.ctx)) {
232  tor_free(r);
233  return NULL;
234  }
235  if (BUG(SECSuccess != PK11_DigestBegin(r->d.ctx))) {
236  crypto_digest_free(r);
237  return NULL;
238  }
239  break;
240  case DIGEST_SHA3_256:
241  keccak_digest_init(&r->d.sha3, 256);
242  break;
243  case DIGEST_SHA3_512:
244  keccak_digest_init(&r->d.sha3, 512);
245  break;
246  default:
247  tor_assert_unreached();
248  }
249 
250  return r;
251 }
252 
257 {
258  return crypto_digest_new_internal(DIGEST_SHA1);
259 }
260 
268 crypto_digest256_new(digest_algorithm_t algorithm)
269 {
270  tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
271  return crypto_digest_new_internal(algorithm);
272 }
273 
277 crypto_digest512_new(digest_algorithm_t algorithm)
278 {
279  tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
280  return crypto_digest_new_internal(algorithm);
281 }
282 
285 void
287 {
288  if (!digest)
289  return;
290  if (library_supports_digest(digest->algorithm)) {
291  PK11_DestroyContext(digest->d.ctx, PR_TRUE);
292  }
293  size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
294  memwipe(digest, 0, bytes);
295  tor_free(digest);
296 }
297 
303 void
304 crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
305  size_t len)
306 {
307  tor_assert(digest);
308  tor_assert(data);
309  /* Using the SHA*_*() calls directly means we don't support doing
310  * SHA in hardware. But so far the delay of getting the question
311  * to the hardware, and hearing the answer, is likely higher than
312  * just doing it ourselves. Hashes are fast.
313  */
314  switch (digest->algorithm) {
315  case DIGEST_SHA1: /* fall through */
316  case DIGEST_SHA256: /* fall through */
317  case DIGEST_SHA512:
318  tor_assert(len <= UINT_MAX);
319  SECStatus s = PK11_DigestOp(digest->d.ctx,
320  (const unsigned char *)data,
321  (unsigned int)len);
322  tor_assert(s == SECSuccess);
323  break;
324  case DIGEST_SHA3_256: /* FALLSTHROUGH */
325  case DIGEST_SHA3_512:
326  keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len);
327  break;
328  default:
329  /* LCOV_EXCL_START */
331  break;
332  /* LCOV_EXCL_STOP */
333  }
334 }
335 
343 void
345  char *out, size_t out_len)
346 {
347  unsigned char r[DIGEST512_LEN];
348  tor_assert(digest);
349  tor_assert(out);
351 
352  /* The SHA-3 code handles copying into a temporary ctx, and also can handle
353  * short output buffers by truncating appropriately. */
354  if (digest->algorithm == DIGEST_SHA3_256 ||
355  digest->algorithm == DIGEST_SHA3_512) {
356  keccak_digest_sum(&digest->d.sha3, (uint8_t *)out, out_len);
357  return;
358  }
359 
360  /* Copy into a temporary buffer since DigestFinal (alters) the context */
361  unsigned char buf[1024];
362  unsigned int saved_len = 0;
363  unsigned rlen;
364  unsigned char *saved = PK11_SaveContextAlloc(digest->d.ctx,
365  buf, sizeof(buf),
366  &saved_len);
367  tor_assert(saved);
368  SECStatus s = PK11_DigestFinal(digest->d.ctx, r, &rlen, sizeof(r));
369  tor_assert(s == SECSuccess);
370  tor_assert(rlen >= out_len);
371  s = PK11_RestoreContext(digest->d.ctx, saved, saved_len);
372  tor_assert(s == SECSuccess);
373 
374  if (saved != buf) {
375  PORT_ZFree(saved, saved_len);
376  }
377  memcpy(out, r, out_len);
378  memwipe(r, 0, sizeof(r));
379 }
380 
389 {
390  tor_assert(digest);
391  const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
392  crypto_digest_t *result = tor_memdup(digest, alloc_bytes);
393 
394  if (library_supports_digest(digest->algorithm)) {
395  result->d.ctx = PK11_CloneContext(digest->d.ctx);
396  }
397 
398  return result;
399 }
400 
404 void
406  const crypto_digest_t *digest)
407 {
408  const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
409  tor_assert(bytes <= sizeof(checkpoint->mem));
410  if (library_supports_digest(digest->algorithm)) {
411  unsigned char *allocated;
412  allocated = PK11_SaveContextAlloc(digest->d.ctx,
413  (unsigned char *)checkpoint->mem,
414  sizeof(checkpoint->mem),
415  &checkpoint->bytes_used);
416  /* No allocation is allowed here. */
417  tor_assert(allocated == checkpoint->mem);
418  return;
419  }
420  memcpy(checkpoint->mem, digest, bytes);
421 }
422 
426 void
428  const crypto_digest_checkpoint_t *checkpoint)
429 {
430  const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
431  if (library_supports_digest(digest->algorithm)) {
432  SECStatus s = PK11_RestoreContext(digest->d.ctx,
433  (unsigned char *)checkpoint->mem,
434  checkpoint->bytes_used);
435  tor_assert(s == SECSuccess);
436  return;
437  }
438  memcpy(digest, checkpoint->mem, bytes);
439 }
440 
445 void
447  const crypto_digest_t *from)
448 {
449  tor_assert(into);
450  tor_assert(from);
451  tor_assert(into->algorithm == from->algorithm);
452  const size_t alloc_bytes = crypto_digest_alloc_bytes(from->algorithm);
453  if (library_supports_digest(from->algorithm)) {
454  PK11_DestroyContext(into->d.ctx, PR_TRUE);
455  into->d.ctx = PK11_CloneContext(from->d.ctx);
456  return;
457  }
458  memcpy(into,from,alloc_bytes);
459 }
460 
466 void
467 crypto_digest_smartlist(char *digest_out, size_t len_out,
468  const smartlist_t *lst,
469  const char *append,
470  digest_algorithm_t alg)
471 {
472  crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg);
473 }
474 
481 void
482 crypto_digest_smartlist_prefix(char *digest_out, size_t len_out,
483  const char *prepend,
484  const smartlist_t *lst,
485  const char *append,
486  digest_algorithm_t alg)
487 {
489  if (prepend)
490  crypto_digest_add_bytes(d, prepend, strlen(prepend));
491  SMARTLIST_FOREACH(lst, const char *, cp,
492  crypto_digest_add_bytes(d, cp, strlen(cp)));
493  if (append)
494  crypto_digest_add_bytes(d, append, strlen(append));
495  crypto_digest_get_digest(d, digest_out, len_out);
496  crypto_digest_free(d);
497 }
498 
503 void
504 crypto_hmac_sha256(char *hmac_out,
505  const char *key, size_t key_len,
506  const char *msg, size_t msg_len)
507 {
508  /* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */
509  tor_assert(key_len < INT_MAX);
510  tor_assert(msg_len < INT_MAX);
511  tor_assert(hmac_out);
512 
513  PK11SlotInfo *slot = NULL;
514  PK11SymKey *symKey = NULL;
515  PK11Context *hmac = NULL;
516 
517  int ok = 0;
518  SECStatus s;
519  SECItem keyItem, paramItem;
520  keyItem.data = (unsigned char *)key;
521  keyItem.len = (unsigned)key_len;
522  paramItem.type = siBuffer;
523  paramItem.data = NULL;
524  paramItem.len = 0;
525 
526  slot = PK11_GetBestSlot(CKM_SHA256_HMAC, NULL);
527  if (!slot)
528  goto done;
529  symKey = PK11_ImportSymKey(slot, CKM_SHA256_HMAC,
530  PK11_OriginUnwrap, CKA_SIGN, &keyItem, NULL);
531  if (!symKey)
532  goto done;
533 
534  hmac = PK11_CreateContextBySymKey(CKM_SHA256_HMAC, CKA_SIGN, symKey,
535  &paramItem);
536  if (!hmac)
537  goto done;
538  s = PK11_DigestBegin(hmac);
539  if (s != SECSuccess)
540  goto done;
541  s = PK11_DigestOp(hmac, (const unsigned char *)msg, (unsigned int)msg_len);
542  if (s != SECSuccess)
543  goto done;
544  unsigned int len=0;
545  s = PK11_DigestFinal(hmac, (unsigned char *)hmac_out, &len, DIGEST256_LEN);
546  if (s != SECSuccess || len != DIGEST256_LEN)
547  goto done;
548  ok = 1;
549 
550  done:
551  if (hmac)
552  PK11_DestroyContext(hmac, PR_TRUE);
553  if (symKey)
554  PK11_FreeSymKey(symKey);
555  if (slot)
556  PK11_FreeSlot(slot);
557 
558  tor_assert(ok);
559 }
560 
void crypto_digest_smartlist(char *digest_out, size_t len_out, const smartlist_t *lst, const char *append, digest_algorithm_t alg)
int crypto_digest256(char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
crypto_digest_t * crypto_digest256_new(digest_algorithm_t algorithm)
Header for smartlist.c.
static bool library_supports_digest(digest_algorithm_t alg)
#define DIGEST512_LEN
Definition: digest_sizes.h:25
digest_algorithm_t algorithm
static size_t crypto_digest_alloc_bytes(digest_algorithm_t alg)
int crypto_digest512(char *digest, const char *m, size_t len, digest_algorithm_t algorithm)
void crypto_digest_smartlist_prefix(char *digest_out, size_t len_out, const char *prepend, const smartlist_t *lst, const char *append, digest_algorithm_t alg)
crypto_digest_t * crypto_digest512_new(digest_algorithm_t algorithm)
#define tor_free(p)
Definition: malloc.h:52
#define tor_fragile_assert()
Definition: util_bug.h:241
void memwipe(void *mem, uint8_t byte, size_t sz)
Definition: crypto_util.c:57
#define DIGEST256_LEN
Definition: digest_sizes.h:23
void crypto_hmac_sha256(char *hmac_out, const char *key, size_t key_len, const char *msg, size_t msg_len)
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
Common functions for cryptographic routines.
tor_assert(buffer)
void crypto_digest_free_(crypto_digest_t *digest)
void crypto_digest_assign(crypto_digest_t *into, const crypto_digest_t *from)
#define DIGEST_LEN
Definition: digest_sizes.h:20
static SECOidTag digest_alg_to_nss_oid(digest_algorithm_t alg)
crypto_digest_t * crypto_digest_dup(const crypto_digest_t *digest)
void crypto_digest_restore(crypto_digest_t *digest, const crypto_digest_checkpoint_t *checkpoint)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
MOCK_IMPL(int, crypto_digest,(char *digest, const char *m, size_t len))
Headers for crypto_digest.c.
#define SMARTLIST_FOREACH(sl, type, var, cmd)
Inline functions for reading and writing multibyte values from the middle of strings,...
size_t crypto_digest_algorithm_get_length(digest_algorithm_t alg)
Definition: crypto_digest.c:86
crypto_digest_t * crypto_digest_new(void)
Headers for log.c.
Macros to manage assertions, fatal and non-fatal.
void crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint, const crypto_digest_t *digest)
static crypto_digest_t * crypto_digest_new_internal(digest_algorithm_t algorithm)
union crypto_digest_t::@3 d