162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0+ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Copyright (C) 2019 Microsoft Corporation 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Author: Lakshmi Ramasubramanian (nramas@linux.microsoft.com) 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * File: ima_asymmetric_keys.c 862306a36Sopenharmony_ci * Defines an IMA hook to measure asymmetric keys on key 962306a36Sopenharmony_ci * create or update. 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include <keys/asymmetric-type.h> 1362306a36Sopenharmony_ci#include <linux/user_namespace.h> 1462306a36Sopenharmony_ci#include <linux/ima.h> 1562306a36Sopenharmony_ci#include "ima.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci/** 1862306a36Sopenharmony_ci * ima_post_key_create_or_update - measure asymmetric keys 1962306a36Sopenharmony_ci * @keyring: keyring to which the key is linked to 2062306a36Sopenharmony_ci * @key: created or updated key 2162306a36Sopenharmony_ci * @payload: The data used to instantiate or update the key. 2262306a36Sopenharmony_ci * @payload_len: The length of @payload. 2362306a36Sopenharmony_ci * @flags: key flags 2462306a36Sopenharmony_ci * @create: flag indicating whether the key was created or updated 2562306a36Sopenharmony_ci * 2662306a36Sopenharmony_ci * Keys can only be measured, not appraised. 2762306a36Sopenharmony_ci * The payload data used to instantiate or update the key is measured. 2862306a36Sopenharmony_ci */ 2962306a36Sopenharmony_civoid ima_post_key_create_or_update(struct key *keyring, struct key *key, 3062306a36Sopenharmony_ci const void *payload, size_t payload_len, 3162306a36Sopenharmony_ci unsigned long flags, bool create) 3262306a36Sopenharmony_ci{ 3362306a36Sopenharmony_ci bool queued = false; 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci /* Only asymmetric keys are handled by this hook. */ 3662306a36Sopenharmony_ci if (key->type != &key_type_asymmetric) 3762306a36Sopenharmony_ci return; 3862306a36Sopenharmony_ci 3962306a36Sopenharmony_ci if (!payload || (payload_len == 0)) 4062306a36Sopenharmony_ci return; 4162306a36Sopenharmony_ci 4262306a36Sopenharmony_ci if (ima_should_queue_key()) 4362306a36Sopenharmony_ci queued = ima_queue_key(keyring, payload, payload_len); 4462306a36Sopenharmony_ci 4562306a36Sopenharmony_ci if (queued) 4662306a36Sopenharmony_ci return; 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci /* 4962306a36Sopenharmony_ci * keyring->description points to the name of the keyring 5062306a36Sopenharmony_ci * (such as ".builtin_trusted_keys", ".ima", etc.) to 5162306a36Sopenharmony_ci * which the given key is linked to. 5262306a36Sopenharmony_ci * 5362306a36Sopenharmony_ci * The name of the keyring is passed in the "eventname" 5462306a36Sopenharmony_ci * parameter to process_buffer_measurement() and is set 5562306a36Sopenharmony_ci * in the "eventname" field in ima_event_data for 5662306a36Sopenharmony_ci * the key measurement IMA event. 5762306a36Sopenharmony_ci * 5862306a36Sopenharmony_ci * The name of the keyring is also passed in the "keyring" 5962306a36Sopenharmony_ci * parameter to process_buffer_measurement() to check 6062306a36Sopenharmony_ci * if the IMA policy is configured to measure a key linked 6162306a36Sopenharmony_ci * to the given keyring. 6262306a36Sopenharmony_ci */ 6362306a36Sopenharmony_ci process_buffer_measurement(&nop_mnt_idmap, NULL, payload, payload_len, 6462306a36Sopenharmony_ci keyring->description, KEY_CHECK, 0, 6562306a36Sopenharmony_ci keyring->description, false, NULL, 0); 6662306a36Sopenharmony_ci} 67