/* * 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); }
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, ¶m, 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, ¶m, 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; }