int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, unsigned long long outlen, const char * const passwd, unsigned long long passwdlen, const unsigned char * const salt, unsigned long long opslimit, size_t memlimit) { uint32_t N_log2; uint32_t p; uint32_t r; memset(out, 0, outlen); if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) { errno = EFBIG; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t) (1) << N_log2, r, p, out, (size_t) outlen); }
int crypto_pwhash_scryptsalsa208sha256(unsigned char * const out, unsigned long long outlen, const char * const passwd, unsigned long long passwdlen, const unsigned char * const salt, unsigned long long opslimit, size_t memlimit) { //fprintf(stderr, "Doing that dirty thang!!!!\n"); uint32_t N_log2; uint32_t p; uint32_t r; memset(out, 0, outlen); if (passwdlen > SIZE_MAX || outlen > SIZE_MAX) { errno = EFBIG; return -1; } if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { errno = EINVAL; return -1; } return crypto_pwhash_scryptsalsa208sha256_ll((const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) salt, crypto_pwhash_scryptsalsa208sha256_SALTBYTES, (uint64_t) (1) << N_log2, r, p, out, (size_t) outlen); }
int calibrate(size_t maxmem, double maxmemfrac, double maxtime, uint64_t * n, uint32_t * r, uint32_t * p) { int logN = 0; int result = pickparams( maxmem, maxmemfrac, maxtime, & logN, r, p ); if (result == 0) { *n = (uint64_t)(1) << logN; } return result; }
static int scryptenc_setup(uint8_t header[96], uint8_t dk[64], const uint8_t * passwd, size_t passwdlen, size_t maxmem, double maxmemfrac, double maxtime) { uint8_t salt[32]; uint8_t hbuf[32]; int logN; uint64_t N; uint32_t r; uint32_t p; SHA256_CTX ctx; uint8_t * key_hmac = &dk[32]; HMAC_SHA256_CTX hctx; int rc; /* Pick values for N, r, p. */ if ((rc = pickparams(maxmem, maxmemfrac, maxtime, &logN, &r, &p)) != 0) return (rc); N = (uint64_t)(1) << logN; /* Get some salt. */ if (crypto_entropy_read(salt, 32)) return (4); /* Generate the derived keys. */ if (crypto_scrypt(passwd, passwdlen, salt, 32, N, r, p, dk, 64)) return (3); /* Construct the file header. */ memcpy(header, "scrypt", 6); header[6] = 0; header[7] = logN; be32enc(&header[8], r); be32enc(&header[12], p); memcpy(&header[16], salt, 32); /* Add header checksum. */ SHA256_Init(&ctx); SHA256_Update(&ctx, header, 48); SHA256_Final(hbuf, &ctx); memcpy(&header[48], hbuf, 16); /* Add header signature (used for verifying password). */ HMAC_SHA256_Init(&hctx, key_hmac, 32); HMAC_SHA256_Update(&hctx, header, 64); HMAC_SHA256_Final(hbuf, &hctx); memcpy(&header[64], hbuf, 32); /* Success! */ return (0); }
int crypto_pwhash_scryptsalsa208sha256_str(char out[crypto_pwhash_scryptsalsa208sha256_STRBYTES], const char * const passwd, unsigned long long passwdlen, unsigned long long opslimit, size_t memlimit) { uint8_t salt[crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES]; char setting[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U]; escrypt_local_t escrypt_local; uint32_t N_log2; uint32_t p; uint32_t r; memset(out, 0, crypto_pwhash_scryptsalsa208sha256_STRBYTES); if (passwdlen > SIZE_MAX) { errno = EFBIG; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } if (pickparams(opslimit, memlimit, &N_log2, &p, &r) != 0) { errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } randombytes_buf(salt, sizeof salt); if (escrypt_gensalt_r(N_log2, r, p, salt, sizeof salt, (uint8_t *) setting, sizeof setting) == NULL) { errno = EINVAL; /* LCOV_EXCL_LINE */ return -1; /* LCOV_EXCL_LINE */ } if (escrypt_init_local(&escrypt_local) != 0) { return -1; /* LCOV_EXCL_LINE */ } if (escrypt_r(&escrypt_local, (const uint8_t *) passwd, (size_t) passwdlen, (const uint8_t *) setting, (uint8_t *) out, crypto_pwhash_scryptsalsa208sha256_STRBYTES) == NULL) { /* LCOV_EXCL_START */ escrypt_free_local(&escrypt_local); errno = EINVAL; return -1; /* LCOV_EXCL_STOP */ } escrypt_free_local(&escrypt_local); (void) sizeof (int[SETTING_SIZE(crypto_pwhash_scryptsalsa208sha256_STRSALTBYTES) == crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES ? 1 : -1]); (void) sizeof (int[crypto_pwhash_scryptsalsa208sha256_STRSETTINGBYTES + 1U + crypto_pwhash_scryptsalsa208sha256_STRHASHBYTES_ENCODED + 1U == crypto_pwhash_scryptsalsa208sha256_STRBYTES ? 1 : -1]); return 0; }
int salsa20_init(salsa20_ctx_t *ctx, uchar_t *salt, int saltlen, uchar_t *pwd, int pwd_len, uchar_t *nonce, int enc) { struct timespec tp; uint64_t tv; uchar_t num[25]; uchar_t IV[32]; uchar_t *key = ctx->pkey; #ifndef _USE_PBK int logN; uint32_t r, p; uint64_t N; if (XSALSA20_CRYPTO_NONCEBYTES % 8) { log_msg(LOG_ERR, 0, "XSALSA20_CRYPTO_NONCEBYTES is not a multiple of 8!\n"); return (-1); } pickparams(&logN, &r, &p); N = (uint64_t)(1) << logN; if (crypto_scrypt(pwd, pwd_len, salt, saltlen, N, r, p, key, ctx->keylen)) { log_msg(LOG_ERR, 0, "Scrypt failed\n"); return (-1); } #else rv = PKCS5_PBKDF2_HMAC(pwd, pwd_len, salt, saltlen, PBE_ROUNDS, EVP_sha256(), ctx->keylen, key); if (rv != ctx->keylen) { log_msg(LOG_ERR, 0, "Key size is %d bytes - should be %d bits\n", i, ctx->keylen); return (-1); } #endif /* * Copy the key. XSalsa20 core cipher always uses a 256-bit key. If we are using a * 128-bit key then the key value is repeated twice to form a 256-bit value. * This approach is based on the Salsa20 code submitted to eSTREAM. See the function * ECRYPT_keysetup() in the Salsa20 submission: * http://www.ecrypt.eu.org/stream/svn/viewcvs.cgi/ecrypt/trunk/submissions/salsa20/full/ref/salsa20.c?rev=161&view=auto * * The input values corresponding to a 256-bit key contain repeated values if key * length is 128-bit. */ memcpy(ctx->key, key, ctx->keylen); if (ctx->keylen < XSALSA20_CRYPTO_KEYBYTES) { uchar_t *k; k = ctx->key + ctx->keylen; memcpy(k, key, XSALSA20_CRYPTO_KEYBYTES - ctx->keylen); } if (enc) { int i; uint64_t *n, *n1; // Derive 192-bit nonce if (RAND_status() != 1 || RAND_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 1) { if (geturandom_bytes(IV, XSALSA20_CRYPTO_NONCEBYTES) != 0) { if (clock_gettime(CLOCK_MONOTONIC, &tp) == -1) { time((time_t *)&tv); } else { tv = tp.tv_sec * 1000UL + tp.tv_nsec; } sprintf((char *)num, "%" PRIu64, tv); PKCS5_PBKDF2_HMAC((const char *)num, strlen((char *)num), salt, saltlen, PBE_ROUNDS, EVP_sha256(), 32, IV); } } n = (uint64_t *)IV; n1 = (uint64_t *)(ctx->nonce); for (i = 0; i < XSALSA20_CRYPTO_NONCEBYTES/8; i++) { *n1 = LE64(*n); n++; n1++; } // Nullify stack components memset(num, 0, 25); memset(IV, 0, 32); memset(&tp, 0, sizeof (tp)); tv = 0; } else { memcpy(ctx->nonce, nonce, XSALSA20_CRYPTO_NONCEBYTES); memset(nonce, 0, XSALSA20_CRYPTO_NONCEBYTES); } return (0); }