blob: 937c844bee4af8b17d2780bf69203ce381a434cd [file] [log] [blame]
Rusty Russell106a4ee2012-09-26 10:09:40 +01001/* Module signature checker
2 *
3 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
4 * Written by David Howells (dhowells@redhat.com)
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public Licence
8 * as published by the Free Software Foundation; either version
9 * 2 of the Licence, or (at your option) any later version.
10 */
11
12#include <linux/kernel.h>
David Howells146aa8b2015-10-21 14:04:48 +010013#include <linux/errno.h>
David Howells89053aa2016-03-01 10:36:07 +000014#include <linux/string.h>
David Howellsa511e1a2016-04-06 16:14:26 +010015#include <linux/verification.h>
David Howells3f1e1be2015-07-20 21:16:27 +010016#include <crypto/public_key.h>
Rusty Russell106a4ee2012-09-26 10:09:40 +010017#include "module-internal.h"
18
David Howells4e8ae722016-03-03 21:49:27 +000019enum pkey_id_type {
20 PKEY_ID_PGP, /* OpenPGP generated key ID */
21 PKEY_ID_X509, /* X.509 arbitrary subjectKeyIdentifier */
22 PKEY_ID_PKCS7, /* Signature in PKCS#7 message */
23};
24
Rusty Russell106a4ee2012-09-26 10:09:40 +010025/*
David Howells48ba2462012-09-26 10:11:03 +010026 * Module signature information block.
27 *
28 * The constituents of the signature section are, in order:
29 *
30 * - Signer's name
31 * - Key identifier
32 * - Signature data
33 * - Information block
34 */
35struct module_signature {
David Howells3f1e1be2015-07-20 21:16:27 +010036 u8 algo; /* Public-key crypto algorithm [0] */
37 u8 hash; /* Digest algorithm [0] */
38 u8 id_type; /* Key identifier type [PKEY_ID_PKCS7] */
39 u8 signer_len; /* Length of signer's name [0] */
40 u8 key_id_len; /* Length of key identifier [0] */
David Howells12e130b2012-10-22 15:05:48 +010041 u8 __pad[3];
42 __be32 sig_len; /* Length of signature data */
David Howells48ba2462012-09-26 10:11:03 +010043};
44
45/*
Rusty Russell106a4ee2012-09-26 10:09:40 +010046 * Verify the signature on a module.
47 */
David Howellscaabe242012-10-20 01:19:29 +010048int mod_verify_sig(const void *mod, unsigned long *_modlen)
Rusty Russell106a4ee2012-09-26 10:09:40 +010049{
David Howells48ba2462012-09-26 10:11:03 +010050 struct module_signature ms;
David Howellscaabe242012-10-20 01:19:29 +010051 size_t modlen = *_modlen, sig_len;
David Howells48ba2462012-09-26 10:11:03 +010052
Randy Dunlap0390c882012-10-20 18:59:31 -070053 pr_devel("==>%s(,%zu)\n", __func__, modlen);
David Howells48ba2462012-09-26 10:11:03 +010054
David Howellscaabe242012-10-20 01:19:29 +010055 if (modlen <= sizeof(ms))
David Howells48ba2462012-09-26 10:11:03 +010056 return -EBADMSG;
57
David Howellscaabe242012-10-20 01:19:29 +010058 memcpy(&ms, mod + (modlen - sizeof(ms)), sizeof(ms));
59 modlen -= sizeof(ms);
David Howells48ba2462012-09-26 10:11:03 +010060
61 sig_len = be32_to_cpu(ms.sig_len);
David Howellscaabe242012-10-20 01:19:29 +010062 if (sig_len >= modlen)
David Howells48ba2462012-09-26 10:11:03 +010063 return -EBADMSG;
David Howellscaabe242012-10-20 01:19:29 +010064 modlen -= sig_len;
David Howellscaabe242012-10-20 01:19:29 +010065 *_modlen = modlen;
David Howells48ba2462012-09-26 10:11:03 +010066
David Howells3f1e1be2015-07-20 21:16:27 +010067 if (ms.id_type != PKEY_ID_PKCS7) {
68 pr_err("Module is not signed with expected PKCS#7 message\n");
David Howells48ba2462012-09-26 10:11:03 +010069 return -ENOPKG;
David Howells48ba2462012-09-26 10:11:03 +010070 }
71
David Howells3f1e1be2015-07-20 21:16:27 +010072 if (ms.algo != 0 ||
73 ms.hash != 0 ||
74 ms.signer_len != 0 ||
75 ms.key_id_len != 0 ||
76 ms.__pad[0] != 0 ||
77 ms.__pad[1] != 0 ||
78 ms.__pad[2] != 0) {
79 pr_err("PKCS#7 signature info has unexpected non-zero params\n");
80 return -EBADMSG;
81 }
David Howells48ba2462012-09-26 10:11:03 +010082
David Howellse68503b2016-04-06 16:14:24 +010083 return verify_pkcs7_signature(mod, modlen, mod + modlen, sig_len,
David Howellsbda850c2016-04-06 16:14:24 +010084 NULL, VERIFYING_MODULE_SIGNATURE,
David Howellse68503b2016-04-06 16:14:24 +010085 NULL, NULL);
Rusty Russell106a4ee2012-09-26 10:09:40 +010086}