|
|
45e748 |
From e339fdbbd0b81dc1fcdc2032e861b8a5fa6e062d Mon Sep 17 00:00:00 2001
|
|
|
45e748 |
From: Jes Sorensen <jsorensen@fb.com>
|
|
|
45e748 |
Date: Mon, 20 Apr 2020 13:40:26 -0400
|
|
|
45e748 |
Subject: [PATCH 26/33] fsverity - add tag for fsverity algorithm
|
|
|
45e748 |
|
|
|
45e748 |
The default algorith is SHA256, but fsverity allows for other
|
|
|
45e748 |
algorithms, so add a tag to handle this.
|
|
|
45e748 |
|
|
|
45e748 |
Signed-off-by: Jes Sorensen <jsorensen@fb.com>
|
|
|
45e748 |
---
|
|
|
45e748 |
lib/package.c | 1 +
|
|
|
45e748 |
lib/rpmfi.c | 2 ++
|
|
|
45e748 |
lib/rpmtag.h | 2 ++
|
|
|
45e748 |
sign/rpmsignverity.c | 32 ++++++++++++++++++++++++++++----
|
|
|
45e748 |
4 files changed, 33 insertions(+), 4 deletions(-)
|
|
|
45e748 |
|
|
|
45e748 |
diff --git a/lib/package.c b/lib/package.c
|
|
|
45e748 |
index c6108f686..3c761d365 100644
|
|
|
45e748 |
--- a/lib/package.c
|
|
|
45e748 |
+++ b/lib/package.c
|
|
|
45e748 |
@@ -46,6 +46,7 @@ struct taglate_s {
|
|
|
45e748 |
{ RPMSIGTAG_FILESIGNATURES, RPMTAG_FILESIGNATURES, 0, 1 },
|
|
|
45e748 |
{ RPMSIGTAG_FILESIGNATURELENGTH, RPMTAG_FILESIGNATURELENGTH, 1, 1 },
|
|
|
45e748 |
{ RPMSIGTAG_VERITYSIGNATURES, RPMTAG_VERITYSIGNATURES, 0, 0 },
|
|
|
45e748 |
+ { RPMSIGTAG_VERITYSIGNATUREALGO, RPMTAG_VERITYSIGNATUREALGO, 1, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_SHA1, RPMTAG_SHA1HEADER, 1, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_SHA256, RPMTAG_SHA256HEADER, 1, 0 },
|
|
|
45e748 |
{ RPMSIGTAG_DSA, RPMTAG_DSAHEADER, 0, 0 },
|
|
|
45e748 |
diff --git a/lib/rpmfi.c b/lib/rpmfi.c
|
|
|
45e748 |
index 5fdbe02a2..70f05f509 100644
|
|
|
45e748 |
--- a/lib/rpmfi.c
|
|
|
45e748 |
+++ b/lib/rpmfi.c
|
|
|
45e748 |
@@ -118,6 +118,7 @@ struct rpmfiles_s {
|
|
|
45e748 |
int digestalgo; /*!< File digest algorithm */
|
|
|
45e748 |
uint32_t *signatureoffs; /*!< File signature offsets */
|
|
|
45e748 |
int veritysiglength; /*!< Verity signature length */
|
|
|
45e748 |
+ uint16_t verityalgo; /*!< Verity algorithm */
|
|
|
45e748 |
unsigned char * digests; /*!< File digests in binary. */
|
|
|
45e748 |
unsigned char * signatures; /*!< File signatures in binary. */
|
|
|
45e748 |
unsigned char * veritysigs; /*!< Verity signatures in binary. */
|
|
|
45e748 |
@@ -1667,6 +1668,7 @@ static int rpmfilesPopulate(rpmfiles fi, Header h, rpmfiFlags flags)
|
|
|
45e748 |
|
|
|
45e748 |
fi->veritysigs = NULL;
|
|
|
45e748 |
if (!(flags & RPMFI_NOVERITYSIGNATURES)) {
|
|
|
45e748 |
+ fi->verityalgo = headerGetNumber(h, RPMTAG_VERITYSIGNATUREALGO);
|
|
|
45e748 |
fi->veritysigs = base2bin(h, RPMTAG_VERITYSIGNATURES,
|
|
|
45e748 |
totalfc, &fi->veritysiglength);
|
|
|
45e748 |
}
|
|
|
45e748 |
diff --git a/lib/rpmtag.h b/lib/rpmtag.h
|
|
|
45e748 |
index 478457ecb..8d1efcc79 100644
|
|
|
45e748 |
--- a/lib/rpmtag.h
|
|
|
45e748 |
+++ b/lib/rpmtag.h
|
|
|
45e748 |
@@ -68,6 +68,7 @@ typedef enum rpmTag_e {
|
|
|
45e748 |
/* RPMTAG_SIG_BASE+18 reserved for RPMSIGTAG_FILESIGNATURES */
|
|
|
45e748 |
/* RPMTAG_SIG_BASE+19 reserved for RPMSIGTAG_FILESIGNATURELENGTH */
|
|
|
45e748 |
RPMTAG_VERITYSIGNATURES = RPMTAG_SIG_BASE+20, /* s[] */
|
|
|
45e748 |
+ RPMTAG_VERITYSIGNATUREALGO = RPMTAG_SIG_BASE+21, /* i */
|
|
|
45e748 |
|
|
|
45e748 |
RPMTAG_NAME = 1000, /* s */
|
|
|
45e748 |
#define RPMTAG_N RPMTAG_NAME /* s */
|
|
|
45e748 |
@@ -431,6 +432,7 @@ typedef enum rpmSigTag_e {
|
|
|
45e748 |
RPMSIGTAG_FILESIGNATURES = RPMTAG_SIG_BASE + 18,
|
|
|
45e748 |
RPMSIGTAG_FILESIGNATURELENGTH = RPMTAG_SIG_BASE + 19,
|
|
|
45e748 |
RPMSIGTAG_VERITYSIGNATURES = RPMTAG_VERITYSIGNATURES,
|
|
|
45e748 |
+ RPMSIGTAG_VERITYSIGNATUREALGO = RPMTAG_VERITYSIGNATUREALGO,
|
|
|
45e748 |
} rpmSigTag;
|
|
|
45e748 |
|
|
|
45e748 |
|
|
|
45e748 |
diff --git a/sign/rpmsignverity.c b/sign/rpmsignverity.c
|
|
|
45e748 |
index 445e1197c..55096e732 100644
|
|
|
45e748 |
--- a/sign/rpmsignverity.c
|
|
|
45e748 |
+++ b/sign/rpmsignverity.c
|
|
|
45e748 |
@@ -35,7 +35,7 @@ static int rpmVerityRead(void *opaque, void *buf, size_t size)
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
|
|
|
45e748 |
- char *keypass, char *cert)
|
|
|
45e748 |
+ char *keypass, char *cert, uint16_t algo)
|
|
|
45e748 |
{
|
|
|
45e748 |
struct libfsverity_merkle_tree_params params;
|
|
|
45e748 |
struct libfsverity_signature_params sig_params;
|
|
|
45e748 |
@@ -52,7 +52,7 @@ static char *rpmVeritySignFile(rpmfi fi, size_t *sig_size, char *key,
|
|
|
45e748 |
|
|
|
45e748 |
memset(¶ms, 0, sizeof(struct libfsverity_merkle_tree_params));
|
|
|
45e748 |
params.version = 1;
|
|
|
45e748 |
- params.hash_algorithm = FS_VERITY_HASH_ALG_SHA256;
|
|
|
45e748 |
+ params.hash_algorithm = algo;
|
|
|
45e748 |
params.block_size = RPM_FSVERITY_BLKSZ;
|
|
|
45e748 |
params.salt_size = 0 /* salt_size */;
|
|
|
45e748 |
params.salt = NULL /* salt */;
|
|
|
45e748 |
@@ -111,6 +111,8 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
char **signatures = NULL;
|
|
|
45e748 |
size_t sig_size;
|
|
|
45e748 |
int nr_files, idx;
|
|
|
45e748 |
+ uint16_t algo;
|
|
|
45e748 |
+ uint32_t algo32;
|
|
|
45e748 |
|
|
|
45e748 |
Fseek(fd, 0, SEEK_SET);
|
|
|
45e748 |
rpmtsSetVSFlags(ts, RPMVSF_MASK_NODIGESTS | RPMVSF_MASK_NOSIGNATURES |
|
|
|
45e748 |
@@ -142,6 +144,7 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
* Should this be sigh from the cloned fd or the sigh we received?
|
|
|
45e748 |
*/
|
|
|
45e748 |
headerDel(sigh, RPMSIGTAG_VERITYSIGNATURES);
|
|
|
45e748 |
+ headerDel(sigh, RPMSIGTAG_VERITYSIGNATUREALGO);
|
|
|
45e748 |
|
|
|
45e748 |
/*
|
|
|
45e748 |
* The payload doesn't include special files, like ghost files, and
|
|
|
45e748 |
@@ -153,20 +156,24 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
nr_files = rpmfiFC(hfi);
|
|
|
45e748 |
signatures = xcalloc(nr_files, sizeof(char *));
|
|
|
45e748 |
|
|
|
45e748 |
+ algo = FS_VERITY_HASH_ALG_SHA256;
|
|
|
45e748 |
+
|
|
|
45e748 |
rpmlog(RPMLOG_DEBUG, _("file count - header: %i, payload %i\n"),
|
|
|
45e748 |
nr_files, rpmfiFC(fi));
|
|
|
45e748 |
|
|
|
45e748 |
while (rpmfiNext(fi) >= 0) {
|
|
|
45e748 |
idx = rpmfiFX(fi);
|
|
|
45e748 |
|
|
|
45e748 |
- signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, cert);
|
|
|
45e748 |
+ signatures[idx] = rpmVeritySignFile(fi, &sig_size, key, keypass, cert,
|
|
|
45e748 |
+ algo);
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
while (rpmfiNext(hfi) >= 0) {
|
|
|
45e748 |
idx = rpmfiFX(hfi);
|
|
|
45e748 |
if (signatures[idx])
|
|
|
45e748 |
continue;
|
|
|
45e748 |
- signatures[idx] = rpmVeritySignFile(hfi, &sig_size, key, keypass, cert);
|
|
|
45e748 |
+ signatures[idx] = rpmVeritySignFile(hfi, &sig_size, key, keypass, cert,
|
|
|
45e748 |
+ algo);
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
rpmtdReset(&td);
|
|
|
45e748 |
@@ -187,6 +194,23 @@ rpmRC rpmSignVerity(FD_t fd, Header sigh, Header h, char *key,
|
|
|
45e748 |
signatures[idx] = NULL;
|
|
|
45e748 |
}
|
|
|
45e748 |
|
|
|
45e748 |
+ if (sig_size == 0) {
|
|
|
45e748 |
+ rpmlog(RPMLOG_ERR, _("Zero length fsverity signature\n"));
|
|
|
45e748 |
+ rc = RPMRC_FAIL;
|
|
|
45e748 |
+ goto out;
|
|
|
45e748 |
+ }
|
|
|
45e748 |
+
|
|
|
45e748 |
+ rpmtdReset(&td);
|
|
|
45e748 |
+
|
|
|
45e748 |
+ /* RPM doesn't like new 16 bit types, so use a 32 bit tag */
|
|
|
45e748 |
+ algo32 = algo;
|
|
|
45e748 |
+ rpmtdReset(&td);
|
|
|
45e748 |
+ td.tag = RPMSIGTAG_VERITYSIGNATUREALGO;
|
|
|
45e748 |
+ td.type = RPM_INT32_TYPE;
|
|
|
45e748 |
+ td.data = &algo32;
|
|
|
45e748 |
+ td.count = 1;
|
|
|
45e748 |
+ headerPut(sigh, &td, HEADERPUT_DEFAULT);
|
|
|
45e748 |
+
|
|
|
45e748 |
rpmlog(RPMLOG_DEBUG, _("sigh size: %i\n"), headerSizeof(sigh, 0));
|
|
|
45e748 |
|
|
|
45e748 |
rc = RPMRC_OK;
|
|
|
45e748 |
--
|
|
|
45e748 |
2.27.0
|
|
|
45e748 |
|