Example #1
0
/*
 * SKEYSEED = prf(Ni | Nr, g^ir)
 */
PK11SymKey *ikev2_ike_sa_skeyseed(const struct prf_desc *prf_desc,
				  const chunk_t Ni, const chunk_t Nr,
				  PK11SymKey *dh_secret)
{
	/* key = Ni|Nr */
	chunk_t key = concat_chunk_chunk("key = Ni|Nr", Ni, Nr);
	struct crypt_prf *prf = crypt_prf_init_chunk("ike sa SKEYSEED",
						     DBG_CRYPT,
						     prf_desc,
						     "Ni|Nr", key);
	freeanychunk(key);
	/* seed = g^ir */
	crypt_prf_update_symkey("g^ir", prf, dh_secret);
	/* generate */
	return crypt_prf_final(prf);
}
Example #2
0
static bool ike_alg_nss_gcm(const struct encrypt_desc *alg,
			    u_int8_t *salt, size_t salt_size,
			    u_int8_t *wire_iv, size_t wire_iv_size,
			    u_int8_t *aad, size_t aad_size,
			    u_int8_t *text_and_tag,
			    size_t text_size, size_t tag_size,
			    PK11SymKey *sym_key, bool enc)
{
	/* See pk11gcmtest.c */
	bool ok = TRUE;

	chunk_t salt_chunk = {
		.ptr = salt,
		.len = salt_size,
	};
	chunk_t wire_iv_chunk = {
		.ptr = wire_iv,
		.len = wire_iv_size,
	};
	chunk_t iv = concat_chunk_chunk("IV", salt_chunk, wire_iv_chunk);

	CK_GCM_PARAMS gcm_params;
	gcm_params.pIv = iv.ptr;
	gcm_params.ulIvLen = iv.len;
	gcm_params.pAAD = aad;
	gcm_params.ulAADLen = aad_size;
	gcm_params.ulTagBits = tag_size * 8;

	SECItem param;
	param.type = siBuffer;
	param.data = (void*)&gcm_params;
	param.len = sizeof gcm_params;

	/* Output buffer for transformed data.  */
	size_t text_and_tag_size = text_size + tag_size;
	u_int8_t *out_buf = PR_Malloc(text_and_tag_size);
	unsigned int out_len = 0;

	if (enc) {
		SECStatus rv = PK11_Encrypt(sym_key, alg->common.nss_mechanism,
					    &param, out_buf, &out_len,
					    text_and_tag_size,
					    text_and_tag, text_size);
		if (rv != SECSuccess) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Encrypt failure (err %d)", PR_GetError());
			ok = FALSE;
		} else if (out_len != text_and_tag_size) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Encrypt output length of %u not the expected %zd",
			       out_len, text_and_tag_size);
			ok = FALSE;
		}
	} else {
		SECStatus rv = PK11_Decrypt(sym_key, CKM_AES_GCM, &param,
					    out_buf, &out_len, text_and_tag_size,
					    text_and_tag, text_and_tag_size);
		if (rv != SECSuccess) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Decrypt failure (err %d)", PR_GetError());
			ok = FALSE;
		} else if (out_len != text_size) {
			loglog(RC_LOG_SERIOUS,
			       "do_aes_gcm: PK11_Decrypt output length of %u not the expected %zd",
			       out_len, text_size);
			ok = FALSE;
		}
	}

	memcpy(text_and_tag, out_buf, out_len);
	PR_Free(out_buf);
	freeanychunk(iv);

	return ok;
}