Пример #1
1
/* cpu and memory intensive function to transform a 80 byte buffer into a 32 byte output
   scratchpad size needs to be at least 63 + (128 * r * p) + (256 * r + 64) + (128 * r * N) bytes
 */
void scrypt_N_R_1_256_sp(const char* input, char* output, char* scratchpad, uint32_t N, uint32_t R, uint32_t len)
{
	uint8_t * B;
	uint32_t * V;
	uint32_t * XY;
	uint32_t i;

	//const uint32_t N = 1024;
	uint32_t r=R;
	const uint32_t p = 1;

	B = (uint8_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));
	XY = (uint32_t *)(B + (128 * r * p));
	V = (uint32_t *)(B + (128 * r * p) + (256 * r + 64));

	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
	PBKDF2_SHA256((const uint8_t*)input, len, (const uint8_t*)input, len, 1, B, p * 128 * r);

	/* 2: for i = 0 to p - 1 do */
	for (i = 0; i < p; i++) {
		/* 3: B_i <-- MF(B_i, N) */
		smix(&B[i * 128 * r], r, N, V, XY);
	}

	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
	PBKDF2_SHA256((const uint8_t*)input, len, B, p * 128 * r, 1, (uint8_t*)output, 32);
}
Пример #2
0
/**
 * scrypt (passwd, passwdlen, salt, saltlen, N, r, p, res, res_len):
 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
 * p, res_len) and write the result into res.  The parameters r, p, and res_len
 * must satisfy r * p < 2^30 and res_len <= (2^32 - 1) * 32.  The parameter N
 * must be a power of 2.
 *
 * Return 0 on success; or -1 on error.
 */
int scrypt (
  const uint8_t * password, size_t password_len, const uint8_t * salt, size_t salt_len,
  uint64_t N, uint32_t r, uint32_t p, uint8_t * res, size_t res_len)
{
  uint8_t * B;
  uint8_t * V;
  uint8_t * XY;
  uint32_t i;

#if SIZE_MAX > UINT32_MAX
  if (res_len > (((uint64_t)(1) << 32) - 1) * 32) {
    errno = EFBIG;
    goto err0;
  }
#endif
  if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
    errno = EFBIG;
    goto err0;
  }
  if (((N & (N - 1)) != 0) || (N == 0)) {
    errno = EINVAL;
    goto err0;
  }
  if ((r > SIZE_MAX / 128 / p) ||
#if SIZE_MAX / 256 <= UINT32_MAX
    (r > SIZE_MAX / 256) ||
#endif
    (N > SIZE_MAX / 128 / r)) {
    errno = ENOMEM;
    goto err0;
  }

  if ((B = malloc(128 * r * p)) == NULL) goto err0;
  if ((XY = malloc(256 * r)) == NULL) goto err1;
  if ((V = malloc(128 * r * N)) == NULL) goto err2;

  /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
  PBKDF2_SHA256(password, password_len, salt, salt_len, 1, B, p * 128 * r);

  /* 2: for i = 0 to p - 1 do */
  for (i = 0; i < p; i++) {
    /* 3: B_i <-- MF(B_i, N) */
    smix(&B[i * 128 * r], r, N, V, XY);
  }

  /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
  PBKDF2_SHA256(password, password_len, B, p * 128 * r, 1, res, res_len);

  free(V);
  free(XY);
  free(B);
  return (0);
err2:
  free(XY);
err1:
  free(B);
err0:
  return (-1);
}
Пример #3
0
static void scrypt(const void* input, size_t inputlen, uint32_t *res, void *scratchpad)
{
    uint32_t *V;
    uint32_t X[32];
    V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, sizeof(block_header), 1, (uint8_t *)X, 128);

    scrypt_core(X, V);

    PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)res, 32);
}
Пример #4
0
uint256 scrypt(const void* data, size_t datalen, const void* salt, size_t saltlen, void *scratchpad)
{
    unsigned int *V;
    unsigned int X[32];
    uint256 result = 0;
    V = (unsigned int *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PBKDF2_SHA256((const uint8_t*)data, datalen, (const uint8_t*)salt, saltlen, 1, (uint8_t *)X, 128);
    scrypt_core(X, V);
    PBKDF2_SHA256((const uint8_t*)data, datalen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32);

    return result;
}
Пример #5
0
uint256 scrypt_nosalt(const void* input, size_t inputlen, void *scratchpad)
{
    uint32_t *V;
    uint32_t X[32];
    uint256 result = 0;
    V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PBKDF2_SHA256((const uint8_t*)input, inputlen, (const uint8_t*)input, inputlen, 1, (uint8_t *)X, 128);
    scrypt_core(X, V);
    PBKDF2_SHA256((const uint8_t*)input, inputlen, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32);

    return result;
}
Пример #6
0
static void scrypt_2way(const void *input1, const void *input2, size_t input1len, size_t input2len, uint32_t *res1, uint32_t *res2, void *scratchpad)
{
    uint32_t *V;
    uint32_t X[32], Y[32];
    V = (uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PBKDF2_SHA256((const uint8_t*)input1, input1len, (const uint8_t*)input1, input1len, 1, (uint8_t *)X, 128);
    PBKDF2_SHA256((const uint8_t*)input2, input2len, (const uint8_t*)input2, input2len, 1, (uint8_t *)Y, 128);

    scrypt_core_2way(X, Y, V);

    PBKDF2_SHA256((const uint8_t*)input1, input1len, (uint8_t *)X, 128, 1, (uint8_t*)res1, 32);
    PBKDF2_SHA256((const uint8_t*)input2, input2len, (uint8_t *)Y, 128, 1, (uint8_t*)res2, 32);
}
Пример #7
0
uint256 scrypt_blockhash(const uint8_t* input)
{
    uint8_t scratchpad[SCRYPT_BUFFER_SIZE];
    ::uint32_t X[32];
    uint256 result = 0;

    ::uint32_t *V = (::uint32_t *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

    PBKDF2_SHA256(input, 80, input, 80, 1, (uint8_t *)X, 128);
    scrypt_core(X, V);
    PBKDF2_SHA256(input, 80, (uint8_t *)X, 128, 1, (uint8_t*)&result, 32);

    return result;
}
Пример #8
0
/**
 * proto_crypt_dhmac(K, nonce_l, nonce_r, dhmac_l, dhmac_r, decr):
 * Using the key file hash ${K}, and the local and remote nonces ${nonce_l}
 * and ${nonce_r}, compute the local and remote diffie-hellman parameter MAC
 * keys ${dhmac_l} and ${dhmac_r}.  If ${decr} is non-zero, "local" == "S"
 * and "remote" == "C"; otherwise the assignments are opposite.
 */
void
proto_crypt_dhmac(const struct proto_secret * K,
    const uint8_t nonce_l[PCRYPT_NONCE_LEN],
    const uint8_t nonce_r[PCRYPT_NONCE_LEN],
    uint8_t dhmac_l[PCRYPT_DHMAC_LEN], uint8_t dhmac_r[PCRYPT_DHMAC_LEN],
    int decr)
{
	uint8_t nonce_CS[PCRYPT_NONCE_LEN * 2];
	uint8_t dk_1[PCRYPT_DHMAC_LEN * 2];
	const uint8_t * nonce_c, * nonce_s;
	uint8_t * dhmac_c, * dhmac_s;

	/* Figure out how {c, s} maps to {l, r}. */
	nonce_c = decr ? nonce_r : nonce_l;
	dhmac_c = decr ? dhmac_r : dhmac_l;
	nonce_s = decr ? nonce_l : nonce_r;
	dhmac_s = decr ? dhmac_l : dhmac_r;

	/* Copy in nonces (in the right order). */
	memcpy(&nonce_CS[0], nonce_c, PCRYPT_NONCE_LEN);
	memcpy(&nonce_CS[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN);

	/* Compute dk_1. */
	PBKDF2_SHA256(K->K, 32, nonce_CS, PCRYPT_NONCE_LEN * 2, 1,
	    dk_1, PCRYPT_DHMAC_LEN * 2);

	/* Copy out diffie-hellman parameter MAC keys (in the right order). */
	memcpy(dhmac_c, &dk_1[0], PCRYPT_DHMAC_LEN);
	memcpy(dhmac_s, &dk_1[PCRYPT_DHMAC_LEN], PCRYPT_DHMAC_LEN);
}
Пример #9
0
void ramhog_run_iterations(const uint8_t *input, size_t input_size, uint8_t *output, size_t output_size,
                           uint32_t N, uint32_t C, uint32_t I,
                           uint64_t **scratchpads)
{
    xorshift_ctx ctx;
    uint32_t i, padIndex;
    uint64_t X;
    uint64_t finalChunks[N * 32];
    uint64_t finalSalt[32] = {N, C, I, input_size, output_size};
    
    for (padIndex=0; padIndex < N; padIndex++)
    {
        memcpy(&finalChunks[padIndex * 32], &scratchpads[padIndex][C - 1 - 32], sizeof(uint64_t) * 32);
    }
    
    xorshift_pbkdf2_seed(&ctx, input, input_size, (uint8_t *)&finalChunks[0], sizeof(uint64_t) * N);
    
    X = xorshift_next(&ctx);
    
    for (i=0; i < I - (32 - 5); i++)
    {
        X = scratchpads[(X & 0xffffffff00000000L) % N][(X & 0x00000000ffffffffL) % C] ^ xorshift_next(&ctx);
    }
    
    for (i=5; i < 32; i++)
    {
        X = scratchpads[(X & 0xffffffff00000000L) % N][(X & 0x00000000ffffffffL) % C] ^ xorshift_next(&ctx);
        finalSalt[i] = X;
    }
    
    PBKDF2_SHA256(input, input_size,
                  (uint8_t *)finalSalt, sizeof(uint64_t)*32,
                  1, (uint8_t *)output, output_size);
}
Пример #10
0
void scrypt_N_1_1_256_sp_sse2(const char *input, char *output, char *scratchpad, unsigned char Nfactor)
{
	uint8_t B[128];
	union {
		__m128i i128[8];
		uint32_t u32[32];
	} X;
	__m128i *V;
	uint32_t i, j, k, N;

	V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

	PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128);

	for (k = 0; k < 2; k++) {
		for (i = 0; i < 16; i++) {
			X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
		}
	}

        N = (1 << (Nfactor + 1));
        
	for (i = 0; i < N; i++) {
		for (k = 0; k < 8; k++)
			V[i * 8 + k] = X.i128[k];
		xor_salsa8_sse2(&X.i128[0], &X.i128[4]);
		xor_salsa8_sse2(&X.i128[4], &X.i128[0]);
	}
	for (i = 0; i < N; i++) {
		//j = 8 * (X.u32[16] & 1023);
                j = 8 * (X.u32[16] & (N-1));
		for (k = 0; k < 8; k++)
			X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]);
		xor_salsa8_sse2(&X.i128[0], &X.i128[4]);
		xor_salsa8_sse2(&X.i128[4], &X.i128[0]);
	}

	for (k = 0; k < 2; k++) {
		for (i = 0; i < 16; i++) {
			le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]);
		}
	}

	PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32);
}
Пример #11
0
static void xorshift_pbkdf2_seed(xorshift_ctx *ctx, const uint8_t *seed, size_t seedlen, const uint8_t *salt, size_t saltlen)
{
    uint64_t fullSeed[65];
    
    PBKDF2_SHA256(seed, seedlen, salt, saltlen, 128, (uint8_t *)fullSeed, sizeof(uint64_t)*65);
    
    memcpy(ctx->s, &fullSeed[0], sizeof(uint64_t)*64);
    ctx->p = (uint8_t)(fullSeed[16] & 63);
}
Пример #12
0
void scrypt_8_4_1_256_sp_sse2(const char *input, char *output, char *scratchpad)
{
	const int N=123;
	uint8_t B[128];
	union {
		__m128i i128[8];
		uint32_t u32[32];
	} X;
	__m128i *V;
	uint32_t i, j, k;

	V = (__m128i *)(((uintptr_t)(scratchpad) + 63) & ~ (uintptr_t)(63));

	PBKDF2_SHA256((const uint8_t *)input, 80, (const uint8_t *)input, 80, 1, B, 128);

	for (k = 0; k < 2; k++) {
		for (i = 0; i < 16; i++) {
			X.u32[k * 16 + i] = le32dec(&B[(k * 16 + (i * 5 % 16)) * 4]);
		}
	}

	for (i = 0; i < N; i++) {
		for (k = 0; k < 8; k++)
			V[i * 8 + k] = X.i128[k];
		xor_salsa8_sse2(&X.i128[0], &X.i128[4]);
		xor_salsa8_sse2(&X.i128[4], &X.i128[0]);
	}
	for (i = 0; i < N i++) {
		j = 8 * (X.u32[16] % (N));
		for (k = 0; k < 8; k++)
			X.i128[k] = _mm_xor_si128(X.i128[k], V[j + k]);
		xor_salsa8_sse2(&X.i128[0], &X.i128[4]);
		xor_salsa8_sse2(&X.i128[4], &X.i128[0]);
	}

	for (k = 0; k < 2; k++) {
		for (i = 0; i < 16; i++) {
			le32enc(&B[(k * 16 + (i * 5 % 16)) * 4], X.u32[k * 16 + i]);
		}
	}

	PBKDF2_SHA256((const uint8_t *)input, 80, B, 128, 1, (uint8_t *)output, 32);
}
Пример #13
0
/**
 * proto_crypt_mkkeys(K, nonce_l, nonce_r, yh_r, x, nofps, decr, eh_c, eh_s):
 * Using the protocol secret ${K}, the local and remote nonces ${nonce_l} and
 * ${nonce_r}, the remote MACed diffie-hellman handshake parameter ${yh_r},
 * and the local diffie-hellman secret ${x}, generate the keys ${eh_c} and
 * ${eh_s}.  If ${nofps} is non-zero, we are performing weak handshaking and
 * y_SC is set to 1 rather than being computed.  If ${decr} is non-zero,
 * "local" == "S" and "remote" == "C"; otherwise the assignments are opposite.
 */
int
proto_crypt_mkkeys(const struct proto_secret * K,
    const uint8_t nonce_l[PCRYPT_NONCE_LEN],
    const uint8_t nonce_r[PCRYPT_NONCE_LEN],
    const uint8_t yh_r[PCRYPT_YH_LEN], const uint8_t x[PCRYPT_X_LEN],
    int nofps, int decr,
    struct proto_keys ** eh_c, struct proto_keys ** eh_s)
{
	uint8_t nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN];
	uint8_t dk_2[128];
	const uint8_t * nonce_c, * nonce_s;

	/* Copy in nonces (in the right order). */
	nonce_c = decr ? nonce_r : nonce_l;
	nonce_s = decr ? nonce_l : nonce_r;
	memcpy(&nonce_y[0], nonce_c, PCRYPT_NONCE_LEN);
	memcpy(&nonce_y[PCRYPT_NONCE_LEN], nonce_s, PCRYPT_NONCE_LEN);

	/* Are we bypassing the diffie-hellman computation? */
	if (nofps) {
		/* We sent y_l = 1, so y_SC is also 1. */
		memset(&nonce_y[PCRYPT_NONCE_LEN * 2], 0,
		    CRYPTO_DH_KEYLEN - 1);
		nonce_y[PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN - 1] = 1;
	} else {
		/* Perform the diffie-hellman computation. */
		if (crypto_dh_compute(yh_r, x,
		    &nonce_y[PCRYPT_NONCE_LEN * 2]))
			goto err0;
	}

	/* Compute dk_2. */
	PBKDF2_SHA256(K->K, 32, nonce_y,
	    PCRYPT_NONCE_LEN * 2 + CRYPTO_DH_KEYLEN, 1, dk_2, 128);

	/* Create key structures. */
	if ((*eh_c = mkkeypair(&dk_2[0])) == NULL)
		goto err0;
	if ((*eh_s = mkkeypair(&dk_2[64])) == NULL)
		goto err1;

	/* Success! */
	return (0);

err1:
	proto_crypt_free(*eh_c);
err0:
	/* Failure! */
	return (-1);
}
/**
 * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
 * p, buflen) and write the result into buf.  The parameters r, p, and buflen
 * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
 * must be a power of 2 greater than 1.
 *
 * Return 0 on success; or -1 on error.
 */
int
crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
    uint8_t * buf, size_t buflen)
{
	void * B0, * V0, * XY0;
	uint8_t * B;
	uint32_t * V;
	uint32_t * XY;
	uint32_t i;

	/* Sanity-check parameters. */
#if SIZE_MAX > UINT32_MAX
	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
		errno = EFBIG;
		goto err0;
	}
#endif
	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
		errno = EFBIG;
		goto err0;
	}
	if (((N & (N - 1)) != 0) || (N == 0)) {
		errno = EINVAL;
		goto err0;
	}
	if ((r > SIZE_MAX / 128 / p) ||
#if SIZE_MAX / 256 <= UINT32_MAX
	    (r > (SIZE_MAX - 64) / 256) ||
#endif
	    (N > SIZE_MAX / 128 / r)) {
		errno = ENOMEM;
		goto err0;
	}

	/* Allocate memory. */
#ifdef HAVE_POSIX_MEMALIGN
	if ((errno = posix_memalign(&B0, 64, 128 * r * p)) != 0)
		goto err0;
	B = (uint8_t *)(B0);
	if ((errno = posix_memalign(&XY0, 64, 256 * r + 64)) != 0)
		goto err1;
	XY = (uint32_t *)(XY0);
#ifndef MAP_ANON
	if ((errno = posix_memalign(&V0, 64, 128 * r * N)) != 0)
		goto err2;
	V = (uint32_t *)(V0);
#endif
#else
	if ((B0 = malloc(128 * r * p + 63)) == NULL)
		goto err0;
	B = (uint8_t *)(((uintptr_t)(B0) + 63) & ~ (uintptr_t)(63));
	if ((XY0 = malloc(256 * r + 64 + 63)) == NULL)
		goto err1;
	XY = (uint32_t *)(((uintptr_t)(XY0) + 63) & ~ (uintptr_t)(63));
#ifndef MAP_ANON
	if ((V0 = malloc(128 * r * N + 63)) == NULL)
		goto err2;
	V = (uint32_t *)(((uintptr_t)(V0) + 63) & ~ (uintptr_t)(63));
#endif
#endif
#ifdef MAP_ANON
	if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
#ifdef MAP_NOCORE
	    MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
#else
	    MAP_ANON | MAP_PRIVATE,
#endif
	    -1, 0)) == MAP_FAILED)
		goto err2;
	V = (uint32_t *)(V0);
#endif

	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);

	/* 2: for i = 0 to p - 1 do */
	for (i = 0; i < p; i++) {
		/* 3: B_i <-- MF(B_i, N) */
		smix(&B[i * 128 * r], r, N, V, XY);
	}

	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);

	/* Free memory. */
#ifdef MAP_ANON
	if (munmap(V0, 128 * r * N))
		goto err2;
#else
	free(V0);
#endif
	free(XY0);
	free(B0);

	/* Success! */
	return (0);

err2:
	free(XY0);
err1:
	free(B0);
err0:
	/* Failure! */
	return (-1);
}
Пример #15
0
/**
 * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
 * p, buflen) and write the result into buf.  The parameters r, p, and buflen
 * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
 * must be a power of 2.
 *
 * Return 0 on success; or -1 on error.
 */
int scrypt(const uint8_t * passwd, size_t passwdlen,
           const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
           uint8_t * buf, size_t buflen) {
	uint8_t * B;
	uint8_t * V;
	uint8_t * XY;
	uint32_t i;

	/* Sanity-check parameters. */
#if SIZE_MAX > UINT32_MAX
	if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
		errno = EFBIG;
		goto err0;
	}
#endif
	if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
		errno = EFBIG;
		goto err0;
	}
	if (((N & (N - 1)) != 0) || (N == 0)) {
		errno = EINVAL;
		goto err0;
	}
	if ((r > SIZE_MAX / 128 / p) ||
#if SIZE_MAX / 256 <= UINT32_MAX
	    (r > SIZE_MAX / 256) ||
#endif
	    (N > SIZE_MAX / 128 / r)) {
		errno = ENOMEM;
		goto err0;
	}

	/* Allocate memory. */
	if ((B = malloc(128 * r * p)) == NULL)
		goto err0;
	if ((XY = malloc(256 * r)) == NULL)
		goto err1;
	if ((V = malloc(128 * r * N)) == NULL)
		goto err2;

	/* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
	PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);

	/* 2: for i = 0 to p - 1 do */
	for (i = 0; i < p; i++) {
		/* 3: B_i <-- MF(B_i, N) */
		smix(&B[i * 128 * r], r, N, V, XY);
	}

	/* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
	PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);

	/* Free memory. */
	free(V);
	free(XY);
	free(B);

	/* Success! */
	return (0);

err2:
	free(XY);
err1:
	free(B);
err0:
	/* Failure! */
	return (-1);
}
Пример #16
0
/**
 * crypto_scrypt(passwd, passwdlen, salt, saltlen, N, r, p, buf, buflen):
 * Compute scrypt(passwd[0 .. passwdlen - 1], salt[0 .. saltlen - 1], N, r,
 * p, buflen) and write the result into buf.  The parameters r, p, and buflen
 * must satisfy r * p < 2^30 and buflen <= (2^32 - 1) * 32.  The parameter N
 * must be a power of 2 greater than 1.
 *
 * Return 0 on success; or -1 on error.
 */
int
crypto_scrypt(const uint8_t * passwd, size_t passwdlen,
    const uint8_t * salt, size_t saltlen, uint64_t N, uint32_t r, uint32_t p,
    uint8_t * buf, size_t buflen)
{
  void * B0, * V0, * XY0;
  uint8_t * B;
  uint32_t * V;
  uint32_t * XY;
  uint32_t i;

  /* Sanity-check parameters. */
  if (buflen > (((uint64_t)(1) << 32) - 1) * 32) {
    errno = EFBIG;
    goto err0;
  }
  if ((uint64_t)(r) * (uint64_t)(p) >= (1 << 30)) {
    errno = EFBIG;
    goto err0;
  }
  if (((N & (N - 1)) != 0) || (N == 0)) {
    errno = EINVAL;
    goto err0;
  }
  if ((r > SIZE_MAX / 128 / p) ||
      (N > SIZE_MAX / 128 / r)) {
    errno = ENOMEM;
    goto err0;
  }

  /* Allocate memory. */
  B0 = folly_ext::aligned_malloc(128 * r * p, 64);
  if (!B0) {
    goto err0;
  }

  XY0 = folly_ext::aligned_malloc(256 * r + 64, 64);
  if (!XY0) {
    goto err1;
  }

  B = (uint8_t *)(B0);
  XY = (uint32_t *)(XY0);

  if ((V0 = mmap(NULL, 128 * r * N, PROT_READ | PROT_WRITE,
#ifdef MAP_NOCORE
      MAP_ANON | MAP_PRIVATE | MAP_NOCORE,
#else
      MAP_ANON | MAP_PRIVATE,
#endif
      -1, 0)) == MAP_FAILED)
    goto err2;
  V = (uint32_t *)(V0);

  /* 1: (B_0 ... B_{p-1}) <-- PBKDF2(P, S, 1, p * MFLen) */
  PBKDF2_SHA256(passwd, passwdlen, salt, saltlen, 1, B, p * 128 * r);

  /* 2: for i = 0 to p - 1 do */
  for (i = 0; i < p; i++) {
    /* 3: B_i <-- MF(B_i, N) */
    smix(&B[i * 128 * r], r, N, V, XY);
  }
  /* 5: DK <-- PBKDF2(P, B, 1, dkLen) */
  PBKDF2_SHA256(passwd, passwdlen, B, p * 128 * r, 1, buf, buflen);

  /* Free memory. */
  if (munmap(V0, 128 * r * N))
    goto err2;
  folly_ext::aligned_free(XY0);
  folly_ext::aligned_free(B0);

  /* Success! */
  return (0);

err2:
  folly_ext::aligned_free(XY0);
err1:
  folly_ext::aligned_free(B0);
err0:
  /* Failure! */
  return (-1);
}