LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_digest.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 60 61 98.4 %
Date: 2021-11-24 03:28:48 Functions: 10 10 100.0 %

          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.c
       9             :  * \brief Block of functions related with digest and xof utilities and
      10             :  * operations.
      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             : /** Set the common_digests_t in <b>ds_out</b> to contain every digest on the
      27             :  * <b>len</b> bytes in <b>m</b> that we know how to compute.  Return 0 on
      28             :  * success, -1 on failure. */
      29             : int
      30        3593 : crypto_common_digests(common_digests_t *ds_out, const char *m, size_t len)
      31             : {
      32        3593 :   tor_assert(ds_out);
      33        3593 :   memset(ds_out, 0, sizeof(*ds_out));
      34        3593 :   if (crypto_digest(ds_out->d[DIGEST_SHA1], m, len) < 0)
      35             :     return -1;
      36        3591 :   if (crypto_digest256(ds_out->d[DIGEST_SHA256], m, len, DIGEST_SHA256) < 0)
      37           0 :     return -1;
      38             : 
      39             :   return 0;
      40             : }
      41             : 
      42             : /** Return the name of an algorithm, as used in directory documents. */
      43             : const char *
      44         428 : crypto_digest_algorithm_get_name(digest_algorithm_t alg)
      45             : {
      46         428 :   switch (alg) {
      47             :     case DIGEST_SHA1:
      48             :       return "sha1";
      49         298 :     case DIGEST_SHA256:
      50         298 :       return "sha256";
      51           1 :     case DIGEST_SHA512:
      52           1 :       return "sha512";
      53         106 :     case DIGEST_SHA3_256:
      54         106 :       return "sha3-256";
      55           1 :     case DIGEST_SHA3_512:
      56           1 :       return "sha3-512";
      57             :       // LCOV_EXCL_START
      58             :     default:
      59             :       tor_fragile_assert();
      60             :       return "??unknown_digest??";
      61             :       // LCOV_EXCL_STOP
      62             :   }
      63             : }
      64             : 
      65             : /** Given the name of a digest algorithm, return its integer value, or -1 if
      66             :  * the name is not recognized. */
      67             : int
      68        4090 : crypto_digest_algorithm_parse_name(const char *name)
      69             : {
      70        4090 :   if (!strcmp(name, "sha1"))
      71             :     return DIGEST_SHA1;
      72        4062 :   else if (!strcmp(name, "sha256"))
      73             :     return DIGEST_SHA256;
      74        3746 :   else if (!strcmp(name, "sha512"))
      75             :     return DIGEST_SHA512;
      76        3165 :   else if (!strcmp(name, "sha3-256"))
      77             :     return DIGEST_SHA3_256;
      78         674 :   else if (!strcmp(name, "sha3-512"))
      79             :     return DIGEST_SHA3_512;
      80             :   else
      81         667 :     return -1;
      82             : }
      83             : 
      84             : /** Given an algorithm, return the digest length in bytes. */
      85             : size_t
      86       53858 : crypto_digest_algorithm_get_length(digest_algorithm_t alg)
      87             : {
      88       53858 :   switch (alg) {
      89             :     case DIGEST_SHA1:
      90             :       return DIGEST_LEN;
      91             :     case DIGEST_SHA256:
      92             :       return DIGEST256_LEN;
      93             :     case DIGEST_SHA512:
      94             :       return DIGEST512_LEN;
      95             :     case DIGEST_SHA3_256:
      96             :       return DIGEST256_LEN;
      97             :     case DIGEST_SHA3_512:
      98             :       return DIGEST512_LEN;
      99             :     default:
     100             :       tor_assert(0);              // LCOV_EXCL_LINE
     101             :       return 0; /* Unreachable */ // LCOV_EXCL_LINE
     102             :   }
     103             : }
     104             : 
     105             : /** Compute a MAC using SHA3-256 of <b>msg_len</b> bytes in <b>msg</b> using a
     106             :  * <b>key</b> of length <b>key_len</b> and a <b>salt</b> of length
     107             :  * <b>salt_len</b>. Store the result of <b>len_out</b> bytes in in
     108             :  * <b>mac_out</b>. This function can't fail. */
     109             : void
     110          66 : crypto_mac_sha3_256(uint8_t *mac_out, size_t len_out,
     111             :                     const uint8_t *key, size_t key_len,
     112             :                     const uint8_t *msg, size_t msg_len)
     113             : {
     114          66 :   crypto_digest_t *digest;
     115             : 
     116          66 :   const uint64_t key_len_netorder = tor_htonll(key_len);
     117             : 
     118          66 :   tor_assert(mac_out);
     119          66 :   tor_assert(key);
     120          66 :   tor_assert(msg);
     121             : 
     122          66 :   digest = crypto_digest256_new(DIGEST_SHA3_256);
     123             : 
     124             :   /* Order matters here that is any subsystem using this function should
     125             :    * expect this very precise ordering in the MAC construction. */
     126          66 :   crypto_digest_add_bytes(digest, (const char *) &key_len_netorder,
     127             :                           sizeof(key_len_netorder));
     128          66 :   crypto_digest_add_bytes(digest, (const char *) key, key_len);
     129          66 :   crypto_digest_add_bytes(digest, (const char *) msg, msg_len);
     130          66 :   crypto_digest_get_digest(digest, (char *) mac_out, len_out);
     131          66 :   crypto_digest_free(digest);
     132          66 : }
     133             : 
     134             : /* xof functions  */
     135             : 
     136             : /** Internal state for a eXtendable-Output Function (XOF). */
     137             : struct crypto_xof_t {
     138             : #ifdef OPENSSL_HAS_SHAKE3_EVP
     139             :   /* XXXX We can't enable this yet, because OpenSSL's
     140             :    * DigestFinalXOF function can't be called repeatedly on the same
     141             :    * XOF.
     142             :    *
     143             :    * We could in theory use the undocumented SHA3_absorb and SHA3_squeeze
     144             :    * functions, but let's not mess with undocumented OpenSSL internals any
     145             :    * more than we have to.
     146             :    *
     147             :    * We could also revise our XOF code so that it only allows a single
     148             :    * squeeze operation; we don't require streaming squeeze operations
     149             :    * outside the tests yet.
     150             :    */
     151             :   EVP_MD_CTX *ctx;
     152             : #else /* !defined(OPENSSL_HAS_SHAKE3_EVP) */
     153             :   /**
     154             :    * State of the Keccak sponge for the SHAKE-256 computation.
     155             :    **/
     156             :   keccak_state s;
     157             : #endif /* defined(OPENSSL_HAS_SHAKE3_EVP) */
     158             : };
     159             : 
     160             : /** Allocate a new XOF object backed by SHAKE-256.  The security level
     161             :  * provided is a function of the length of the output used.  Read and
     162             :  * understand FIPS-202 A.2 "Additional Consideration for Extendable-Output
     163             :  * Functions" before using this construct.
     164             :  */
     165             : crypto_xof_t *
     166         534 : crypto_xof_new(void)
     167             : {
     168         534 :   crypto_xof_t *xof;
     169         534 :   xof = tor_malloc(sizeof(crypto_xof_t));
     170             : #ifdef OPENSSL_HAS_SHAKE256
     171             :   xof->ctx = EVP_MD_CTX_new();
     172             :   tor_assert(xof->ctx);
     173             :   int r = EVP_DigestInit(xof->ctx, EVP_shake256());
     174             :   tor_assert(r == 1);
     175             : #else /* !defined(OPENSSL_HAS_SHAKE256) */
     176         534 :   keccak_xof_init(&xof->s, 256);
     177             : #endif /* defined(OPENSSL_HAS_SHAKE256) */
     178         534 :   return xof;
     179             : }
     180             : 
     181             : /** Absorb bytes into a XOF object.  Must not be called after a call to
     182             :  * crypto_xof_squeeze_bytes() for the same instance, and will assert
     183             :  * if attempted.
     184             :  */
     185             : void
     186        1529 : crypto_xof_add_bytes(crypto_xof_t *xof, const uint8_t *data, size_t len)
     187             : {
     188             : #ifdef OPENSSL_HAS_SHAKE256
     189             :   int r = EVP_DigestUpdate(xof->ctx, data, len);
     190             :   tor_assert(r == 1);
     191             : #else
     192        1529 :   int i = keccak_xof_absorb(&xof->s, data, len);
     193        1529 :   tor_assert(i == 0);
     194             : #endif /* defined(OPENSSL_HAS_SHAKE256) */
     195        1529 : }
     196             : 
     197             : /** Squeeze bytes out of a XOF object.  Calling this routine will render
     198             :  * the XOF instance ineligible to absorb further data.
     199             :  */
     200             : void
     201        5264 : crypto_xof_squeeze_bytes(crypto_xof_t *xof, uint8_t *out, size_t len)
     202             : {
     203             : #ifdef OPENSSL_HAS_SHAKE256
     204             :   int r = EVP_DigestFinalXOF(xof->ctx, out, len);
     205             :   tor_assert(r == 1);
     206             : #else
     207        5264 :   int i = keccak_xof_squeeze(&xof->s, out, len);
     208        5264 :   tor_assert(i == 0);
     209             : #endif /* defined(OPENSSL_HAS_SHAKE256) */
     210        5264 : }
     211             : 
     212             : /** Cleanse and deallocate a XOF object. */
     213             : void
     214         566 : crypto_xof_free_(crypto_xof_t *xof)
     215             : {
     216         566 :   if (!xof)
     217             :     return;
     218             : #ifdef OPENSSL_HAS_SHAKE256
     219             :   if (xof->ctx)
     220             :     EVP_MD_CTX_free(xof->ctx);
     221             : #endif
     222         534 :   memwipe(xof, 0, sizeof(crypto_xof_t));
     223         534 :   tor_free(xof);
     224             : }
     225             : 
     226             : /** Compute the XOF (SHAKE256) of a <b>input_len</b> bytes at <b>input</b>,
     227             :  * putting <b>output_len</b> bytes at <b>output</b>. */
     228             : void
     229          39 : crypto_xof(uint8_t *output, size_t output_len,
     230             :            const uint8_t *input, size_t input_len)
     231             : {
     232             : #ifdef OPENSSL_HAS_SHA3
     233             :   EVP_MD_CTX *ctx = EVP_MD_CTX_new();
     234             :   tor_assert(ctx);
     235             :   int r = EVP_DigestInit(ctx, EVP_shake256());
     236             :   tor_assert(r == 1);
     237             :   r = EVP_DigestUpdate(ctx, input, input_len);
     238             :   tor_assert(r == 1);
     239             :   r = EVP_DigestFinalXOF(ctx, output, output_len);
     240             :   tor_assert(r == 1);
     241             :   EVP_MD_CTX_free(ctx);
     242             : #else /* !defined(OPENSSL_HAS_SHA3) */
     243          39 :   crypto_xof_t *xof = crypto_xof_new();
     244          39 :   crypto_xof_add_bytes(xof, input, input_len);
     245          39 :   crypto_xof_squeeze_bytes(xof, output, output_len);
     246          39 :   crypto_xof_free(xof);
     247             : #endif /* defined(OPENSSL_HAS_SHA3) */
     248          39 : }

Generated by: LCOV version 1.14