Skip to content

Commit

Permalink
PKCS#7: Introduce pkcs7_get_digest()
Browse files Browse the repository at this point in the history
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: Thiago Jung Bauermann <[email protected]>
Reviewed-by: Mimi Zohar <[email protected]>
Cc: David Howells <[email protected]>
Cc: David Woodhouse <[email protected]>
Cc: Herbert Xu <[email protected]>
Cc: "David S. Miller" <[email protected]>
Signed-off-by: Mimi Zohar <[email protected]>
  • Loading branch information
bauermann authored and mimizohar committed Aug 5, 2019
1 parent 2a7bf67 commit e201af1
Show file tree
Hide file tree
Showing 2 changed files with 37 additions and 0 deletions.
33 changes: 33 additions & 0 deletions crypto/asymmetric_keys/pkcs7_verify.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -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;

Expand Down Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions include/crypto/pkcs7.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
#define _CRYPTO_PKCS7_H

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

struct key;
Expand Down Expand Up @@ -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 */

0 comments on commit e201af1

Please sign in to comment.