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; }
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); }