2 * Copyright (C) 2013 Intel Corporation
5 * Dmitry Kasatkin <dmitry.kasatkin@intel.com>
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation, version 2 of the License.
13 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
15 #include <linux/err.h>
16 #include <linux/ratelimit.h>
17 #include <linux/key-type.h>
18 #include <crypto/public_key.h>
19 #include <keys/asymmetric-type.h>
20 #include <keys/system_keyring.h>
22 #include "integrity.h"
25 * Request an asymmetric key.
27 static struct key
*request_asymmetric_key(struct key
*keyring
, uint32_t keyid
)
32 sprintf(name
, "id:%08x", keyid
);
34 pr_debug("key search: \"%s\"\n", name
);
36 key
= get_ima_blacklist_keyring();
40 kref
= keyring_search(make_key_ref(key
, 1),
41 &key_type_asymmetric
, name
);
43 pr_err("Key '%s' is in ima_blacklist_keyring\n", name
);
44 return ERR_PTR(-EKEYREJECTED
);
49 /* search in specific keyring */
52 kref
= keyring_search(make_key_ref(keyring
, 1),
53 &key_type_asymmetric
, name
);
57 key
= key_ref_to_ptr(kref
);
59 key
= request_key(&key_type_asymmetric
, name
, NULL
);
63 pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
65 switch (PTR_ERR(key
)) {
66 /* Hide some search errors */
70 return ERR_PTR(-ENOKEY
);
76 pr_debug("%s() = 0 [%x]\n", __func__
, key_serial(key
));
81 int asymmetric_verify(struct key
*keyring
, const char *sig
,
82 int siglen
, const char *data
, int datalen
)
84 struct public_key_signature pks
;
85 struct signature_v2_hdr
*hdr
= (struct signature_v2_hdr
*)sig
;
89 if (siglen
<= sizeof(*hdr
))
92 siglen
-= sizeof(*hdr
);
94 if (siglen
!= __be16_to_cpu(hdr
->sig_size
))
97 if (hdr
->hash_algo
>= PKEY_HASH__LAST
)
100 key
= request_asymmetric_key(keyring
, __be32_to_cpu(hdr
->keyid
));
104 memset(&pks
, 0, sizeof(pks
));
106 pks
.pkey_hash_algo
= hdr
->hash_algo
;
107 pks
.digest
= (u8
*)data
;
108 pks
.digest_size
= datalen
;
110 pks
.rsa
.s
= mpi_read_raw_data(hdr
->sig
, siglen
);
113 ret
= verify_signature(key
, &pks
);
117 pr_debug("%s() = %d\n", __func__
, ret
);