hc
2024-02-20 102a0743326a03cd1a1202ceda21e175b7d3575c
kernel/crypto/asymmetric_keys/pkcs7_verify.c
....@@ -1,12 +1,8 @@
1
+// SPDX-License-Identifier: GPL-2.0-or-later
12 /* Verify the signature on a PKCS#7 message.
23 *
34 * Copyright (C) 2012 Red Hat, Inc. All Rights Reserved.
45 * 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.
106 */
117
128 #define pr_fmt(fmt) "PKCS7: "fmt
....@@ -16,6 +12,7 @@
1612 #include <linux/err.h>
1713 #include <linux/asn1.h>
1814 #include <crypto/hash.h>
15
+#include <crypto/hash_info.h>
1916 #include <crypto/public_key.h>
2017 #include "pkcs7_parser.h"
2118
....@@ -32,6 +29,10 @@
3229 int ret;
3330
3431 kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);
32
+
33
+ /* The digest was calculated already. */
34
+ if (sig->digest)
35
+ return 0;
3536
3637 if (!sinfo->sig->hash_algo)
3738 return -ENOPKG;
....@@ -56,7 +57,6 @@
5657 goto error_no_desc;
5758
5859 desc->tfm = tfm;
59
- desc->flags = CRYPTO_TFM_REQ_MAY_SLEEP;
6060
6161 /* Digest the message [RFC2315 9.3] */
6262 ret = crypto_shash_digest(desc, pkcs7->data, pkcs7->data_len,
....@@ -79,16 +79,16 @@
7979 }
8080
8181 if (sinfo->msgdigest_len != sig->digest_size) {
82
- pr_debug("Sig %u: Invalid digest size (%u)\n",
83
- sinfo->index, sinfo->msgdigest_len);
82
+ pr_warn("Sig %u: Invalid digest size (%u)\n",
83
+ sinfo->index, sinfo->msgdigest_len);
8484 ret = -EBADMSG;
8585 goto error;
8686 }
8787
8888 if (memcmp(sig->digest, sinfo->msgdigest,
8989 sinfo->msgdigest_len) != 0) {
90
- pr_debug("Sig %u: Message digest doesn't match\n",
91
- sinfo->index);
90
+ pr_warn("Sig %u: Message digest doesn't match\n",
91
+ sinfo->index);
9292 ret = -EKEYREJECTED;
9393 goto error;
9494 }
....@@ -120,6 +120,34 @@
120120 crypto_free_shash(tfm);
121121 kleave(" = %d", ret);
122122 return ret;
123
+}
124
+
125
+int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
126
+ enum hash_algo *hash_algo)
127
+{
128
+ struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
129
+ int i, ret;
130
+
131
+ /*
132
+ * This function doesn't support messages with more than one signature.
133
+ */
134
+ if (sinfo == NULL || sinfo->next != NULL)
135
+ return -EBADMSG;
136
+
137
+ ret = pkcs7_digest(pkcs7, sinfo);
138
+ if (ret)
139
+ return ret;
140
+
141
+ *buf = sinfo->sig->digest;
142
+ *len = sinfo->sig->digest_size;
143
+
144
+ for (i = 0; i < HASH_ALGO__LAST; i++)
145
+ if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
146
+ *hash_algo = i;
147
+ break;
148
+ }
149
+
150
+ return 0;
123151 }
124152
125153 /*
....@@ -460,7 +488,7 @@
460488 const void *data, size_t datalen)
461489 {
462490 if (pkcs7->data) {
463
- pr_debug("Data already supplied\n");
491
+ pr_warn("Data already supplied\n");
464492 return -EINVAL;
465493 }
466494 pkcs7->data = data;