Esempio n. 1
0
static void gcm_run_test(void)
{
	print_number("Count", NULL, count);
	print_symkey("Key", NULL, key, 0);
	print_chunk("IV", NULL, iv, 0);
	print_chunk("CT", NULL, ct, 0);
	print_chunk("AAD", NULL, aad, 0);
	print_chunk("Tag", NULL, tag, 0);
	const struct encrypt_desc *gcm_alg = lookup_by_taglen();
	if (gcm_alg == NULL) {
		fprintf(stderr, "taglen %lu not supported\n",
			taglen);
		return;
	}
	PK11SymKey *gcm_key = encrypt_key_from_symkey_bytes("GCM key", gcm_alg,
							    0, sizeof_symkey(key),
							    key);

	chunk_t text_and_tag = clone_chunk_chunk(ct, tag, "text-and-tag");

	bool result = gcm_alg->encrypt_ops
		->do_aead(gcm_alg,
			  salt.ptr, salt.len,
			  iv.ptr, iv.len,
			  aad.ptr, aad.len,
			  text_and_tag.ptr,
			  ct.len, tag.len,
			  gcm_key,
			  FALSE/*encrypt*/);
	if (result) {
		/* plain text */
		chunk_t pt = {
			.ptr = text_and_tag.ptr,
			.len = ct.len,
		};
		print_chunk("PT", NULL, pt, 0);
	} else {
		print_line("FAIL");
	}
	release_symkey(__func__, "GCM-key", &gcm_key);
	freeanychunk(text_and_tag);
}
Esempio n. 2
0
/* MUST BE THREAD-SAFE */
static void calc_skeyseed_v2(struct pcr_skeyid_q *skq,
			     PK11SymKey *shared,
			     const size_t key_size,
			     const size_t salt_size,
			     PK11SymKey **skeyseed_out,
			     PK11SymKey **SK_d_out,
			     PK11SymKey **SK_ai_out,
			     PK11SymKey **SK_ar_out,
			     PK11SymKey **SK_ei_out,
			     PK11SymKey **SK_er_out,
			     PK11SymKey **SK_pi_out,
			     PK11SymKey **SK_pr_out,
			     chunk_t *initiator_salt_out,
			     chunk_t *responder_salt_out,
			     chunk_t *chunk_SK_pi_out,
			     chunk_t *chunk_SK_pr_out)
{
	DBG(DBG_CRYPT, DBG_log("NSS: Started key computation"));

	PK11SymKey
		*skeyseed_k,
		*SK_d_k,
		*SK_ai_k,
		*SK_ar_k,
		*SK_ei_k,
		*SK_er_k,
		*SK_pi_k,
		*SK_pr_k;
	chunk_t initiator_salt;
	chunk_t responder_salt;
	chunk_t chunk_SK_pi;
	chunk_t chunk_SK_pr;

	/* this doesn't take any memory, it's just moving pointers around */
	chunk_t ni;
	chunk_t nr;
	chunk_t spii;
	chunk_t spir;
	setchunk_from_wire(ni, skq, &skq->ni);
	setchunk_from_wire(nr, skq, &skq->nr);
	setchunk_from_wire(spii, skq, &skq->icookie);
	setchunk_from_wire(spir, skq, &skq->rcookie);

	DBG(DBG_CONTROLMORE,
	    DBG_log("calculating skeyseed using prf=%s integ=%s cipherkey-size=%zu salt-size=%zu",
		    enum_name(&ikev2_trans_type_prf_names, skq->prf_hash),
		    enum_name(&ikev2_trans_type_integ_names, skq->integ_hash),
		    key_size, salt_size));

	const struct hash_desc *prf_hasher = (struct hash_desc *)
		ikev2_alg_find(IKE_ALG_HASH, skq->prf_hash);
	passert(prf_hasher != NULL);

	const struct encrypt_desc *encrypter = skq->encrypter;
	passert(encrypter != NULL);

	/* generate SKEYSEED from key=(Ni|Nr), hash of shared */
	skeyseed_k = ikev2_ike_sa_skeyseed(prf_hasher, ni, nr, shared);
	passert(skeyseed_k != NULL);
	
	/* now we have to generate the keys for everything */

	/* need to know how many bits to generate */
	/* SK_d needs PRF hasher key bytes */
	/* SK_p needs PRF hasher*2 key bytes */
	/* SK_e needs key_size*2 key bytes */
	/* ..._salt needs salt_size*2 bytes */
	/* SK_a needs integ's key size*2 bytes */

	int skd_bytes = prf_hasher->hash_key_size;
	int skp_bytes = prf_hasher->hash_key_size;
	const struct hash_desc *integ_hasher =
		(struct hash_desc *)ikev2_alg_find(IKE_ALG_INTEG, skq->integ_hash);
	int integ_size = integ_hasher != NULL ? integ_hasher->hash_key_size : 0;
	size_t total_keysize = skd_bytes + 2*skp_bytes + 2*key_size + 2*salt_size + 2*integ_size;
	PK11SymKey *finalkey = ikev2_ike_sa_keymat(prf_hasher, skeyseed_k,
						   ni, nr, spii, spir,
						   total_keysize);

	size_t next_byte = 0;

	SK_d_k = key_from_symkey_bytes(finalkey, next_byte, skd_bytes);
	next_byte += skd_bytes;

	SK_ai_k = key_from_symkey_bytes(finalkey, next_byte, integ_size);
	next_byte += integ_size;

	SK_ar_k = key_from_symkey_bytes(finalkey, next_byte, integ_size);
	next_byte += integ_size;

	/* The encryption key and salt are extracted together. */
	SK_ei_k = encrypt_key_from_symkey_bytes(finalkey, encrypter,
						next_byte, key_size);
	next_byte += key_size;
	PK11SymKey *initiator_salt_key = key_from_symkey_bytes(finalkey, next_byte,
							       salt_size);
	initiator_salt = chunk_from_symkey("initiator salt", initiator_salt_key);
	free_any_symkey("initiator salt key:", &initiator_salt_key);
						
	next_byte += salt_size;

	/* The encryption key and salt are extracted together. */	
	SK_er_k = encrypt_key_from_symkey_bytes(finalkey, encrypter,
						next_byte, key_size);
	next_byte += key_size;
	PK11SymKey *responder_salt_key = key_from_symkey_bytes(finalkey, next_byte,
							       salt_size);
	responder_salt = chunk_from_symkey("responder salt", responder_salt_key);
	free_any_symkey("responder salt key:", &responder_salt_key);
	next_byte += salt_size;

	SK_pi_k = key_from_symkey_bytes(finalkey, next_byte, skp_bytes);
	/* store copy of SK_pi_k for later use in authnull */
	chunk_SK_pi = chunk_from_symkey("chunk_SK_pi", SK_pi_k);
	next_byte += skp_bytes;

	SK_pr_k = key_from_symkey_bytes(finalkey, next_byte, skp_bytes);
	/* store copy of SK_pr_k for later use in authnull */
	chunk_SK_pr = chunk_from_symkey("chunk_SK_pr", SK_pr_k);
	next_byte += skp_bytes;	/* next_byte not subsequently used */

	DBG(DBG_CRYPT,
	    DBG_log("NSS ikev2: finished computing individual keys for IKEv2 SA"));
	free_any_symkey("finalkey", &finalkey);

	*skeyseed_out = skeyseed_k;
	*SK_d_out = SK_d_k;
	*SK_ai_out = SK_ai_k;
	*SK_ar_out = SK_ar_k;
	*SK_ei_out = SK_ei_k;
	*SK_er_out = SK_er_k;
	*SK_pi_out = SK_pi_k;
	*SK_pr_out = SK_pr_k;
	*initiator_salt_out = initiator_salt;
	*responder_salt_out = responder_salt;
	*chunk_SK_pi_out = chunk_SK_pi;
	*chunk_SK_pr_out = chunk_SK_pr;

	DBG(DBG_CRYPT,
	    DBG_log("calc_skeyseed_v2 pointers: shared %p, skeyseed %p, SK_d %p, SK_ai %p, SK_ar %p, SK_ei %p, SK_er %p, SK_pi %p, SK_pr %p",
		    shared, skeyseed_k, SK_d_k, SK_ai_k, SK_ar_k, SK_ei_k, SK_er_k, SK_pi_k, SK_pr_k);
	    DBG_dump_chunk("calc_skeyseed_v2 initiator salt", initiator_salt);
	    DBG_dump_chunk("calc_skeyseed_v2 responder salt", responder_salt);
	    DBG_dump_chunk("calc_skeyseed_v2 SK_pi", chunk_SK_pi);
	    DBG_dump_chunk("calc_skeyseed_v2 SK_pr", chunk_SK_pr));
}