Esempio n. 1
0
/*
 * SKEYSEED = prf(SK_d (old), g^ir (new) | Ni | Nr)
 */
PK11SymKey *ikev2_ike_sa_rekey_skeyseed(const struct prf_desc *prf_desc,
					PK11SymKey *SK_d_old,
					PK11SymKey *new_dh_secret,
					const chunk_t Ni, const chunk_t Nr)
{
	/* key = SK_d (old) */
	struct crypt_prf *prf = crypt_prf_init_symkey("ike sa rekey skeyseed",
						      DBG_CRYPT, prf_desc,
						      "SK_d (old)", SK_d_old);
	/* seed: g^ir (new) | Ni | Nr) */
	crypt_prf_update_symkey("g^ir (new)", prf, new_dh_secret);
	crypt_prf_update_chunk("Ni", prf, Ni);
	crypt_prf_update_chunk("Nr", prf, Nr);
	/* generate */
	return crypt_prf_final(prf);
}
Esempio n. 2
0
static bool ikev2_calculate_psk_sighash(struct state *st,
					enum original_role role,
					unsigned char *idhash,
					chunk_t firstpacket,
					unsigned char *signed_octets)
{
	const chunk_t *nonce;
	const char    *nonce_name;
	const struct connection *c = st->st_connection;
	const chunk_t *pss = &empty_chunk;
	const size_t hash_len =  st->st_oakley.prf_hasher->hash_digest_len;

	if (!(c->policy & POLICY_AUTH_NULL)) {
		pss = get_preshared_secret(c);
		if (pss == NULL) {
			libreswan_log("No matching PSK found for connection:%s",
			      st->st_connection->name);
			return FALSE; /* failure: no PSK to use */
		}
		DBG(DBG_PRIVATE, DBG_dump_chunk("User PSK:", *pss));
	} else {
		/*
		 * draft-ietf-ipsecme-ikev2-null-auth-02
		 *
		 * When using the NULL Authentication Method, the
		 * content of the AUTH payload is computed using the
		 * syntax of pre-shared secret authentication,
		 * described in Section 2.15 of [RFC7296].  The values
		 * SK_pi and SK_pr are used as shared secrets for the
		 * content of the AUTH payloads generated by the
		 * initiator and the responder respectively.
		 *
		 * We have SK_pi/SK_pr as PK11SymKey in st_skey_pi_nss
		 * and st_skey_pr_nss
		 */
		passert(st->hidden_variables.st_skeyid_calculated);

		/*
		 * This is wrong as role - we need to role for THIS exchange
		 * But verify calls this routine with the role inverted, so we
		 * cannot juse st->st_state either.
		 */
		if (role == ORIGINAL_INITIATOR) {
			/* we are sending initiator, or verifying responder */
			pss = &st->st_skey_chunk_SK_pi;
		} else {
			/* we are verifying initiator, or sending responder */
			pss = &st->st_skey_chunk_SK_pr;
		}
		 DBG(DBG_PRIVATE, DBG_dump_chunk("AUTH_NULL PSK:", *pss));
	}

	/*
	 * RFC 4306 2.15:
	 * AUTH = prf(prf(Shared Secret,"Key Pad for IKEv2"), <msg octets>)
	 */

	/* calculate inner prf */
	PK11SymKey *prf_psk;
	{
		struct crypt_prf *prf =
			crypt_prf_init(("<prf-psk>"
					" = prf(<psk>,\"Key Pad for IKEv2\")"),
				       st->st_oakley.prf_hasher,
				       st->st_shared_nss/*scratch*/);
		crypt_prf_init_chunk("shared secret", prf, *pss);
		crypt_prf_update(prf);
		crypt_prf_update_bytes(psk_key_pad_str/*name*/, prf,
				       psk_key_pad_str, psk_key_pad_str_len);
		prf_psk = crypt_prf_final(prf);
	}

	/* decide nonce based on the role */
	if (role == ORIGINAL_INITIATOR) {
		/* on initiator, we need to hash responders nonce */
		nonce = &st->st_nr;
		nonce_name = "inputs to hash2 (responder nonce)";
	} else {
		nonce = &st->st_ni;
		nonce_name = "inputs to hash2 (initiator nonce)";
	}

	/* calculate outer prf */
	{
		struct crypt_prf *prf =
			crypt_prf_init(("<signed-octets>"
					" = prf(<prf-psk>, <msg octets>)"),
				       st->st_oakley.prf_hasher,
				       st->st_shared_nss /*scratch*/);
		crypt_prf_init_symkey("<prf-psk>", prf, prf_psk);
		/*
		 * For the responder, the octets to be signed start
		 * with the first octet of the first SPI in the header
		 * of the second message and end with the last octet
		 * of the last payload in the second message.
		 * Appended to this (for purposes of computing the
		 * signature) are the initiator's nonce Ni (just the
		 * value, not the payload containing it), and the
		 * value prf(SK_pr,IDr') where IDr' is the responder's
		 * ID payload excluding the fixed header.  Note that
		 * neither the nonce Ni nor the value prf(SK_pr,IDr')
		 * are transmitted.
		 */
		crypt_prf_update(prf);
		crypt_prf_update_chunk("first-packet", prf, firstpacket);
		crypt_prf_update_chunk("nonce", prf, *nonce);
		crypt_prf_update_bytes("hash", prf, idhash, hash_len);
		crypt_prf_final_bytes(prf, signed_octets, hash_len);
	}
	free_any_symkey("<prf-psk>", &prf_psk);

	DBG(DBG_CRYPT,
	    DBG_dump_chunk("inputs to hash1 (first packet)", firstpacket);
	    DBG_dump_chunk(nonce_name, *nonce);
	    DBG_dump("idhash", idhash, hash_len));

	return TRUE;
}