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/key-type.h>
17 #include <crypto/public_key.h>
18 #include <keys/asymmetric-type.h>
20 #include "integrity.h"
23 * signature format v2 - for using with asymmetric keys
25 struct signature_v2_hdr
{
26 uint8_t version
; /* signature format version */
27 uint8_t hash_algo
; /* Digest algorithm [enum pkey_hash_algo] */
28 uint32_t keyid
; /* IMA key identifier - not X509/PGP specific*/
29 uint16_t sig_size
; /* signature size */
30 uint8_t sig
[0]; /* signature payload */
34 * Request an asymmetric key.
36 static struct key
*request_asymmetric_key(struct key
*keyring
, uint32_t keyid
)
41 sprintf(name
, "id:%x", keyid
);
43 pr_debug("key search: \"%s\"\n", name
);
46 /* search in specific keyring */
48 kref
= keyring_search(make_key_ref(keyring
, 1),
49 &key_type_asymmetric
, name
);
53 key
= key_ref_to_ptr(kref
);
55 key
= request_key(&key_type_asymmetric
, name
, NULL
);
59 pr_warn("Request for unknown key '%s' err %ld\n",
61 switch (PTR_ERR(key
)) {
62 /* Hide some search errors */
66 return ERR_PTR(-ENOKEY
);
72 pr_debug("%s() = 0 [%x]\n", __func__
, key_serial(key
));
77 int asymmetric_verify(struct key
*keyring
, const char *sig
,
78 int siglen
, const char *data
, int datalen
)
80 struct public_key_signature pks
;
81 struct signature_v2_hdr
*hdr
= (struct signature_v2_hdr
*)sig
;
85 if (siglen
<= sizeof(*hdr
))
88 siglen
-= sizeof(*hdr
);
90 if (siglen
!= __be16_to_cpu(hdr
->sig_size
))
93 if (hdr
->hash_algo
>= PKEY_HASH__LAST
)
96 key
= request_asymmetric_key(keyring
, __be32_to_cpu(hdr
->keyid
));
100 memset(&pks
, 0, sizeof(pks
));
102 pks
.pkey_hash_algo
= hdr
->hash_algo
;
103 pks
.digest
= (u8
*)data
;
104 pks
.digest_size
= datalen
;
106 pks
.rsa
.s
= mpi_read_raw_data(hdr
->sig
, siglen
);
109 ret
= verify_signature(key
, &pks
);
113 pr_debug("%s() = %d\n", __func__
, ret
);