Path: blob/master/security/integrity/digsig_asymmetric.c
26378 views
// SPDX-License-Identifier: GPL-2.0-only1/*2* Copyright (C) 2013 Intel Corporation3*4* Author:5* Dmitry Kasatkin <[email protected]>6*/78#include <linux/err.h>9#include <linux/ratelimit.h>10#include <linux/key-type.h>11#include <crypto/public_key.h>12#include <crypto/hash_info.h>13#include <keys/asymmetric-type.h>14#include <keys/system_keyring.h>1516#include "integrity.h"1718/*19* Request an asymmetric key.20*/21static struct key *request_asymmetric_key(struct key *keyring, uint32_t keyid)22{23struct key *key;24char name[12];2526sprintf(name, "id:%08x", keyid);2728pr_debug("key search: \"%s\"\n", name);2930key = get_ima_blacklist_keyring();31if (key) {32key_ref_t kref;3334kref = keyring_search(make_key_ref(key, 1),35&key_type_asymmetric, name, true);36if (!IS_ERR(kref)) {37pr_err("Key '%s' is in ima_blacklist_keyring\n", name);38return ERR_PTR(-EKEYREJECTED);39}40}4142if (keyring) {43/* search in specific keyring */44key_ref_t kref;4546kref = keyring_search(make_key_ref(keyring, 1),47&key_type_asymmetric, name, true);48if (IS_ERR(kref))49key = ERR_CAST(kref);50else51key = key_ref_to_ptr(kref);52} else {53key = request_key(&key_type_asymmetric, name, NULL);54}5556if (IS_ERR(key)) {57if (keyring)58pr_err_ratelimited("Request for unknown key '%s' in '%s' keyring. err %ld\n",59name, keyring->description,60PTR_ERR(key));61else62pr_err_ratelimited("Request for unknown key '%s' err %ld\n",63name, PTR_ERR(key));6465switch (PTR_ERR(key)) {66/* Hide some search errors */67case -EACCES:68case -ENOTDIR:69case -EAGAIN:70return ERR_PTR(-ENOKEY);71default:72return key;73}74}7576pr_debug("%s() = 0 [%x]\n", __func__, key_serial(key));7778return key;79}8081int asymmetric_verify(struct key *keyring, const char *sig,82int siglen, const char *data, int datalen)83{84struct public_key_signature pks;85struct signature_v2_hdr *hdr = (struct signature_v2_hdr *)sig;86const struct public_key *pk;87struct key *key;88int ret;8990if (siglen <= sizeof(*hdr))91return -EBADMSG;9293siglen -= sizeof(*hdr);9495if (siglen != be16_to_cpu(hdr->sig_size))96return -EBADMSG;9798if (hdr->hash_algo >= HASH_ALGO__LAST)99return -ENOPKG;100101key = request_asymmetric_key(keyring, be32_to_cpu(hdr->keyid));102if (IS_ERR(key))103return PTR_ERR(key);104105memset(&pks, 0, sizeof(pks));106107pks.hash_algo = hash_algo_name[hdr->hash_algo];108109pk = asymmetric_key_public_key(key);110pks.pkey_algo = pk->pkey_algo;111if (!strcmp(pk->pkey_algo, "rsa")) {112pks.encoding = "pkcs1";113} else if (!strncmp(pk->pkey_algo, "ecdsa-", 6)) {114/* edcsa-nist-p192 etc. */115pks.encoding = "x962";116} else if (!strcmp(pk->pkey_algo, "ecrdsa")) {117pks.encoding = "raw";118} else {119ret = -ENOPKG;120goto out;121}122123pks.digest = (u8 *)data;124pks.digest_size = datalen;125pks.s = hdr->sig;126pks.s_size = siglen;127ret = verify_signature(key, &pks);128out:129key_put(key);130pr_debug("%s() = %d\n", __func__, ret);131return ret;132}133134135