tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

crypto_digest_openssl.c (15953B)


      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-2021, The Tor Project, Inc. */
      5 /* See LICENSE for licensing information */
      6 
      7 /**
      8 * \file crypto_digest_openssl.c
      9 * \brief Block of functions related with digest and xof utilities and
     10 * operations (OpenSSL specific implementations).
     11 **/
     12 
     13 #include "lib/container/smartlist.h"
     14 #include "lib/crypt_ops/crypto_digest.h"
     15 #include "lib/crypt_ops/crypto_util.h"
     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 #include "lib/crypt_ops/crypto_openssl_mgt.h"
     27 
     28 DISABLE_GCC_WARNING("-Wredundant-decls")
     29 
     30 #include <openssl/hmac.h>
     31 #include <openssl/sha.h>
     32 
     33 ENABLE_GCC_WARNING("-Wredundant-decls")
     34 
     35 /* Crypto digest functions */
     36 
     37 /** Compute the SHA1 digest of the <b>len</b> bytes on data stored in
     38 * <b>m</b>.  Write the DIGEST_LEN byte result into <b>digest</b>.
     39 * Return 0 on success, -1 on failure.
     40 */
     41 MOCK_IMPL(int,
     42 crypto_digest,(char *digest, const char *m, size_t len))
     43 {
     44  tor_assert(m);
     45  tor_assert(digest);
     46  if (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL) {
     47    return -1;
     48  }
     49  return 0;
     50 }
     51 
     52 /** Compute a 256-bit digest of <b>len</b> bytes in data stored in <b>m</b>,
     53 * using the algorithm <b>algorithm</b>.  Write the DIGEST_LEN256-byte result
     54 * into <b>digest</b>.  Return 0 on success, -1 on failure. */
     55 int
     56 crypto_digest256(char *digest, const char *m, size_t len,
     57                 digest_algorithm_t algorithm)
     58 {
     59  tor_assert(m);
     60  tor_assert(digest);
     61  tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
     62 
     63  int ret = 0;
     64  if (algorithm == DIGEST_SHA256) {
     65    ret = (SHA256((const uint8_t*)m,len,(uint8_t*)digest) != NULL);
     66  } else {
     67 #ifdef OPENSSL_HAS_SHA3
     68    unsigned int dlen = DIGEST256_LEN;
     69    ret = EVP_Digest(m, len, (uint8_t*)digest, &dlen, EVP_sha3_256(), NULL);
     70 #else
     71    ret = (sha3_256((uint8_t *)digest, DIGEST256_LEN,(const uint8_t *)m, len)
     72           > -1);
     73 #endif /* defined(OPENSSL_HAS_SHA3) */
     74  }
     75 
     76  if (!ret)
     77    return -1;
     78  return 0;
     79 }
     80 
     81 /** Compute a 512-bit digest of <b>len</b> bytes in data stored in <b>m</b>,
     82 * using the algorithm <b>algorithm</b>.  Write the DIGEST_LEN512-byte result
     83 * into <b>digest</b>.  Return 0 on success, -1 on failure. */
     84 int
     85 crypto_digest512(char *digest, const char *m, size_t len,
     86                 digest_algorithm_t algorithm)
     87 {
     88  tor_assert(m);
     89  tor_assert(digest);
     90  tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
     91 
     92  int ret = 0;
     93  if (algorithm == DIGEST_SHA512) {
     94    ret = (SHA512((const unsigned char*)m,len,(unsigned char*)digest)
     95           != NULL);
     96  } else {
     97 #ifdef OPENSSL_HAS_SHA3
     98    unsigned int dlen = DIGEST512_LEN;
     99    ret = EVP_Digest(m, len, (uint8_t*)digest, &dlen, EVP_sha3_512(), NULL);
    100 #else
    101    ret = (sha3_512((uint8_t*)digest, DIGEST512_LEN, (const uint8_t*)m, len)
    102           > -1);
    103 #endif /* defined(OPENSSL_HAS_SHA3) */
    104  }
    105 
    106  if (!ret)
    107    return -1;
    108  return 0;
    109 }
    110 
    111 /** Intermediate information about the digest of a stream of data. */
    112 struct crypto_digest_t {
    113  digest_algorithm_t algorithm; /**< Which algorithm is in use? */
    114   /** State for the digest we're using.  Only one member of the
    115    * union is usable, depending on the value of <b>algorithm</b>. Note also
    116    * that space for other members might not even be allocated!
    117    */
    118  union {
    119    SHA_CTX sha1; /**< state for SHA1 */
    120    SHA256_CTX sha2; /**< state for SHA256 */
    121    SHA512_CTX sha512; /**< state for SHA512 */
    122 #ifdef OPENSSL_HAS_SHA3
    123    EVP_MD_CTX *md;
    124 #else
    125    keccak_state sha3; /**< state for SHA3-[256,512] */
    126 #endif
    127  } d;
    128 };
    129 
    130 #ifdef TOR_UNIT_TESTS
    131 
    132 digest_algorithm_t
    133 crypto_digest_get_algorithm(crypto_digest_t *digest)
    134 {
    135  tor_assert(digest);
    136 
    137  return digest->algorithm;
    138 }
    139 
    140 #endif /* defined(TOR_UNIT_TESTS) */
    141 
    142 /**
    143 * Return the number of bytes we need to malloc in order to get a
    144 * crypto_digest_t for <b>alg</b>, or the number of bytes we need to wipe
    145 * when we free one.
    146 */
    147 static size_t
    148 crypto_digest_alloc_bytes(digest_algorithm_t alg)
    149 {
    150  /** Helper: returns the number of bytes in the 'f' field of 'st' */
    151 #define STRUCT_FIELD_SIZE(st, f) (sizeof( ((st*)0)->f ))
    152  /** Gives the length of crypto_digest_t through the end of the field 'd' */
    153 #define END_OF_FIELD(f) (offsetof(crypto_digest_t, f) + \
    154                         STRUCT_FIELD_SIZE(crypto_digest_t, f))
    155  switch (alg) {
    156    case DIGEST_SHA1:
    157      return END_OF_FIELD(d.sha1);
    158    case DIGEST_SHA256:
    159      return END_OF_FIELD(d.sha2);
    160    case DIGEST_SHA512:
    161      return END_OF_FIELD(d.sha512);
    162 #ifdef OPENSSL_HAS_SHA3
    163    case DIGEST_SHA3_256: FALLTHROUGH;
    164    case DIGEST_SHA3_512:
    165      return END_OF_FIELD(d.md);
    166 #else
    167    case DIGEST_SHA3_256: FALLTHROUGH;
    168    case DIGEST_SHA3_512:
    169      return END_OF_FIELD(d.sha3);
    170 #endif /* defined(OPENSSL_HAS_SHA3) */
    171    default:
    172      tor_assert(0); // LCOV_EXCL_LINE
    173      return 0;      // LCOV_EXCL_LINE
    174  }
    175 #undef END_OF_FIELD
    176 #undef STRUCT_FIELD_SIZE
    177 }
    178 
    179 /**
    180 * Internal function: create and return a new digest object for 'algorithm'.
    181 * Does not typecheck the algorithm.
    182 */
    183 static crypto_digest_t *
    184 crypto_digest_new_internal(digest_algorithm_t algorithm)
    185 {
    186  crypto_digest_t *r = tor_malloc(crypto_digest_alloc_bytes(algorithm));
    187  r->algorithm = algorithm;
    188 
    189  switch (algorithm)
    190    {
    191    case DIGEST_SHA1:
    192      SHA1_Init(&r->d.sha1);
    193      break;
    194    case DIGEST_SHA256:
    195      SHA256_Init(&r->d.sha2);
    196      break;
    197    case DIGEST_SHA512:
    198      SHA512_Init(&r->d.sha512);
    199      break;
    200 #ifdef OPENSSL_HAS_SHA3
    201    case DIGEST_SHA3_256:
    202      r->d.md = EVP_MD_CTX_new();
    203      if (!EVP_DigestInit(r->d.md, EVP_sha3_256())) {
    204        crypto_digest_free(r);
    205        return NULL;
    206      }
    207      break;
    208    case DIGEST_SHA3_512:
    209      r->d.md = EVP_MD_CTX_new();
    210      if (!EVP_DigestInit(r->d.md, EVP_sha3_512())) {
    211        crypto_digest_free(r);
    212        return NULL;
    213      }
    214      break;
    215 #else /* !defined(OPENSSL_HAS_SHA3) */
    216    case DIGEST_SHA3_256:
    217      keccak_digest_init(&r->d.sha3, 256);
    218      break;
    219    case DIGEST_SHA3_512:
    220      keccak_digest_init(&r->d.sha3, 512);
    221      break;
    222 #endif /* defined(OPENSSL_HAS_SHA3) */
    223    default:
    224      tor_assert_unreached();
    225    }
    226 
    227  return r;
    228 }
    229 
    230 /** Allocate and return a new digest object to compute SHA1 digests.
    231 */
    232 crypto_digest_t *
    233 crypto_digest_new(void)
    234 {
    235  return crypto_digest_new_internal(DIGEST_SHA1);
    236 }
    237 
    238 /** Allocate and return a new digest object to compute 256-bit digests
    239 * using <b>algorithm</b>.
    240 *
    241 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest256_new`
    242 * C_RUST_COUPLED: `crypto::digest::Sha256::default`
    243 */
    244 crypto_digest_t *
    245 crypto_digest256_new(digest_algorithm_t algorithm)
    246 {
    247  tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
    248  return crypto_digest_new_internal(algorithm);
    249 }
    250 
    251 /** Allocate and return a new digest object to compute 512-bit digests
    252 * using <b>algorithm</b>. */
    253 crypto_digest_t *
    254 crypto_digest512_new(digest_algorithm_t algorithm)
    255 {
    256  tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
    257  return crypto_digest_new_internal(algorithm);
    258 }
    259 
    260 /** Deallocate a digest object.
    261 */
    262 void
    263 crypto_digest_free_(crypto_digest_t *digest)
    264 {
    265  if (!digest)
    266    return;
    267 #ifdef OPENSSL_HAS_SHA3
    268  if (digest->algorithm == DIGEST_SHA3_256 ||
    269      digest->algorithm == DIGEST_SHA3_512) {
    270    if (digest->d.md) {
    271      EVP_MD_CTX_free(digest->d.md);
    272    }
    273  }
    274 #endif /* defined(OPENSSL_HAS_SHA3) */
    275  size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
    276  memwipe(digest, 0, bytes);
    277  tor_free(digest);
    278 }
    279 
    280 /** Add <b>len</b> bytes from <b>data</b> to the digest object.
    281 *
    282 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_add_bytess`
    283 * C_RUST_COUPLED: `crypto::digest::Sha256::process`
    284 */
    285 void
    286 crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
    287                        size_t len)
    288 {
    289  tor_assert(digest);
    290  tor_assert(data);
    291  /* Using the SHA*_*() calls directly means we don't support doing
    292   * SHA in hardware. But so far the delay of getting the question
    293   * to the hardware, and hearing the answer, is likely higher than
    294   * just doing it ourselves. Hashes are fast.
    295   */
    296  switch (digest->algorithm) {
    297    case DIGEST_SHA1:
    298      SHA1_Update(&digest->d.sha1, (void*)data, len);
    299      break;
    300    case DIGEST_SHA256:
    301      SHA256_Update(&digest->d.sha2, (void*)data, len);
    302      break;
    303    case DIGEST_SHA512:
    304      SHA512_Update(&digest->d.sha512, (void*)data, len);
    305      break;
    306 #ifdef OPENSSL_HAS_SHA3
    307    case DIGEST_SHA3_256: FALLTHROUGH;
    308    case DIGEST_SHA3_512: {
    309      int r = EVP_DigestUpdate(digest->d.md, data, len);
    310      tor_assert(r);
    311  }
    312      break;
    313 #else /* !defined(OPENSSL_HAS_SHA3) */
    314    case DIGEST_SHA3_256: FALLTHROUGH;
    315    case DIGEST_SHA3_512:
    316      keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len);
    317      break;
    318 #endif /* defined(OPENSSL_HAS_SHA3) */
    319    default:
    320      /* LCOV_EXCL_START */
    321      tor_fragile_assert();
    322      break;
    323      /* LCOV_EXCL_STOP */
    324  }
    325 }
    326 
    327 /** Compute the hash of the data that has been passed to the digest
    328 * object; write the first out_len bytes of the result to <b>out</b>.
    329 * <b>out_len</b> must be \<= DIGEST512_LEN.
    330 *
    331 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_get_digest`
    332 * C_RUST_COUPLED: `impl digest::FixedOutput for Sha256`
    333 */
    334 void
    335 crypto_digest_get_digest(crypto_digest_t *digest,
    336                         char *out, size_t out_len)
    337 {
    338  unsigned char r[DIGEST512_LEN];
    339  tor_assert(digest);
    340  tor_assert(out);
    341  tor_assert(out_len <= crypto_digest_algorithm_get_length(digest->algorithm));
    342 
    343  /* The SHA-3 code handles copying into a temporary ctx, and also can handle
    344   * short output buffers by truncating appropriately. */
    345  if (digest->algorithm == DIGEST_SHA3_256 ||
    346      digest->algorithm == DIGEST_SHA3_512) {
    347 #ifdef OPENSSL_HAS_SHA3
    348    unsigned dlen = (unsigned)
    349      crypto_digest_algorithm_get_length(digest->algorithm);
    350    EVP_MD_CTX *tmp = EVP_MD_CTX_new();
    351    EVP_MD_CTX_copy(tmp, digest->d.md);
    352    memset(r, 0xff, sizeof(r));
    353    int res = EVP_DigestFinal(tmp, r, &dlen);
    354    EVP_MD_CTX_free(tmp);
    355    tor_assert(res == 1);
    356    goto done;
    357 #else /* !defined(OPENSSL_HAS_SHA3) */
    358    /* Tiny-Keccak handles copying into a temporary ctx, and also can handle
    359     * short output buffers by truncating appropriately. */
    360    keccak_digest_sum(&digest->d.sha3, (uint8_t *)out, out_len);
    361    return;
    362 #endif /* defined(OPENSSL_HAS_SHA3) */
    363  }
    364 
    365  const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
    366  crypto_digest_t tmpenv;
    367  /* memcpy into a temporary ctx, since SHA*_Final clears the context */
    368  memcpy(&tmpenv, digest, alloc_bytes);
    369  switch (digest->algorithm) {
    370    case DIGEST_SHA1:
    371      SHA1_Final(r, &tmpenv.d.sha1);
    372      break;
    373    case DIGEST_SHA256:
    374      SHA256_Final(r, &tmpenv.d.sha2);
    375      break;
    376    case DIGEST_SHA512:
    377      SHA512_Final(r, &tmpenv.d.sha512);
    378      break;
    379 //LCOV_EXCL_START
    380    case DIGEST_SHA3_256: FALLTHROUGH;
    381    case DIGEST_SHA3_512:
    382    default:
    383      log_warn(LD_BUG, "Handling unexpected algorithm %d", digest->algorithm);
    384      /* This is fatal, because it should never happen. */
    385      tor_assert_unreached();
    386      break;
    387 //LCOV_EXCL_STOP
    388  }
    389 #ifdef OPENSSL_HAS_SHA3
    390 done:
    391 #endif
    392  memcpy(out, r, out_len);
    393  memwipe(r, 0, sizeof(r));
    394 }
    395 
    396 /** Allocate and return a new digest object with the same state as
    397 * <b>digest</b>
    398 *
    399 * C_RUST_COUPLED: `external::crypto_digest::crypto_digest_dup`
    400 * C_RUST_COUPLED: `impl Clone for crypto::digest::Sha256`
    401 */
    402 crypto_digest_t *
    403 crypto_digest_dup(const crypto_digest_t *digest)
    404 {
    405  tor_assert(digest);
    406  const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
    407  crypto_digest_t *result = tor_memdup(digest, alloc_bytes);
    408 
    409 #ifdef OPENSSL_HAS_SHA3
    410  if (digest->algorithm == DIGEST_SHA3_256 ||
    411      digest->algorithm == DIGEST_SHA3_512) {
    412    result->d.md = EVP_MD_CTX_new();
    413    EVP_MD_CTX_copy(result->d.md, digest->d.md);
    414  }
    415 #endif /* defined(OPENSSL_HAS_SHA3) */
    416  return result;
    417 }
    418 
    419 /** Temporarily save the state of <b>digest</b> in <b>checkpoint</b>.
    420 * Asserts that <b>digest</b> is a SHA1 digest object.
    421 */
    422 void
    423 crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
    424                         const crypto_digest_t *digest)
    425 {
    426  const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
    427  tor_assert(bytes <= sizeof(checkpoint->mem));
    428  memcpy(checkpoint->mem, digest, bytes);
    429 }
    430 
    431 /** Restore the state of  <b>digest</b> from <b>checkpoint</b>.
    432 * Asserts that <b>digest</b> is a SHA1 digest object. Requires that the
    433 * state was previously stored with crypto_digest_checkpoint() */
    434 void
    435 crypto_digest_restore(crypto_digest_t *digest,
    436                      const crypto_digest_checkpoint_t *checkpoint)
    437 {
    438  const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
    439  memcpy(digest, checkpoint->mem, bytes);
    440 }
    441 
    442 /** Replace the state of the digest object <b>into</b> with the state
    443 * of the digest object <b>from</b>.  Requires that 'into' and 'from'
    444 * have the same digest type.
    445 */
    446 void
    447 crypto_digest_assign(crypto_digest_t *into,
    448                     const crypto_digest_t *from)
    449 {
    450  tor_assert(into);
    451  tor_assert(from);
    452  tor_assert(into->algorithm == from->algorithm);
    453  const size_t alloc_bytes = crypto_digest_alloc_bytes(from->algorithm);
    454 
    455 #ifdef OPENSSL_HAS_SHA3
    456  if (from->algorithm == DIGEST_SHA3_256 ||
    457      from->algorithm == DIGEST_SHA3_512) {
    458    EVP_MD_CTX_copy(into->d.md, from->d.md);
    459    return;
    460  }
    461 #endif /* defined(OPENSSL_HAS_SHA3) */
    462 
    463  memcpy(into,from,alloc_bytes);
    464 }
    465 
    466 /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
    467 * at <b>digest_out</b> to the hash of the concatenation of those strings,
    468 * plus the optional string <b>append</b>, computed with the algorithm
    469 * <b>alg</b>.
    470 * <b>out_len</b> must be \<= DIGEST512_LEN. */
    471 void
    472 crypto_digest_smartlist(char *digest_out, size_t len_out,
    473                        const smartlist_t *lst,
    474                        const char *append,
    475                        digest_algorithm_t alg)
    476 {
    477  crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg);
    478 }
    479 
    480 /** Given a list of strings in <b>lst</b>, set the <b>len_out</b>-byte digest
    481 * at <b>digest_out</b> to the hash of the concatenation of: the
    482 * optional string <b>prepend</b>, those strings,
    483 * and the optional string <b>append</b>, computed with the algorithm
    484 * <b>alg</b>.
    485 * <b>len_out</b> must be \<= DIGEST512_LEN. */
    486 void
    487 crypto_digest_smartlist_prefix(char *digest_out, size_t len_out,
    488                        const char *prepend,
    489                        const smartlist_t *lst,
    490                        const char *append,
    491                        digest_algorithm_t alg)
    492 {
    493  crypto_digest_t *d = crypto_digest_new_internal(alg);
    494  if (prepend)
    495    crypto_digest_add_bytes(d, prepend, strlen(prepend));
    496  SMARTLIST_FOREACH(lst, const char *, cp,
    497                    crypto_digest_add_bytes(d, cp, strlen(cp)));
    498  if (append)
    499    crypto_digest_add_bytes(d, append, strlen(append));
    500  crypto_digest_get_digest(d, digest_out, len_out);
    501  crypto_digest_free(d);
    502 }
    503 
    504 /** Compute the HMAC-SHA-256 of the <b>msg_len</b> bytes in <b>msg</b>, using
    505 * the <b>key</b> of length <b>key_len</b>.  Store the DIGEST256_LEN-byte
    506 * result in <b>hmac_out</b>. Asserts on failure.
    507 */
    508 void
    509 crypto_hmac_sha256(char *hmac_out,
    510                   const char *key, size_t key_len,
    511                   const char *msg, size_t msg_len)
    512 {
    513  /* If we've got OpenSSL >=0.9.8 we can use its hmac implementation. */
    514  tor_assert(key_len < INT_MAX);
    515  tor_assert(msg_len < INT_MAX);
    516  tor_assert(hmac_out);
    517  unsigned char *rv = NULL;
    518  rv = HMAC(EVP_sha256(), key, (int)key_len, (unsigned char*)msg, (int)msg_len,
    519            (unsigned char*)hmac_out, NULL);
    520  tor_assert(rv);
    521 }