13#define CRYPTO_S2K_PRIVATE
26#include <openssl/evp.h>
29DISABLE_GCC_WARNING(
"-Wstrict-prototypes")
31ENABLE_GCC_WARNING(
"-Wstrict-prototypes")
34#if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
63#define S2K_TYPE_RFC2440 0
64#define S2K_TYPE_PBKDF2 1
65#define S2K_TYPE_SCRYPT 2
67#define PBKDF2_SPEC_LEN 17
68#define PBKDF2_KEY_LEN 20
70#define SCRYPT_SPEC_LEN 18
71#define SCRYPT_KEY_LEN 32
80 case S2K_TYPE_RFC2440:
83 return PBKDF2_SPEC_LEN;
85 return SCRYPT_SPEC_LEN;
97 case S2K_TYPE_RFC2440:
101 case S2K_TYPE_SCRYPT:
120 int key_included,
int *legacy_out)
129 if (spec_and_key_len == legacy_len) {
131 return S2K_TYPE_RFC2440;
135 if (spec_and_key_len == 0)
138 type = spec_and_key[0];
149 if ((
size_t)total_len + 1 == spec_and_key_len)
169 case S2K_TYPE_RFC2440:
173 case S2K_TYPE_PBKDF2:
175 spec_out[PBKDF2_SPEC_LEN-1] = 17;
177 case S2K_TYPE_SCRYPT:
180 spec_out[SCRYPT_SPEC_LEN-2] = 12;
183 spec_out[SCRYPT_SPEC_LEN-2] = 15;
186 spec_out[SCRYPT_SPEC_LEN-1] = (3u << 4) | (1u << 0);
206 size_t secret_len,
const char *s2k_specifier)
210 size_t count, tmplen;
216 c = s2k_specifier[8];
217 count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
221 tmplen = 8+secret_len;
222 tmp = tor_malloc(tmplen);
223 memcpy(tmp,s2k_specifier,8);
224 memcpy(tmp+8,secret,secret_len);
227 if (count >= secret_len) {
237 if (key_out_len <=
sizeof(buf)) {
238 memcpy(key_out, buf, key_out_len);
241 (
const uint8_t*)s2k_specifier, 8,
242 (
const uint8_t*)
"EXPAND", 6,
243 (uint8_t*)key_out, key_out_len);
261 const uint8_t *spec,
size_t spec_len,
262 const char *secret,
size_t secret_len,
266 if (key_out_len > INT_MAX)
270 case S2K_TYPE_RFC2440:
273 return (
int)key_out_len;
275 case S2K_TYPE_PBKDF2: {
277 if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
279 log_iters = spec[spec_len-1];
283 rv = PKCS5_PBKDF2_HMAC_SHA1(secret, (
int)secret_len,
284 spec, (
int)spec_len-1,
286 (
int)key_out_len, key_out);
289 return (
int)key_out_len;
291 SECItem passItem = { .type = siBuffer,
292 .data = (
unsigned char *) secret,
293 .len = (
int)secret_len };
294 SECItem saltItem = { .type = siBuffer,
295 .data = (
unsigned char *) spec,
296 .len = (
int)spec_len - 1 };
297 SECAlgorithmID *alg = NULL;
298 PK11SymKey *key = NULL;
301 alg = PK11_CreatePBEV2AlgorithmID(
302 SEC_OID_PKCS5_PBKDF2, SEC_OID_HMAC_SHA1, SEC_OID_HMAC_SHA1,
303 (
int)key_out_len, (1<<log_iters), &saltItem);
307 key = PK11_PBEKeyGen(NULL ,
313 SECStatus st = PK11_ExtractKeyValue(key);
314 if (st != SECSuccess)
317 const SECItem *iptr = PK11_GetKeyData(key);
321 rv = MIN((
int)iptr->len, (
int)key_out_len);
322 memcpy(key_out, iptr->data, rv);
326 PK11_FreeSymKey(key);
328 SECOID_DestroyAlgorithmID(alg, PR_TRUE);
333 case S2K_TYPE_SCRYPT: {
335 uint8_t log_N, log_r, log_p;
340 log_N = spec[spec_len-2];
341 log_r = (spec[spec_len-1]) >> 4;
342 log_p = (spec[spec_len-1]) & 15;
345 N = ((uint64_t)1) << log_N;
348 rv = libscrypt_scrypt((
const uint8_t*)secret, secret_len,
349 spec, spec_len-2, N, r, p, key_out, key_out_len);
352 return (
int)key_out_len;
373 const uint8_t *spec,
size_t spec_len,
374 const char *secret,
size_t secret_len)
376 int legacy_format = 0;
383 if (type == S2K_TYPE_SCRYPT)
387 if (! legacy_format) {
393 secret, secret_len, type);
412 uint8_t type = S2K_TYPE_SCRYPT;
414 uint8_t type = S2K_TYPE_RFC2440;
418 type = S2K_TYPE_RFC2440;
420 type = S2K_TYPE_PBKDF2;
424 if ((
int)buf_len < spec_len + 1)
447 const char *secret,
size_t secret_len,
466 if ((
int)buf_len < key_len + spec_len)
471 secret, secret_len, type);
475 *len_out = spec_len + key_len;
489 const char *secret,
size_t secret_len)
512 tor_assert((
int)spec_and_key_len == spec_len + key_len);
514 spec_and_key, spec_len,
515 secret, secret_len, type);
519 if (
tor_memeq(buf, spec_and_key + spec_len, key_len))
Macro definitions for MIN, MAX, and CLAMP.
Headers for crypto_cipher.c.
Headers for crypto_digest.c.
void crypto_digest_get_digest(crypto_digest_t *digest, char *out, size_t out_len)
#define crypto_digest_free(d)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
crypto_digest_t * crypto_digest_new(void)
int crypto_expand_key_material_rfc5869_sha256(const uint8_t *key_in, size_t key_in_len, const uint8_t *salt_in, size_t salt_in_len, const uint8_t *info_in, size_t info_in_len, uint8_t *key_out, size_t key_out_len)
Headers for crypto_hkdf.h.
void crypto_rand(char *to, size_t n)
Common functions for using (pseudo-)random number generators.
int secret_to_key_new(uint8_t *buf, size_t buf_len, size_t *len_out, const char *secret, size_t secret_len, unsigned flags)
int secret_to_key_check(const uint8_t *spec_and_key, size_t spec_and_key_len, const char *secret, size_t secret_len)
int secret_to_key_derivekey(uint8_t *key_out, size_t key_out_len, const uint8_t *spec, size_t spec_len, const char *secret, size_t secret_len)
static int secret_to_key_get_type(const uint8_t *spec_and_key, size_t spec_and_key_len, int key_included, int *legacy_out)
int secret_to_key_make_specifier(uint8_t *buf, size_t buf_len, unsigned flags)
static int make_specifier(uint8_t *spec_out, uint8_t type, unsigned flags)
STATIC int secret_to_key_compute_key(uint8_t *key_out, size_t key_out_len, const uint8_t *spec, size_t spec_len, const char *secret, size_t secret_len, int type)
static int secret_to_key_key_len(uint8_t type)
void secret_to_key_rfc2440(char *key_out, size_t key_out_len, const char *secret, size_t secret_len, const char *s2k_specifier)
static int secret_to_key_spec_len(uint8_t type)
#define S2K_FLAG_USE_PBKDF2
#define S2K_NO_SCRYPT_SUPPORT
#define S2K_BAD_ALGORITHM
#define S2K_FLAG_NO_SCRYPT
#define S2K_RFC2440_SPECIFIER_LEN
void memwipe(void *mem, uint8_t byte, size_t sz)
Common functions for cryptographic routines.
int tor_memeq(const void *a, const void *b, size_t sz)
Macros to manage assertions, fatal and non-fatal.
#define tor_fragile_assert()