static PK11SymKey *ikev2_prfplus(const struct prf_desc *prf_desc, PK11SymKey *key, PK11SymKey *seed, size_t required_keymat) { uint8_t count = 1; /* T1(prfplus) = prf(KEY, SEED|1) */ PK11SymKey *prfplus; { struct crypt_prf *prf = crypt_prf_init_symkey("prf+0", DBG_CRYPT, prf_desc, "key", key); crypt_prf_update_symkey("seed", prf, seed); crypt_prf_update_byte("1++", prf, count++); prfplus = crypt_prf_final(prf); } /* make a copy to keep things easy */ PK11SymKey *old_t = key_from_symkey_bytes(prfplus, 0, sizeof_symkey(prfplus)); while (sizeof_symkey(prfplus) < required_keymat) { /* Tn = prf(KEY, Tn-1|SEED|n) */ struct crypt_prf *prf = crypt_prf_init_symkey("prf+N", DBG_CRYPT, prf_desc, "key", key); crypt_prf_update_symkey("old_t", prf, old_t); crypt_prf_update_symkey("seed", prf, seed); crypt_prf_update_byte("N++", prf, count++); PK11SymKey *new_t = crypt_prf_final(prf); append_symkey_symkey(prf_desc->hasher, &prfplus, new_t); free_any_symkey("old_t[N]", &old_t); old_t = new_t; } free_any_symkey("old_t[final]", &old_t); return prfplus; }
/* * SKEYSEED = prf(Ni | Nr, g^ir) */ PK11SymKey *ikev2_ike_sa_skeyseed(const struct hash_desc *hasher, const chunk_t Ni, const chunk_t Nr, PK11SymKey *dh_secret) { struct crypt_prf *prf = crypt_prf_init("ike sa SKEYSEED", hasher, dh_secret); /* key = Ni|Nr */ crypt_prf_init_chunk("Ni", prf, Ni); crypt_prf_init_chunk("Nr", prf, Nr); /* seed = g^ir */ crypt_prf_update(prf); /* generate */ crypt_prf_update_symkey("g^ir", prf, dh_secret); return crypt_prf_final(prf); }
/* * 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); }
/* * 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); }