/* * First 64 bytes of the key description is key name in EBCDIC CP 500. * Convert it to ASCII for displaying in /proc/keys.
*/
strscpy(ascii, key->description);
EBCASC_500(ascii, VC_NAME_LEN_BYTES);
seq_puts(m, ascii);
seq_puts(m, &key->description[VC_NAME_LEN_BYTES]); if (key_is_positive(key))
seq_printf(m, ": %u", key->datalen);
}
/* * Certificate store key type takes over properties of * user key but cannot be updated.
*/ staticstruct key_type key_type_cert_store_key = {
.name = CERT_STORE_KEY_TYPE_NAME,
.preparse = user_preparse,
.free_preparse = user_free_preparse,
.instantiate = generic_key_instantiate,
.revoke = user_revoke,
.destroy = user_destroy,
.describe = cert_store_key_describe,
.read = user_read,
};
pr_dbf_msg("SHA256 hash of received certificate does not match");
debug_text_event(cert_store_hexdump, 3, "VCE hash:");
debug_event(cert_store_hexdump, 3, vce_hash, SHA256_DIGEST_SIZE);
debug_text_event(cert_store_hexdump, 3, "Calculated hash:");
debug_event(cert_store_hexdump, 3, hash, SHA256_DIGEST_SIZE);
return -EINVAL;
}
staticint check_certificate_valid(conststruct vce *vce)
{ if (!(vce->vce_hdr.flags & VCE_FLAGS_VALID_MASK)) {
pr_dbf_msg("Certificate entry is invalid"); return -EINVAL;
} if (vce->vce_hdr.vc_format != 1) {
pr_dbf_msg("Certificate format is not supported"); return -EINVAL;
} if (vce->vce_hdr.vc_hash_type != 1) {
pr_dbf_msg("Hash type is not supported"); return -EINVAL;
}
cs_keyring = find_cs_keyring(); if (!cs_keyring) return;
pr_dbf_msg("Found cert_store keyring. Purging..."); /* * Remove cert_store_key_type in case invalidation * of old cert_store keys failed (= severe error).
*/ if (invalidate_keyring_keys(cs_keyring))
unregister_key_type(&key_type_cert_store_key);
/* * In case a previous clean-up ran into an * error and unregistered key type.
*/
register_key_type(&key_type_cert_store_key);
return cs_keyring;
}
/* * Allocate memory and create key description in format * [key name in EBCDIC]:[VCE index]:[CS token]. * Return a pointer to key description or NULL if memory * allocation failed. Memory should be freed by caller.
*/ staticchar *get_key_description(struct vcssb *vcssb, conststruct vce *vce)
{
size_t len, name_len;
u32 cs_token; char *desc;
/* * Create a key of type "cert_store_key" using the data from VCE for key * payload and key description. Link the key to "cert_store" keyring.
*/ staticint create_key_from_vce(struct vcssb *vcssb, struct vce *vce, struct key *keyring)
{
key_ref_t newkey; char *desc; int rc;
desc = get_key_description(vcssb, vce); if (!desc) return -ENOMEM;
if (diag320_rc != DIAG320_RC_OK) {
pr_dbf_msg("Diag 320 Subcode 1 returned bad RC: %04x", diag320_rc); return -EIO;
} if (vcssb->vcssb_length == VCSSB_LEN_NO_CERTS) {
pr_dbf_msg("No certificates available for current configuration"); return -ENOKEY;
}
rc = get_sevcb(vcssb, index, vcb); if (rc) goto out;
extract_vce_from_sevcb(vcb, vce);
rc = check_certificate_valid(vce); if (rc) goto out;
rc = create_key_from_vce(vcssb, vce, keyring); if (rc) goto out;
pr_dbf_msg("Successfully created key from Certificate Entry %d", index);
out:
vfree(vce);
vfree(vcb); return rc;
}
/* * Request a single-entry VCB for each VCE available for the partition. * Create a key from it and link it to cert_store keyring. If no keys * could be created (i.e. VCEs were invalid) return -ENOKEY.
*/ staticint add_certificates_to_keyring(struct vcssb *vcssb, struct key *keyring)
{ int rc, index, count, added;
count = 0;
added = 0; /* Certificate Store entries indices start with 1 and have no gaps. */ for (index = 1; index < vcssb->total_vc_index_count + 1; index++) {
pr_dbf_msg("Creating key from VCE %u", index);
rc = create_key_from_sevcb(vcssb, index, keyring);
count++;
if (rc == -EAGAIN) return rc;
if (rc)
pr_dbf_msg("Creating key from VCE %u failed (%d)", index, rc); else
added++;
}
if (added == 0) {
pr_dbf_msg("Processed %d entries. No keys created", count); return -ENOKEY;
}
pr_info("Added %d of %d keys to cert_store keyring", added, count);
/* * Do not allow to link more keys to certificate store keyring after all * the VCEs were processed.
*/
rc = keyring_restrict(make_key_ref(keyring, true), NULL, NULL); if (rc)
pr_dbf_msg("Failed to set restriction to cert_store keyring (%d)", rc);
return 0;
}
/* * Check which DIAG320 subcodes are installed. * Return -ENOENT if subcodes 1 or 2 are not available.
*/ staticint query_diag320_subcodes(void)
{ unsignedlong ism[ISM_LEN_DWORDS]; int rc;
rc = diag320(0, ism); if (rc != DIAG320_RC_OK) {
pr_dbf_msg("DIAG320 subcode query returned %04x", rc); return -ENOENT;
}
if (!test_bit_inv(1, ism) || !test_bit_inv(2, ism)) {
pr_dbf_msg("Not all required DIAG320 subcodes are installed"); return -ENOENT;
}
return 0;
}
/* * Check if Certificate Store is supported by the firmware and DIAG320 subcodes * 1 and 2 are installed. Create cert_store keyring and link all certificates * available for the current partition to it as "cert_store_key" type * keys. On refresh or error invalidate cert_store keyring and destroy * all keys of "cert_store_key" type.
*/ staticint fill_cs_keyring(void)
{ struct key *cs_keyring; struct vcssb *vcssb; int rc;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.