Exemplo n.º 1
0
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);
}
Exemplo n.º 2
0
/**
 * crypto_dh_generate(pub, priv):
 * Generate a 256-bit private key ${priv}, and compute ${pub} equal to
 * 2^(2^258 + ${priv}) mod p where p is the Diffie-Hellman group #14 modulus.
 * Both values are stored as big-endian integers.
 */
int
crypto_dh_generate(uint8_t pub[CRYPTO_DH_PUBLEN],
    uint8_t priv[CRYPTO_DH_PRIVLEN])
{

	/* Generate a random private key. */
	if (crypto_entropy_read(priv, CRYPTO_DH_PRIVLEN))
		goto err0;

	/* Compute the public key. */
	if (crypto_dh_generate_pub(pub, priv))
		goto err0;

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Exemplo n.º 3
0
/**
 * crypto_keys_subr_generate_HMAC(key):
 * Generate an HMAC key.
 */
int
crypto_keys_subr_generate_HMAC(struct crypto_hmac_key ** key)
{

	/* Free any existing key. */
	if (*key != NULL) {
		free((*key)->key);
		free(*key);
	}

	/* Allocate memory. */
	if ((*key = malloc(sizeof(struct crypto_hmac_key))) == NULL)
		goto err0;
	if (((*key)->key = malloc(32)) == NULL)
		goto err1;

	/* Store key length. */
	(*key)->len = 32;

	/* Generate key. */
	if (crypto_entropy_read((*key)->key, 32)) {
		warnp("Could not obtain sufficient entropy");
		goto err2;
	}

	/* Success! */
	return (0);

err2:
	free((*key)->key);
err1:
	free(*key);
err0:
	/* Failure! */
	return (-1);
}
Exemplo n.º 4
0
/**
 * blinded_modexp(r, a, priv):
 * Compute ${r} = ${a}^(2^258 + ${priv}), where ${r} and ${priv} are treated
 * as big-endian integers; and avoid leaking timing data in this process.
 */
static int
blinded_modexp(uint8_t r[CRYPTO_DH_PUBLEN], BIGNUM * a,
    const uint8_t priv[CRYPTO_DH_PRIVLEN])
{
	BIGNUM * two_exp_256_bn;
	BIGNUM * priv_bn;
	uint8_t blinding[CRYPTO_DH_PRIVLEN];
	BIGNUM * blinding_bn;
	BIGNUM * priv_blinded;
	BIGNUM * m_bn;
	BN_CTX * ctx;
	BIGNUM * r1;
	BIGNUM * r2;
	size_t rlen;

	/* Construct 2^256 in BN representation. */
	if ((two_exp_256_bn = BN_bin2bn(two_exp_256, 33, NULL)) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err0;
	}

	/* Construct 2^258 + ${priv} in BN representation. */
	if ((priv_bn = BN_bin2bn(priv, CRYPTO_DH_PRIVLEN, NULL)) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err1;
	}
	if ((!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
	    (!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
	    (!BN_add(priv_bn, priv_bn, two_exp_256_bn)) ||
	    (!BN_add(priv_bn, priv_bn, two_exp_256_bn))) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err2;
	}

	/* Generate blinding exponent. */
	if (crypto_entropy_read(blinding, CRYPTO_DH_PRIVLEN))
		goto err2;
	if ((blinding_bn = BN_bin2bn(blinding,
	    CRYPTO_DH_PRIVLEN, NULL)) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err2;
	}
	if (!BN_add(blinding_bn, blinding_bn, two_exp_256_bn)) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err3;
	}

	/* Generate blinded exponent. */
	if ((priv_blinded = BN_new()) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err3;
	}
	if (!BN_sub(priv_blinded, priv_bn, blinding_bn)) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err4;
	}

	/* Construct group #14 modulus in BN representation. */
	if ((m_bn = BN_bin2bn(crypto_dh_group14, 256, NULL)) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err4;
	}

	/* Allocate BN context. */
	if ((ctx = BN_CTX_new()) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err5;
	}

	/* Allocate space for storing results of exponentiations. */
	if ((r1 = BN_new()) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err6;
	}
	if ((r2 = BN_new()) == NULL) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err7;
	}

	/* Perform modular exponentiations. */
	if (!BN_mod_exp(r1, a, blinding_bn, m_bn, ctx)) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err8;
	}
	if (!BN_mod_exp(r2, a, priv_blinded, m_bn, ctx)) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err8;
	}

	/* Compute final result and export to big-endian integer format. */
	if (!BN_mod_mul(r1, r1, r2, m_bn, ctx)) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err8;
	}
	rlen = BN_num_bytes(r1);
	if (rlen > CRYPTO_DH_PUBLEN) {
		warn0("Exponent result too large!");
		goto err8;
	}
	memset(r, 0, CRYPTO_DH_PUBLEN - rlen);
	BN_bn2bin(r1, r + CRYPTO_DH_PUBLEN - rlen);

	/* Free space allocated by BN_new. */
	BN_clear_free(r2);
	BN_clear_free(r1);

	/* Free context allocated by BN_CTX_new. */
	BN_CTX_free(ctx);

	/* Free space allocated by BN_bin2bn. */
	BN_free(m_bn);

	/* Free space allocated by BN_new. */
	BN_clear_free(priv_blinded);

	/* Free space allocated by BN_bin2bn. */
	BN_clear_free(blinding_bn);
	BN_clear_free(priv_bn);
	BN_free(two_exp_256_bn);

	/* Success! */
	return (0);

err8:
	BN_clear_free(r2);
err7:
	BN_clear_free(r1);
err6:
	BN_CTX_free(ctx);
err5:
	BN_free(m_bn);
err4:
	BN_clear_free(priv_blinded);
err3:
	BN_clear_free(blinding_bn);
err2:
	BN_clear_free(priv_bn);
err1:
	BN_free(two_exp_256_bn);
err0:
	/* Failure! */
	return (-1);
}
Exemplo n.º 5
0
/**
 * crypto_rsa_sign(key, data, len, sig, siglen):
 * Sign the provided data with the specified key, writing the signature
 * into ${sig}.
 */
int
crypto_rsa_sign(int key, const uint8_t * data, size_t len,
    uint8_t * sig, size_t siglen)
{
	RSA * rsa;	/* RSA key used for signing. */
	uint8_t mHash[32];
	uint8_t salt[32];
	uint8_t Mprime[72];
	uint8_t H[32];
	uint8_t DB[223];
	uint8_t dbMask[223];
	uint8_t maskedDB[223];
	uint8_t EM[256];
	size_t i;

	/* Find the required key. */
	if ((rsa = crypto_keys_lookup_RSA(key)) == NULL)
		goto err0;

	/* Make sure the key and signature buffer are the correct size. */
	if (!crypto_compat_RSA_valid_size(rsa)) {
		warn0("RSA key is incorrect size");
		goto err0;
	}
	if (siglen != 256) {
		warn0("Programmer error: "
		    "signature buffer is incorrect length");
		goto err0;
	}

	/* Generate mHash as specified in EMSA-PSS-ENCODE from RFC 3447. */
	if (crypto_hash_data(CRYPTO_KEY_HMAC_SHA256, data, len, mHash)) {
		warn0("Programmer error: "
		    "SHA256 should never fail");
		goto err0;
	}

	/* Generate random salt. */
	if (crypto_entropy_read(salt, 32)) {
		warnp("Could not obtain sufficient entropy");
		goto err0;
	}

	/* Construct M'. */
	memset(Mprime, 0, 8);
	memcpy(Mprime + 8, mHash, 32);
	memcpy(Mprime + 40, salt, 32);

	/* Construct H. */
	if (crypto_hash_data(CRYPTO_KEY_HMAC_SHA256, Mprime, 72, H)) {
		warn0("Programmer error: "
		    "SHA256 should never fail");
		goto err0;
	}

	/* Construct DB. */
	memset(DB, 0, 190);
	memset(DB + 190, 1, 1);
	memcpy(DB + 191, salt, 32);

	/* Construct dbMask and maskedDB. */
	crypto_MGF1(H, 32, dbMask, 223);
	for (i = 0; i < 223; i++)
		maskedDB[i] = DB[i] ^ dbMask[i];
	maskedDB[0] &= 0x7f;

	/* Construct EM. */
	memcpy(EM, maskedDB, 223);
	memcpy(EM + 223, H, 32);
	memset(EM + 255, 0xbc, 1);

	/* Convert EM to a signature, via RSA. */
	if (RSA_private_encrypt(256, EM, sig, rsa, RSA_NO_PADDING) != 256) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err0;
	}

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
Exemplo n.º 6
0
/**
 * crypto_rsa_encrypt(key, data, len, out, outlen):
 * Encrypt the provided data with the specified key, writing the ciphertext
 * into ${out} (of length ${outlen}).
 */
int
crypto_rsa_encrypt(int key, const uint8_t * data, size_t len,
    uint8_t * out, size_t outlen)
{
	RSA * rsa;
	uint8_t lHash[32];
	uint8_t DB[223];
	uint8_t seed[32];
	uint8_t dbMask[223];
	uint8_t maskedDB[223];
	uint8_t seedMask[32];
	uint8_t maskedSeed[32];
	uint8_t EM[256];
	size_t i;

	/* Find the required key. */
	if ((rsa = crypto_keys_lookup_RSA(key)) == NULL)
		goto err0;

	/* Make sure the key and ciphertext buffer are the correct size. */
	if (!crypto_compat_RSA_valid_size(rsa)) {
		warn0("RSA key is incorrect size");
		goto err0;
	}
	if (outlen != 256) {
		warn0("Programmer error: "
		    "ciphertext buffer is incorrect length");
		goto err0;
	}

	/* Make sure the input is not too long. */
	if (len > 190) {
		warn0("Programmer error: "
		   "input to crypto_rsa_encrypt is too long");
		goto err0;
	}

	/* Construct lHash as specified in RSAES-OAEP-ENCRYPT in RFC 3447. */
	if (crypto_hash_data(CRYPTO_KEY_HMAC_SHA256, NULL, 0, lHash)) {
		warn0("Programmer error: "
		    "SHA256 should never fail");
		goto err0;
	}

	/* Construct DB. */
	memcpy(DB, lHash, 32);
	memset(DB + 32, 0, 190 - len);
	memset(DB + 222 - len, 1, 1);
	memcpy(DB + 223 - len, data, len);

	/* Generate random seed. */
	if (crypto_entropy_read(seed, 32)) {
		warnp("Could not obtain sufficient entropy");
		goto err0;
	}

	/* Construct dbMask and maskedDB. */
	crypto_MGF1(seed, 32, dbMask, 223);
	for (i = 0; i < 223; i++)
		maskedDB[i] = DB[i] ^ dbMask[i];

	/* Construct seedMask and maskedSeed. */
	crypto_MGF1(maskedDB, 223, seedMask, 32);
	for (i = 0; i < 32; i++)
		maskedSeed[i] = seed[i] ^ seedMask[i];

	/* Construct EM. */
	memset(EM, 0, 1);
	memcpy(EM + 1, maskedSeed, 32);
	memcpy(EM + 33, maskedDB, 223);

	/* Convert EM to ciphertext, via RSA. */
	if (RSA_public_encrypt(256, EM, out, rsa, RSA_NO_PADDING) != 256) {
		warn0("%s", ERR_error_string(ERR_get_error(), NULL));
		goto err0;
	}

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}