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 <crypto/hash_info.h>
20 #include <keys/asymmetric-type.h>
21 #include <keys/system_keyring.h>
23 #include "integrity.h"
26 * Request an asymmetric key.
28 static struct key
*request_asymmetric_key(struct key
*keyring
, uint32_t keyid
)
33 sprintf(name
, "id:%08x", keyid
);
35 pr_debug("key search: \"%s\"\n", name
);
37 key
= get_ima_blacklist_keyring();
41 kref
= keyring_search(make_key_ref(key
, 1),
42 &key_type_asymmetric
, name
);
44 pr_err("Key '%s' is in ima_blacklist_keyring\n", name
);
45 return ERR_PTR(-EKEYREJECTED
);
50 /* search in specific keyring */
53 kref
= keyring_search(make_key_ref(keyring
, 1),
54 &key_type_asymmetric
, name
);
58 key
= key_ref_to_ptr(kref
);
60 key
= request_key(&key_type_asymmetric
, name
, NULL
);
64 pr_err_ratelimited("Request for unknown key '%s' err %ld\n",
66 switch (PTR_ERR(key
)) {
67 /* Hide some search errors */
71 return ERR_PTR(-ENOKEY
);
77 pr_debug("%s() = 0 [%x]\n", __func__
, key_serial(key
));
82 int asymmetric_verify(struct key
*keyring
, const char *sig
,
83 int siglen
, const char *data
, int datalen
)
85 struct public_key_signature pks
;
86 struct signature_v2_hdr
*hdr
= (struct signature_v2_hdr
*)sig
;
90 if (siglen
<= sizeof(*hdr
))
93 siglen
-= sizeof(*hdr
);
95 if (siglen
!= __be16_to_cpu(hdr
->sig_size
))
98 if (hdr
->hash_algo
>= HASH_ALGO__LAST
)
101 key
= request_asymmetric_key(keyring
, __be32_to_cpu(hdr
->keyid
));
105 memset(&pks
, 0, sizeof(pks
));
107 pks
.pkey_algo
= "rsa";
108 pks
.hash_algo
= hash_algo_name
[hdr
->hash_algo
];
109 pks
.digest
= (u8
*)data
;
110 pks
.digest_size
= datalen
;
113 ret
= verify_signature(key
, &pks
);
115 pr_debug("%s() = %d\n", __func__
, ret
);