Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit e201af16 authored by Thiago Jung Bauermann's avatar Thiago Jung Bauermann Committed by Mimi Zohar
Browse files

PKCS#7: Introduce pkcs7_get_digest()



IMA will need to access the digest of the PKCS7 message (as calculated by
the kernel) before the signature is verified, so introduce
pkcs7_get_digest() for that purpose.

Also, modify pkcs7_digest() to detect when the digest was already
calculated so that it doesn't have to do redundant work. Verifying that
sinfo->sig->digest isn't NULL is sufficient because both places which
allocate sinfo->sig (pkcs7_parse_message() and pkcs7_note_signed_info())
use kzalloc() so sig->digest is always initialized to zero.

Signed-off-by: default avatarThiago Jung Bauermann <bauerman@linux.ibm.com>
Reviewed-by: default avatarMimi Zohar <zohar@linux.ibm.com>
Cc: David Howells <dhowells@redhat.com>
Cc: David Woodhouse <dwmw2@infradead.org>
Cc: Herbert Xu <herbert@gondor.apana.org.au>
Cc: "David S. Miller" <davem@davemloft.net>
Signed-off-by: default avatarMimi Zohar <zohar@linux.ibm.com>
parent 2a7bf671
Loading
Loading
Loading
Loading
+33 −0
Original line number Diff line number Diff line
@@ -12,6 +12,7 @@
#include <linux/err.h>
#include <linux/asn1.h>
#include <crypto/hash.h>
#include <crypto/hash_info.h>
#include <crypto/public_key.h>
#include "pkcs7_parser.h"

@@ -29,6 +30,10 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,

	kenter(",%u,%s", sinfo->index, sinfo->sig->hash_algo);

	/* The digest was calculated already. */
	if (sig->digest)
		return 0;

	if (!sinfo->sig->hash_algo)
		return -ENOPKG;

@@ -117,6 +122,34 @@ static int pkcs7_digest(struct pkcs7_message *pkcs7,
	return ret;
}

int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf, u32 *len,
		     enum hash_algo *hash_algo)
{
	struct pkcs7_signed_info *sinfo = pkcs7->signed_infos;
	int i, ret;

	/*
	 * This function doesn't support messages with more than one signature.
	 */
	if (sinfo == NULL || sinfo->next != NULL)
		return -EBADMSG;

	ret = pkcs7_digest(pkcs7, sinfo);
	if (ret)
		return ret;

	*buf = sinfo->sig->digest;
	*len = sinfo->sig->digest_size;

	for (i = 0; i < HASH_ALGO__LAST; i++)
		if (!strcmp(hash_algo_name[i], sinfo->sig->hash_algo)) {
			*hash_algo = i;
			break;
		}

	return 0;
}

/*
 * Find the key (X.509 certificate) to use to verify a PKCS#7 message.  PKCS#7
 * uses the issuer's name and the issuing certificate serial number for
+4 −0
Original line number Diff line number Diff line
@@ -9,6 +9,7 @@
#define _CRYPTO_PKCS7_H

#include <linux/verification.h>
#include <linux/hash_info.h>
#include <crypto/public_key.h>

struct key;
@@ -40,4 +41,7 @@ extern int pkcs7_verify(struct pkcs7_message *pkcs7,
extern int pkcs7_supply_detached_data(struct pkcs7_message *pkcs7,
				      const void *data, size_t datalen);

extern int pkcs7_get_digest(struct pkcs7_message *pkcs7, const u8 **buf,
			    u32 *len, enum hash_algo *hash_algo);

#endif /* _CRYPTO_PKCS7_H */