コード例 #1
0
ファイル: proto_crypt.c プロジェクト: c0decafe/spiped
/**
 * 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);
}
コード例 #2
0
ファイル: keygen.c プロジェクト: lornix/tarsnap
static int
callback_register_challenge(void * cookie, NETPACKET_CONNECTION * NPC,
    int status, uint8_t packettype, const uint8_t * packetbuf,
    size_t packetlen)
{
	struct register_internal * C = cookie;
	uint8_t pub[CRYPTO_DH_PUBLEN];
	uint8_t priv[CRYPTO_DH_PRIVLEN];
	uint8_t K[CRYPTO_DH_KEYLEN];
	uint8_t keys[96];

	/* Handle errors. */
	if (status != NETWORK_STATUS_OK) {
		netproto_printerr(status);
		goto err0;
	}

	/*
	 * Make sure we received the right type of packet.  It is legal for
	 * the server to send back a NETPACKET_REGISTER_RESPONSE at this
	 * point; call callback_register_response to handle those.
	 */
	if (packettype == NETPACKET_REGISTER_RESPONSE)
		return (callback_register_response(cookie, NPC, status,
		    packettype, packetbuf, packetlen));
	else if (packettype != NETPACKET_REGISTER_CHALLENGE) {
		netproto_printerr(NETPROTO_STATUS_PROTERR);
		goto err0;
	}

	/* Generate DH parameters from the password and salt. */
	if (crypto_passwd_to_dh(C->passwd, packetbuf, pub, priv)) {
		warnp("Could not generate DH parameter from password");
		goto err0;
	}

	/* Compute shared key. */
	if (crypto_dh_compute(&packetbuf[32], priv, K))
		goto err0;
	if (crypto_hash_data(CRYPTO_KEY_HMAC_SHA256, K, CRYPTO_DH_KEYLEN,
	    C->register_key)) {
		warn0("Programmer error: "
		    "SHA256 should never fail");
		goto err0;
	}

	/* Export access keys. */
	if (crypto_keys_raw_export_auth(keys))
		goto err0;

	/* Send challenge response packet. */
	if (netpacket_register_cha_response(NPC, keys, C->name,
	    C->register_key, callback_register_response))
		goto err0;

	/* We've responded to a challenge. */
	C->donechallenge = 1;

	/* Success! */
	return (0);

err0:
	/* Failure! */
	return (-1);
}
コード例 #3
0
/**
 * crypto_session_init(pub, priv, nonce, mkey, encr_write, auth_write,
 *     encr_read, auth_read):
 * Compute K = ${pub}^(2^258 + ${priv}), mkey = MGF1(nonce || K, 48), and
 * return a CRYPTO_SESSION with encryption and authentication write and read
 * keys constructed from HMAC(mkey, (encr|auth)_(write|read)).
 */
CRYPTO_SESSION *
crypto_session_init(uint8_t pub[CRYPTO_DH_PUBLEN],
    uint8_t priv[CRYPTO_DH_PRIVLEN], uint8_t nonce[32], uint8_t mkey[48],
    const char * encr_write, const char * auth_write,
    const char * encr_read, const char * auth_read)
{
	struct crypto_session_internal * CS;
	uint8_t K[CRYPTO_DH_PUBLEN];
	uint8_t MGFbuf[32 + CRYPTO_DH_PUBLEN];
	uint8_t aes_write[32];
	uint8_t aes_read[32];

	/* Compute K = 2^(xy) mod p. */
	if (crypto_dh_compute(pub, priv, K))
		goto err0;

	/* Shared key is MGF1(nonce || K, 48). */
	memcpy(MGFbuf, nonce, 32);
	memcpy(MGFbuf + 32, K, CRYPTO_DH_PUBLEN);
	crypto_MGF1(MGFbuf, 32 + CRYPTO_DH_PUBLEN, mkey, 48);

	/* Allocate space for session key structure. */
	if ((CS = malloc(sizeof(struct crypto_session_internal))) == NULL)
		goto err0;

	/* Generate raw keys. */
	crypto_hash_data_key(mkey, 48,
	    (const uint8_t *)encr_write, strlen(encr_write), aes_write);
	crypto_hash_data_key(mkey, 48,
	    (const uint8_t *)auth_write, strlen(auth_write), CS->auth_write);
	crypto_hash_data_key(mkey, 48,
	    (const uint8_t *)encr_read, strlen(encr_read), aes_read);
	crypto_hash_data_key(mkey, 48,
	    (const uint8_t *)auth_read, strlen(auth_read), CS->auth_read);

	/* Expand AES keys and set up streams. */
	if (AES_set_encrypt_key(aes_write, 256, &CS->encr_write)) {
		warn0("error in AES_set_encrypt_key");
		goto err1;
	}
	if (AES_set_encrypt_key(aes_read, 256, &CS->encr_read)) {
		warn0("error in AES_set_encrypt_key");
		goto err1;
	}
	if ((CS->encr_write_stream =
	    crypto_aesctr_init(&CS->encr_write, 0)) == NULL)
		goto err1;
	if ((CS->encr_read_stream =
	    crypto_aesctr_init(&CS->encr_read, 0)) == NULL)
		goto err2;

	/* Initialize parameters. */
	CS->auth_write_nonce = CS->auth_read_nonce = 0;

	/* Success! */
	return (CS);

err2:
	crypto_aesctr_free(CS->encr_write_stream);
err1:
	free(CS);
err0:
	/* Failure! */
	return (NULL);
}