13 #define CRYPTO_S2K_PRIVATE
26 #include <openssl/evp.h>
32 #if defined(HAVE_LIBSCRYPT_H) && defined(HAVE_LIBSCRYPT_SCRYPT)
34 #include <libscrypt.h>
61 #define S2K_TYPE_RFC2440 0
62 #define S2K_TYPE_PBKDF2 1
63 #define S2K_TYPE_SCRYPT 2
65 #define PBKDF2_SPEC_LEN 17
66 #define PBKDF2_KEY_LEN 20
68 #define SCRYPT_SPEC_LEN 18
69 #define SCRYPT_KEY_LEN 32
78 case S2K_TYPE_RFC2440:
81 return PBKDF2_SPEC_LEN;
83 return SCRYPT_SPEC_LEN;
95 case S2K_TYPE_RFC2440:
118 int key_included,
int *legacy_out)
127 if (spec_and_key_len == legacy_len) {
129 return S2K_TYPE_RFC2440;
133 if (spec_and_key_len == 0)
136 type = spec_and_key[0];
147 if ((
size_t)total_len + 1 == spec_and_key_len)
167 case S2K_TYPE_RFC2440:
171 case S2K_TYPE_PBKDF2:
173 spec_out[PBKDF2_SPEC_LEN-1] = 17;
175 case S2K_TYPE_SCRYPT:
178 spec_out[SCRYPT_SPEC_LEN-2] = 12;
181 spec_out[SCRYPT_SPEC_LEN-2] = 15;
184 spec_out[SCRYPT_SPEC_LEN-1] = (3u << 4) | (1u << 0);
204 size_t secret_len,
const char *s2k_specifier)
208 size_t count, tmplen;
214 c = s2k_specifier[8];
215 count = ((uint32_t)16 + (c & 15)) << ((c >> 4) + EXPBIAS);
219 tmplen = 8+secret_len;
220 tmp = tor_malloc(tmplen);
221 memcpy(tmp,s2k_specifier,8);
222 memcpy(tmp+8,secret,secret_len);
225 if (count >= secret_len) {
235 if (key_out_len <=
sizeof(buf)) {
236 memcpy(key_out, buf, key_out_len);
239 (
const uint8_t*)s2k_specifier, 8,
240 (
const uint8_t*)
"EXPAND", 6,
241 (uint8_t*)key_out, key_out_len);
259 const uint8_t *spec,
size_t spec_len,
260 const char *secret,
size_t secret_len,
264 if (key_out_len > INT_MAX)
268 case S2K_TYPE_RFC2440:
271 return (
int)key_out_len;
273 case S2K_TYPE_PBKDF2: {
275 if (spec_len < 1 || secret_len > INT_MAX || spec_len > INT_MAX)
277 log_iters = spec[spec_len-1];
280 #ifdef ENABLE_OPENSSL
281 rv = PKCS5_PBKDF2_HMAC_SHA1(secret, (
int)secret_len,
282 spec, (
int)spec_len-1,
284 (
int)key_out_len, key_out);
287 return (
int)key_out_len;
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;
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);
305 key = PK11_PBEKeyGen(NULL ,
311 SECStatus st = PK11_ExtractKeyValue(key);
312 if (st != SECSuccess)
315 const SECItem *iptr = PK11_GetKeyData(key);
319 rv = MIN((
int)iptr->len, (
int)key_out_len);
320 memcpy(key_out, iptr->data, rv);
324 PK11_FreeSymKey(key);
326 SECOID_DestroyAlgorithmID(alg, PR_TRUE);
331 case S2K_TYPE_SCRYPT: {
333 uint8_t log_N, log_r, log_p;
338 log_N = spec[spec_len-2];
339 log_r = (spec[spec_len-1]) >> 4;
340 log_p = (spec[spec_len-1]) & 15;
343 N = ((uint64_t)1) << log_N;
346 rv = libscrypt_scrypt((
const uint8_t*)secret, secret_len,
347 spec, spec_len-2, N, r, p, key_out, key_out_len);
350 return (
int)key_out_len;
371 const uint8_t *spec,
size_t spec_len,
372 const char *secret,
size_t secret_len)
374 int legacy_format = 0;
381 if (type == S2K_TYPE_SCRYPT)
385 if (! legacy_format) {
391 secret, secret_len, type);
410 uint8_t type = S2K_TYPE_SCRYPT;
412 uint8_t type = S2K_TYPE_RFC2440;
416 type = S2K_TYPE_RFC2440;
418 type = S2K_TYPE_PBKDF2;
422 if ((
int)buf_len < spec_len + 1)
445 const char *secret,
size_t secret_len,
464 if ((
int)buf_len < key_len + spec_len)
469 secret, secret_len, type);
473 *len_out = spec_len + key_len;
487 const char *secret,
size_t secret_len)
510 tor_assert((
int)spec_and_key_len == spec_len + key_len);
512 spec_and_key, spec_len,
513 secret, secret_len, type);
517 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)
crypto_digest_t * crypto_digest_new(void)
void crypto_digest_add_bytes(crypto_digest_t *digest, const char *data, size_t len)
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()