LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_digest_openssl.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 141 151 93.4 %
Date: 2021-11-24 03:28:48 Functions: 18 19 94.7 %

          Line data    Source code
       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        5395 : MOCK_IMPL(int,
      42             : crypto_digest,(char *digest, const char *m, size_t len))
      43             : {
      44        5395 :   tor_assert(m);
      45        5395 :   tor_assert(digest);
      46        5395 :   if (SHA1((const unsigned char*)m,len,(unsigned char*)digest) == NULL) {
      47           0 :     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        7309 : crypto_digest256(char *digest, const char *m, size_t len,
      57             :                  digest_algorithm_t algorithm)
      58             : {
      59        7309 :   tor_assert(m);
      60        7309 :   tor_assert(digest);
      61        7309 :   tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
      62             : 
      63        7309 :   int ret = 0;
      64        7309 :   if (algorithm == DIGEST_SHA256) {
      65        3942 :     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        3367 :     ret = (sha3_256((uint8_t *)digest, DIGEST256_LEN,(const uint8_t *)m, len)
      72        3367 :            > -1);
      73             : #endif /* defined(OPENSSL_HAS_SHA3) */
      74             :   }
      75             : 
      76        7309 :   if (!ret)
      77           0 :     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       11129 : crypto_digest512(char *digest, const char *m, size_t len,
      86             :                  digest_algorithm_t algorithm)
      87             : {
      88       11129 :   tor_assert(m);
      89       11129 :   tor_assert(digest);
      90       11129 :   tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
      91             : 
      92       11129 :   int ret = 0;
      93       11129 :   if (algorithm == DIGEST_SHA512) {
      94       10956 :     ret = (SHA512((const unsigned char*)m,len,(unsigned char*)digest)
      95       10956 :            != 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         173 :     ret = (sha3_512((uint8_t*)digest, DIGEST512_LEN, (const uint8_t*)m, len)
     102         173 :            > -1);
     103             : #endif /* defined(OPENSSL_HAS_SHA3) */
     104             :   }
     105             : 
     106       11129 :   if (!ret)
     107           0 :     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           4 : crypto_digest_get_algorithm(crypto_digest_t *digest)
     134             : {
     135           4 :   tor_assert(digest);
     136             : 
     137           4 :   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      147132 : 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      147132 :   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       53649 : crypto_digest_new_internal(digest_algorithm_t algorithm)
     185             : {
     186       53649 :   crypto_digest_t *r = tor_malloc(crypto_digest_alloc_bytes(algorithm));
     187       53649 :   r->algorithm = algorithm;
     188             : 
     189       53649 :   switch (algorithm)
     190             :     {
     191         201 :     case DIGEST_SHA1:
     192         201 :       SHA1_Init(&r->d.sha1);
     193         201 :       break;
     194         467 :     case DIGEST_SHA256:
     195         467 :       SHA256_Init(&r->d.sha2);
     196         467 :       break;
     197       39030 :     case DIGEST_SHA512:
     198       39030 :       SHA512_Init(&r->d.sha512);
     199       39030 :       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       13949 :     case DIGEST_SHA3_256:
     217       13949 :       keccak_digest_init(&r->d.sha3, 256);
     218       13949 :       break;
     219           2 :     case DIGEST_SHA3_512:
     220           2 :       keccak_digest_init(&r->d.sha3, 512);
     221           2 :       break;
     222             : #endif /* defined(OPENSSL_HAS_SHA3) */
     223           0 :     default:
     224           0 :       tor_assert_unreached();
     225             :     }
     226             : 
     227       53649 :   return r;
     228             : }
     229             : 
     230             : /** Allocate and return a new digest object to compute SHA1 digests.
     231             :  */
     232             : crypto_digest_t *
     233         146 : crypto_digest_new(void)
     234             : {
     235         146 :   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       14376 : crypto_digest256_new(digest_algorithm_t algorithm)
     246             : {
     247       14376 :   tor_assert(algorithm == DIGEST_SHA256 || algorithm == DIGEST_SHA3_256);
     248       14376 :   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       39032 : crypto_digest512_new(digest_algorithm_t algorithm)
     255             : {
     256       39032 :   tor_assert(algorithm == DIGEST_SHA512 || algorithm == DIGEST_SHA3_512);
     257       39032 :   return crypto_digest_new_internal(algorithm);
     258             : }
     259             : 
     260             : /** Deallocate a digest object.
     261             :  */
     262             : void
     263       53938 : crypto_digest_free_(crypto_digest_t *digest)
     264             : {
     265       53938 :   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       53632 :   size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
     276       53632 :   memwipe(digest, 0, bytes);
     277       53632 :   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      190541 : crypto_digest_add_bytes(crypto_digest_t *digest, const char *data,
     287             :                         size_t len)
     288             : {
     289      190541 :   tor_assert(digest);
     290      190541 :   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      190541 :   switch (digest->algorithm) {
     297       32847 :     case DIGEST_SHA1:
     298       32847 :       SHA1_Update(&digest->d.sha1, (void*)data, len);
     299       32847 :       break;
     300        1910 :     case DIGEST_SHA256:
     301        1910 :       SHA256_Update(&digest->d.sha2, (void*)data, len);
     302        1910 :       break;
     303      102212 :     case DIGEST_SHA512:
     304      102212 :       SHA512_Update(&digest->d.sha512, (void*)data, len);
     305      102212 :       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       53572 :     case DIGEST_SHA3_256: FALLTHROUGH;
     315             :     case DIGEST_SHA3_512:
     316       53572 :       keccak_digest_update(&digest->d.sha3, (const uint8_t *)data, len);
     317       53572 :       break;
     318             : #endif /* defined(OPENSSL_HAS_SHA3) */
     319           0 :     default:
     320             :       /* LCOV_EXCL_START */
     321             :       tor_fragile_assert();
     322             :       break;
     323             :       /* LCOV_EXCL_STOP */
     324             :   }
     325      190541 : }
     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       53846 : crypto_digest_get_digest(crypto_digest_t *digest,
     336             :                          char *out, size_t out_len)
     337             : {
     338       53846 :   unsigned char r[DIGEST512_LEN];
     339       53846 :   tor_assert(digest);
     340       53846 :   tor_assert(out);
     341       53846 :   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       53846 :   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       14105 :     keccak_digest_sum(&digest->d.sha3, (uint8_t *)out, out_len);
     361       14105 :     return;
     362             : #endif /* defined(OPENSSL_HAS_SHA3) */
     363             :   }
     364             : 
     365       39741 :   const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
     366       39741 :   crypto_digest_t tmpenv;
     367             :   /* memcpy into a temporary ctx, since SHA*_Final clears the context */
     368       39741 :   memcpy(&tmpenv, digest, alloc_bytes);
     369       39741 :   switch (digest->algorithm) {
     370         285 :     case DIGEST_SHA1:
     371         285 :       SHA1_Final(r, &tmpenv.d.sha1);
     372         285 :       break;
     373         424 :     case DIGEST_SHA256:
     374         424 :       SHA256_Final(r, &tmpenv.d.sha2);
     375         424 :       break;
     376       39032 :     case DIGEST_SHA512:
     377       39032 :       SHA512_Final(r, &tmpenv.d.sha512);
     378       39032 :       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       39741 :   memcpy(out, r, out_len);
     393       39741 :   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           5 : crypto_digest_dup(const crypto_digest_t *digest)
     404             : {
     405           5 :   tor_assert(digest);
     406           5 :   const size_t alloc_bytes = crypto_digest_alloc_bytes(digest->algorithm);
     407           5 :   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           5 :   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         100 : crypto_digest_checkpoint(crypto_digest_checkpoint_t *checkpoint,
     424             :                          const crypto_digest_t *digest)
     425             : {
     426         100 :   const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
     427         100 :   tor_assert(bytes <= sizeof(checkpoint->mem));
     428         100 :   memcpy(checkpoint->mem, digest, bytes);
     429         100 : }
     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           0 : crypto_digest_restore(crypto_digest_t *digest,
     436             :                       const crypto_digest_checkpoint_t *checkpoint)
     437             : {
     438           0 :   const size_t bytes = crypto_digest_alloc_bytes(digest->algorithm);
     439           0 :   memcpy(digest, checkpoint->mem, bytes);
     440           0 : }
     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           5 : crypto_digest_assign(crypto_digest_t *into,
     448             :                      const crypto_digest_t *from)
     449             : {
     450           5 :   tor_assert(into);
     451           5 :   tor_assert(from);
     452           5 :   tor_assert(into->algorithm == from->algorithm);
     453           5 :   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           5 :   memcpy(into,from,alloc_bytes);
     464           5 : }
     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          70 : 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          70 :   crypto_digest_smartlist_prefix(digest_out, len_out, NULL, lst, append, alg);
     478          70 : }
     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          95 : 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          95 :   crypto_digest_t *d = crypto_digest_new_internal(alg);
     494          95 :   if (prepend)
     495          25 :     crypto_digest_add_bytes(d, prepend, strlen(prepend));
     496        1769 :   SMARTLIST_FOREACH(lst, const char *, cp,
     497             :                     crypto_digest_add_bytes(d, cp, strlen(cp)));
     498          95 :   if (append)
     499          95 :     crypto_digest_add_bytes(d, append, strlen(append));
     500          95 :   crypto_digest_get_digest(d, digest_out, len_out);
     501          95 :   crypto_digest_free(d);
     502          95 : }
     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          57 : 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          57 :   tor_assert(key_len < INT_MAX);
     515          57 :   tor_assert(msg_len < INT_MAX);
     516          57 :   tor_assert(hmac_out);
     517          57 :   unsigned char *rv = NULL;
     518          57 :   rv = HMAC(EVP_sha256(), key, (int)key_len, (unsigned char*)msg, (int)msg_len,
     519             :             (unsigned char*)hmac_out, NULL);
     520          57 :   tor_assert(rv);
     521          57 : }

Generated by: LCOV version 1.14