LCOV - code coverage report
Current view: top level - lib/crypt_ops - crypto_s2k.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 168 170 98.8 %
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_s2k.c
       9             :  *
      10             :  * \brief Functions for deriving keys from human-readable passphrases.
      11             :  */
      12             : 
      13             : #define CRYPTO_S2K_PRIVATE
      14             : 
      15             : #include "lib/crypt_ops/crypto_cipher.h"
      16             : #include "lib/crypt_ops/crypto_digest.h"
      17             : #include "lib/crypt_ops/crypto_hkdf.h"
      18             : #include "lib/crypt_ops/crypto_rand.h"
      19             : #include "lib/crypt_ops/crypto_s2k.h"
      20             : #include "lib/crypt_ops/crypto_util.h"
      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             : 
      71             : /** Given an algorithm ID (one of S2K_TYPE_*), return the length of the
      72             :  * specifier part of it, without the prefix type byte.  Return -1 if it is not
      73             :  * a valid algorithm ID. */
      74             : static int
      75          93 : secret_to_key_spec_len(uint8_t type)
      76             : {
      77          93 :   switch (type) {
      78             :     case S2K_TYPE_RFC2440:
      79             :       return S2K_RFC2440_SPECIFIER_LEN;
      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             : 
      89             : /** Given an algorithm ID (one of S2K_TYPE_*), return the length of the
      90             :  * its preferred output. */
      91             : static int
      92          28 : secret_to_key_key_len(uint8_t type)
      93             : {
      94          28 :   switch (type) {
      95             :     case S2K_TYPE_RFC2440:
      96             :       return DIGEST_LEN;
      97             :     case S2K_TYPE_PBKDF2:
      98             :       return DIGEST_LEN;
      99          12 :     case S2K_TYPE_SCRYPT:
     100          12 :       return DIGEST256_LEN;
     101             :     // LCOV_EXCL_START
     102             :     default:
     103             :       tor_fragile_assert();
     104             :       return -1;
     105             :     // LCOV_EXCL_STOP
     106             :   }
     107             : }
     108             : 
     109             : /** Given a specifier in <b>spec_and_key</b> of length
     110             :  * <b>spec_and_key_len</b>, along with its prefix algorithm ID byte, and along
     111             :  * with a key if <b>key_included</b> is true, check whether the whole
     112             :  * specifier-and-key is of valid length, and return the algorithm type if it
     113             :  * is.  Set *<b>legacy_out</b> to 1 iff this is a legacy password hash or
     114             :  * legacy specifier.  Return an error code on failure.
     115             :  */
     116             : static int
     117          56 : 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          56 :   size_t legacy_len = S2K_RFC2440_SPECIFIER_LEN;
     121          56 :   uint8_t type;
     122          56 :   int total_len;
     123             : 
     124          56 :   if (key_included)
     125          13 :     legacy_len += DIGEST_LEN;
     126             : 
     127          56 :   if (spec_and_key_len == legacy_len) {
     128           5 :     *legacy_out = 1;
     129           5 :     return S2K_TYPE_RFC2440;
     130             :   }
     131             : 
     132          51 :   *legacy_out = 0;
     133          51 :   if (spec_and_key_len == 0)
     134             :     return S2K_BAD_LEN;
     135             : 
     136          49 :   type = spec_and_key[0];
     137          49 :   total_len = secret_to_key_spec_len(type);
     138          49 :   if (total_len < 0)
     139             :     return S2K_BAD_ALGORITHM;
     140          47 :   if (key_included) {
     141           9 :     int keylen = secret_to_key_key_len(type);
     142           9 :     if (keylen < 0)
     143             :       return S2K_BAD_ALGORITHM;
     144           9 :     total_len += keylen;
     145             :   }
     146             : 
     147          47 :   if ((size_t)total_len + 1 == spec_and_key_len)
     148             :     return type;
     149             :   else
     150           3 :     return S2K_BAD_LEN;
     151             : }
     152             : 
     153             : /**
     154             :  * Write a new random s2k specifier of type <b>type</b>, without prefixing
     155             :  * type byte, to <b>spec_out</b>, which must have enough room.  May adjust
     156             :  * parameter choice based on <b>flags</b>.
     157             :  */
     158             : static int
     159          15 : make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
     160             : {
     161          15 :   int speclen = secret_to_key_spec_len(type);
     162          15 :   if (speclen < 0)
     163             :       return S2K_BAD_ALGORITHM;
     164             : 
     165          15 :   crypto_rand((char*)spec_out, speclen);
     166          15 :   switch (type) {
     167           5 :     case S2K_TYPE_RFC2440:
     168             :       /* Hash 64 k of data. */
     169           5 :       spec_out[S2K_RFC2440_SPECIFIER_LEN-1] = 96;
     170           5 :       break;
     171           3 :     case S2K_TYPE_PBKDF2:
     172             :       /* 131 K iterations */
     173           3 :       spec_out[PBKDF2_SPEC_LEN-1] = 17;
     174           3 :       break;
     175           7 :     case S2K_TYPE_SCRYPT:
     176           7 :       if (flags & S2K_FLAG_LOW_MEM) {
     177             :         /* N = 1<<12 */
     178           3 :         spec_out[SCRYPT_SPEC_LEN-2] = 12;
     179             :       } else {
     180             :         /* N = 1<<15 */
     181           4 :         spec_out[SCRYPT_SPEC_LEN-2] = 15;
     182             :       }
     183             :       /* r = 8; p = 2. */
     184           7 :       spec_out[SCRYPT_SPEC_LEN-1] = (3u << 4) | (1u << 0);
     185           7 :       break;
     186             :     // LCOV_EXCL_START - we should have returned above.
     187             :     default:
     188             :       tor_fragile_assert();
     189             :       return S2K_BAD_ALGORITHM;
     190             :     // LCOV_EXCL_STOP
     191             :   }
     192             : 
     193             :   return speclen;
     194             : }
     195             : 
     196             : /** Implement RFC2440-style iterated-salted S2K conversion: convert the
     197             :  * <b>secret_len</b>-byte <b>secret</b> into a <b>key_out_len</b> byte
     198             :  * <b>key_out</b>.  As in RFC2440, the first 8 bytes of s2k_specifier
     199             :  * are a salt; the 9th byte describes how much iteration to do.
     200             :  * If <b>key_out_len</b> &gt; DIGEST_LEN, use HDKF to expand the result.
     201             :  */
     202             : void
     203          22 : 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          22 :   crypto_digest_t *d;
     207          22 :   uint8_t c;
     208          22 :   size_t count, tmplen;
     209          22 :   char *tmp;
     210          22 :   uint8_t buf[DIGEST_LEN];
     211          22 :   tor_assert(key_out_len < SIZE_T_CEILING);
     212             : 
     213             : #define EXPBIAS 6
     214          22 :   c = s2k_specifier[8];
     215          22 :   count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
     216             : #undef EXPBIAS
     217             : 
     218          22 :   d = crypto_digest_new();
     219          22 :   tmplen = 8+secret_len;
     220          22 :   tmp = tor_malloc(tmplen);
     221          22 :   memcpy(tmp,s2k_specifier,8);
     222          22 :   memcpy(tmp+8,secret,secret_len);
     223          22 :   secret_len += 8;
     224       31570 :   while (count) {
     225       31568 :     if (count >= secret_len) {
     226       31548 :       crypto_digest_add_bytes(d, tmp, secret_len);
     227       31548 :       count -= secret_len;
     228             :     } else {
     229          20 :       crypto_digest_add_bytes(d, tmp, count);
     230          20 :       count = 0;
     231             :     }
     232             :   }
     233          22 :   crypto_digest_get_digest(d, (char*)buf, sizeof(buf));
     234             : 
     235          22 :   if (key_out_len <= sizeof(buf)) {
     236          10 :     memcpy(key_out, buf, key_out_len);
     237             :   } else {
     238          12 :     crypto_expand_key_material_rfc5869_sha256(buf, DIGEST_LEN,
     239             :                                            (const uint8_t*)s2k_specifier, 8,
     240             :                                            (const uint8_t*)"EXPAND", 6,
     241             :                                            (uint8_t*)key_out, key_out_len);
     242             :   }
     243          22 :   memwipe(tmp, 0, tmplen);
     244          22 :   memwipe(buf, 0, sizeof(buf));
     245          22 :   tor_free(tmp);
     246          22 :   crypto_digest_free(d);
     247          22 : }
     248             : 
     249             : /**
     250             :  * Helper: given a valid specifier without prefix type byte in <b>spec</b>,
     251             :  * whose length must be correct, and given a secret passphrase <b>secret</b>
     252             :  * of length <b>secret_len</b>, compute the key and store it into
     253             :  * <b>key_out</b>, which must have enough room for secret_to_key_key_len(type)
     254             :  * bytes.  Return the number of bytes written on success and an error code
     255             :  * on failure.
     256             :  */
     257             : STATIC int
     258          63 : 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          63 :   int rv;
     264          63 :   if (key_out_len > INT_MAX)
     265             :     return S2K_BAD_LEN;
     266             : 
     267          63 :   switch (type) {
     268          20 :     case S2K_TYPE_RFC2440:
     269          20 :       secret_to_key_rfc2440((char*)key_out, key_out_len, secret, secret_len,
     270             :                             (const char*)spec);
     271          20 :       return (int)key_out_len;
     272             : 
     273          16 :     case S2K_TYPE_PBKDF2: {
     274          16 :       uint8_t log_iters;
     275          16 :       if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
     276             :         return S2K_BAD_LEN;
     277          16 :       log_iters = spec[spec_len-1];
     278          16 :       if (log_iters > 31)
     279             :         return S2K_BAD_PARAMS;
     280             : #ifdef ENABLE_OPENSSL
     281          30 :       rv = PKCS5_PBKDF2_HMAC_SHA1(secret, (int)secret_len,
     282          15 :                                   spec, (int)spec_len-1,
     283             :                                   (1<<log_iters),
     284             :                                   (int)key_out_len, key_out);
     285          15 :       if (rv < 0)
     286           0 :         return S2K_FAILED;
     287             :       return (int)key_out_len;
     288             : #else /* !defined(ENABLE_OPENSSL) */
     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 /* defined(ENABLE_OPENSSL) */
     329             :     }
     330             : 
     331          27 :     case S2K_TYPE_SCRYPT: {
     332             : #ifdef HAVE_SCRYPT
     333          27 :       uint8_t log_N, log_r, log_p;
     334          27 :       uint64_t N;
     335          27 :       uint32_t r, p;
     336          27 :       if (spec_len < 2)
     337             :         return S2K_BAD_LEN;
     338          27 :       log_N = spec[spec_len-2];
     339          27 :       log_r = (spec[spec_len-1]) >> 4;
     340          27 :       log_p = (spec[spec_len-1]) & 15;
     341          27 :       if (log_N > 63)
     342             :         return S2K_BAD_PARAMS;
     343          26 :       N = ((uint64_t)1) << log_N;
     344          26 :       r = 1u << log_r;
     345          26 :       p = 1u << log_p;
     346          26 :       rv = libscrypt_scrypt((const uint8_t*)secret, secret_len,
     347             :                             spec, spec_len-2, N, r, p, key_out, key_out_len);
     348          26 :       if (rv != 0)
     349             :         return S2K_FAILED;
     350          26 :       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             : 
     360             : /**
     361             :  * Given a specifier previously constructed with secret_to_key_make_specifier
     362             :  * in <b>spec</b> of length <b>spec_len</b>, and a secret password in
     363             :  * <b>secret</b> of length <b>secret_len</b>, generate <b>key_out_len</b>
     364             :  * bytes of cryptographic material in <b>key_out</b>.  The native output of
     365             :  * the secret-to-key function will be truncated if key_out_len is short, and
     366             :  * expanded with HKDF if key_out_len is long.  Returns S2K_OKAY on success,
     367             :  * and an error code on failure.
     368             :  */
     369             : int
     370          43 : 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          43 :   int legacy_format = 0;
     375          43 :   int type = secret_to_key_get_type(spec, spec_len, 0, &legacy_format);
     376          43 :   int r;
     377             : 
     378          43 :   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          39 :   if (! legacy_format) {
     386          36 :     ++spec;
     387          36 :     --spec_len;
     388             :   }
     389             : 
     390          39 :   r = secret_to_key_compute_key(key_out, key_out_len, spec, spec_len,
     391             :                                 secret, secret_len, type);
     392          39 :   if (r < 0)
     393             :     return r;
     394             :   else
     395          37 :     return S2K_OKAY;
     396             : }
     397             : 
     398             : /**
     399             :  * Construct a new s2k algorithm specifier and salt in <b>buf</b>, according
     400             :  * to the bitwise-or of some S2K_FLAG_* options in <b>flags</b>.  Up to
     401             :  * <b>buf_len</b> bytes of storage may be used in <b>buf</b>.  Return the
     402             :  * number of bytes used on success and an error code on failure.
     403             :  */
     404             : int
     405          19 : secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags)
     406             : {
     407          19 :   int rv;
     408          19 :   int spec_len;
     409             : #ifdef HAVE_SCRYPT
     410          19 :   uint8_t type = S2K_TYPE_SCRYPT;
     411             : #else
     412             :   uint8_t type = S2K_TYPE_RFC2440;
     413             : #endif
     414             : 
     415          19 :   if (flags & S2K_FLAG_NO_SCRYPT)
     416           6 :     type = S2K_TYPE_RFC2440;
     417          19 :   if (flags & S2K_FLAG_USE_PBKDF2)
     418           4 :     type = S2K_TYPE_PBKDF2;
     419             : 
     420          19 :   spec_len = secret_to_key_spec_len(type);
     421             : 
     422          19 :   if ((int)buf_len < spec_len + 1)
     423             :     return S2K_TRUNCATED;
     424             : 
     425          15 :   buf[0] = type;
     426          15 :   rv = make_specifier(buf+1, type, flags);
     427          15 :   if (rv < 0)
     428             :     return rv;
     429             :   else
     430          15 :     return rv + 1;
     431             : }
     432             : 
     433             : /**
     434             :  * Hash a passphrase from <b>secret</b> of length <b>secret_len</b>, according
     435             :  * to the bitwise-or of some S2K_FLAG_* options in <b>flags</b>, and store the
     436             :  * hash along with salt and hashing parameters into <b>buf</b>.  Up to
     437             :  * <b>buf_len</b> bytes of storage may be used in <b>buf</b>.  Set
     438             :  * *<b>len_out</b> to the number of bytes used and return S2K_OKAY on success;
     439             :  * and return an error code on failure.
     440             :  */
     441             : int
     442           9 : 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           9 :   int key_len;
     449           9 :   int spec_len;
     450           9 :   int type;
     451           9 :   int rv;
     452             : 
     453           9 :   spec_len = secret_to_key_make_specifier(buf, buf_len, flags);
     454             : 
     455           9 :   if (spec_len < 0)
     456             :     return spec_len;
     457             : 
     458           9 :   type = buf[0];
     459           9 :   key_len = secret_to_key_key_len(type);
     460             : 
     461           9 :   if (key_len < 0)
     462             :     return key_len;
     463             : 
     464           9 :   if ((int)buf_len < key_len + spec_len)
     465             :     return S2K_TRUNCATED;
     466             : 
     467          10 :   rv = secret_to_key_compute_key(buf + spec_len, key_len,
     468           5 :                                  buf + 1, spec_len-1,
     469             :                                  secret, secret_len, type);
     470           5 :   if (rv < 0)
     471             :     return rv;
     472             : 
     473           5 :   *len_out = spec_len + key_len;
     474             : 
     475           5 :   return S2K_OKAY;
     476             : }
     477             : 
     478             : /**
     479             :  * Given a hashed passphrase in <b>spec_and_key</b> of length
     480             :  * <b>spec_and_key_len</b> as generated by secret_to_key_new(), verify whether
     481             :  * it is a hash of the passphrase <b>secret</b> of length <b>secret_len</b>.
     482             :  * Return S2K_OKAY on a match, S2K_BAD_SECRET on a well-formed hash that
     483             :  * doesn't match this secret, and another error code on other errors.
     484             :  */
     485             : int
     486          13 : 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          13 :   int is_legacy = 0;
     490          13 :   int type = secret_to_key_get_type(spec_and_key, spec_and_key_len,
     491             :                                     1, &is_legacy);
     492          13 :   uint8_t buf[32];
     493          13 :   int spec_len;
     494          13 :   int key_len;
     495          13 :   int rv;
     496             : 
     497          13 :   if (type < 0)
     498             :     return type;
     499             : 
     500          10 :   if (! is_legacy) {
     501           8 :     spec_and_key++;
     502           8 :     spec_and_key_len--;
     503             :   }
     504             : 
     505          10 :   spec_len = secret_to_key_spec_len(type);
     506          10 :   key_len = secret_to_key_key_len(type);
     507          10 :   tor_assert(spec_len > 0);
     508          10 :   tor_assert(key_len > 0);
     509          10 :   tor_assert(key_len <= (int) sizeof(buf));
     510          10 :   tor_assert((int)spec_and_key_len == spec_len + key_len);
     511          10 :   rv = secret_to_key_compute_key(buf, key_len,
     512             :                                  spec_and_key, spec_len,
     513             :                                  secret, secret_len, type);
     514          10 :   if (rv < 0)
     515           0 :     goto done;
     516             : 
     517          10 :   if (tor_memeq(buf, spec_and_key + spec_len, key_len))
     518             :     rv = S2K_OKAY;
     519             :   else
     520           5 :     rv = S2K_BAD_SECRET;
     521             : 
     522          10 :  done:
     523          10 :   memwipe(buf, 0, sizeof(buf));
     524          10 :   return rv;
     525             : }

Generated by: LCOV version 1.14